Engauge Digitizer  2
 All Classes Files Functions Variables Enumerations Enumerator Friends Pages
StatusBar.cpp
1 /******************************************************************************************************
2  * (C) 2014 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3  * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4  * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5  ******************************************************************************************************/
6 
7 #include "EngaugeAssert.h"
8 #include "Logger.h"
9 #include <QFrame>
10 #include <QHBoxLayout>
11 #include <QLineEdit>
12 #include <QStatusBar>
13 #include <QTextEdit>
14 #include <QTimer>
15 #include <QWhatsThis>
16 #include "StatusBar.h"
17 #include "ZoomFactor.h"
18 #include "ZoomLabels.h"
19 
20 const QString LABEL_COORDS_SCREEN ("Coordinates (pixels):");
21 const QString LABEL_COORDS_GRAPH ("Coordinates (graph):");
22 const QString LABEL_RESOLUTION_GRAPH ("Resolution (graph):");
23 
24 const int TEMPORARY_MESSAGE_LIFETIME = 5000; // Milliseconds. Two seconds is too fast even when the text is anticipated
25 
26 const int MIN_WIDTH_COMBO_UNITS = 160;
27 const int MAX_WIDTH_GROUP_UNITS = 400;
28 const int MAX_SIZE_EDIT_COORDS = 550; // Need lots of space in case date/time and degrees/minutes/seconds are used simultaneously
29 const int MAX_HEIGHT_EDIT_COORDS = 24;
30 
31 StatusBar::StatusBar(QStatusBar &statusBar) :
32  m_statusBar (statusBar),
33  m_statusBarMode (STATUS_BAR_MODE_ALWAYS),
34  m_timer (0)
35 {
36  createZoom ();
37  createGroupUnits ();
38 
39  connect (&m_statusBar, SIGNAL (messageChanged (const QString &)), this, SLOT (slotStatusBarChanged (const QString &)));
40 
41  m_statusBar.setMaximumHeight (60);
42  m_statusBar.hide();
43 }
44 
45 StatusBar::~StatusBar ()
46 {
47  if (m_timer != 0) {
48  delete m_timer;
49  m_timer = 0;
50  }
51 }
52 
53 void StatusBar::createGroupUnits ()
54 {
55  m_cmbUnits = new QComboBox;
56  m_cmbUnits->setEnabled (false); // Disabled until file is opened
57  m_cmbUnits->addItem (LABEL_COORDS_SCREEN, QVariant (STATUS_BAR_UNITS_COORDS_SCREEN));
58  m_cmbUnits->addItem (LABEL_COORDS_GRAPH, QVariant (STATUS_BAR_UNITS_COORDS_GRAPH));
59  m_cmbUnits->addItem (LABEL_RESOLUTION_GRAPH, QVariant (STATUS_BAR_UNITS_RESOLUTION_GRAPH));
60  m_cmbUnits->setCurrentText (LABEL_COORDS_GRAPH);
61  m_cmbUnits->setMaximumWidth (MIN_WIDTH_COMBO_UNITS);
62  m_cmbUnits->setToolTip (tr ("Select cursor coordinate values to display."));
63  m_cmbUnits->setWhatsThis (tr("Select Cursor Coordinate Values\n\n"
64  "Values at cursor coordinates to display. Coordinates are in screen (pixels) or "
65  "graph units. Resolution (which is the number of graph units per pixel) is "
66  "in graph units. Graph units are only available after axis points have been defined."));
67  connect (m_cmbUnits, SIGNAL (activated(const QString &)), this, SLOT (slotComboUnits (const QString &))); // activated() ignores code changes
68 
69  m_editCoords = new QTextEdit;
70  m_editCoords->setEnabled (false); // Disabled until file is opened
71  m_editCoords->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
72  m_editCoords->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
73  m_editCoords->setMinimumSize (MAX_SIZE_EDIT_COORDS, MAX_HEIGHT_EDIT_COORDS);
74  m_editCoords->setMaximumSize (MAX_SIZE_EDIT_COORDS, MAX_HEIGHT_EDIT_COORDS);
75  m_editCoords->setReadOnly(true);
76  m_editCoords->setToolTip (tr ("Cursor coordinate values."));
77  m_editCoords->setWhatsThis (tr ("Cursor Coordinate Values\n\n"
78  "Values at cursor coordinates. Coordinates are in screen (pixels) or "
79  "graph units. Resolution (which is the number of graph units per pixel) is "
80  "in graph units. Graph units are only available after axis points have been defined."));
81 
82  m_groupUnits = new QFrame;
83  m_groupUnits->setFrameStyle (QFrame::Box);
84  QPalette *palette = new QPalette;
85  palette->setColor (QPalette::Foreground, Qt::gray);
86  m_groupUnits->setPalette (*palette);
87  m_groupUnits->setMaximumWidth (MAX_WIDTH_GROUP_UNITS);
88 
89  QHBoxLayout *groupLayout = new QHBoxLayout;
90  m_groupUnits->setLayout (groupLayout);
91  groupLayout->setContentsMargins (0, 0, 0, 0);
92  groupLayout->addWidget (m_cmbUnits);
93  groupLayout->addWidget (m_editCoords);
94  groupLayout->setMargin (2);
95 
96  m_statusBar.addPermanentWidget (m_groupUnits);
97 }
98 
99 void StatusBar::createZoom ()
100 {
101  m_cmbZoom = new QComboBox ();
102  m_cmbZoom->setEnabled (false); // Disabled until file is opened
103  m_cmbZoom->addItem (LABEL_ZOOM_16_TO_1);
104  m_cmbZoom->addItem (LABEL_ZOOM_8_TO_1);
105  m_cmbZoom->addItem (LABEL_ZOOM_4_TO_1);
106  m_cmbZoom->addItem (LABEL_ZOOM_2_TO_1);
107  m_cmbZoom->addItem (LABEL_ZOOM_1_TO_1);
108  m_cmbZoom->addItem (LABEL_ZOOM_1_TO_2);
109  m_cmbZoom->addItem (LABEL_ZOOM_1_TO_4);
110  m_cmbZoom->addItem (LABEL_ZOOM_1_TO_8);
111  m_cmbZoom->addItem (LABEL_ZOOM_1_TO_16);
112  m_cmbZoom->addItem (LABEL_ZOOM_FILL);
113  m_cmbZoom->setCurrentText (LABEL_ZOOM_1_TO_1);
114  m_cmbZoom->setMaximumWidth (80);
115  m_cmbZoom->setToolTip (tr ("Select zoom."));
116  m_cmbZoom->setWhatsThis (tr("Select Zoom\n\n"
117  "Points can be more accurately placed by zooming in."));
118  // Zoom combobox must use currentTextChanged rather than activated or else fill-zoom-at-startup never takes effect
119  connect (m_cmbZoom, SIGNAL (currentTextChanged(const QString &)), this, SLOT (slotComboZoom (const QString &)));
120 
121  m_statusBar.addPermanentWidget (m_cmbZoom);
122 }
123 
124 void StatusBar::setCoordinates (const QString &coordsScreen,
125  const QString &coordsGraph,
126  const QString &resolutionGraph)
127 {
128 // LOG4CPP_DEBUG_S ((*mainCat)) << "StatusBar::setCoordinates"
129 // << " screen=" << coordsScreen.toLatin1 ().data ()
130 // << " graph=" << coordsGraph.toLatin1 ().data ()
131 // << " resolution=" << resolutionGraph.toLatin1 ().data ();
132 
133  if (m_cmbUnits->isEnabled ()) {
134 
135  m_coordsScreen = coordsScreen;
136  m_coordsGraph = coordsGraph;
137  m_resolutionGraph = resolutionGraph;
138 
139  updateCoordsText();
140  }
141 }
142 
143 void StatusBar::setStatusBarMode(StatusBarMode statusBarMode)
144 {
145  m_statusBarMode = statusBarMode;
146  if (m_statusBarMode == STATUS_BAR_MODE_ALWAYS) {
147  m_statusBar.show();
148  } else {
149  m_statusBar.hide();
150  }
151 }
152 
153 void StatusBar::showTemporaryMessage(const QString &message)
154 {
155  LOG4CPP_DEBUG_S ((*mainCat)) << "StatusBar::showTemporaryMessage message=" << message.toLatin1 ().data ();
156 
157  if (m_statusBarMode != STATUS_BAR_MODE_NEVER) {
158  if (m_statusBarMode == STATUS_BAR_MODE_TEMPORARY) {
159  // Calling m_statusBar.show here will have no effect since this is called while processing a signal. Use a timer to
160  // show the status bar as soon as possible
161  m_timer = new QTimer;
162  connect (m_timer, SIGNAL (timeout ()), this, SLOT (slotTimeout()));
163  m_timer->setSingleShot(true);
164  m_timer->start (0);
165  }
166  m_statusBar.showMessage (message, TEMPORARY_MESSAGE_LIFETIME);
167  }
168 }
169 
170 void StatusBar::slotComboUnits (const QString &text)
171 {
172  LOG4CPP_DEBUG_S ((*mainCat)) << "StatusBar::slotComboUnits text=" << text.toLatin1 ().data ();
173 
174  updateCoordsText();
175 }
176 
177 void StatusBar::slotComboZoom (const QString &text)
178 {
179  LOG4CPP_DEBUG_S ((*mainCat)) << "StatusBar::slotComboZoom text=" << text.toLatin1 ().data ();
180 
181  if (text == LABEL_ZOOM_16_TO_1) {
182  emit signalZoom (ZOOM_16_TO_1);
183  } else if (text == LABEL_ZOOM_8_TO_1) {
184  emit signalZoom (ZOOM_8_TO_1);
185  } else if (text == LABEL_ZOOM_4_TO_1) {
186  emit signalZoom (ZOOM_4_TO_1);
187  } else if (text == LABEL_ZOOM_2_TO_1) {
188  emit signalZoom (ZOOM_2_TO_1);
189  } else if (text == LABEL_ZOOM_1_TO_1) {
190  emit signalZoom (ZOOM_1_TO_1);
191  } else if (text == LABEL_ZOOM_1_TO_2) {
192  emit signalZoom (ZOOM_1_TO_2);
193  } else if (text == LABEL_ZOOM_1_TO_4) {
194  emit signalZoom (ZOOM_1_TO_4);
195  } else if (text == LABEL_ZOOM_1_TO_8) {
196  emit signalZoom (ZOOM_1_TO_8);
197  } else if (text == LABEL_ZOOM_1_TO_16) {
198  emit signalZoom (ZOOM_1_TO_16);
199  } else if (text == LABEL_ZOOM_FILL) {
200  emit signalZoom (ZOOM_FILL);
201  } else {
202  ENGAUGE_ASSERT (false);
203  }
204 }
205 
206 void StatusBar::slotStatusBarChanged(const QString &message)
207 {
208  LOG4CPP_DEBUG_S ((*mainCat)) << "StatusBar::slotStatusBarChanged message=" << message.toLatin1 ().data ();
209 
210  if (m_statusBarMode == STATUS_BAR_MODE_TEMPORARY) {
211  m_statusBar.hide();
212  }
213 }
214 
215 void StatusBar::slotTimeout()
216 {
217  LOG4CPP_INFO_S ((*mainCat)) << "StatusBar::slotTimeout";
218 
219  delete m_timer;
220  m_timer = 0;
221 
222  m_statusBar.show();
223 }
224 
225 void StatusBar::slotZoom(int zoom)
226 {
227  LOG4CPP_INFO_S ((*mainCat)) << "StatusBar::slotZoom zoom=" << zoom;
228 
229  // Show string for the numeric zoom value
230  switch ((ZoomFactor) zoom) {
231  case ZOOM_16_TO_1:
232  m_cmbZoom->setCurrentText (LABEL_ZOOM_16_TO_1);
233  break;
234  case ZOOM_8_TO_1:
235  m_cmbZoom->setCurrentText (LABEL_ZOOM_8_TO_1);
236  break;
237  case ZOOM_4_TO_1:
238  m_cmbZoom->setCurrentText (LABEL_ZOOM_4_TO_1);
239  break;
240  case ZOOM_2_TO_1:
241  m_cmbZoom->setCurrentText (LABEL_ZOOM_2_TO_1);
242  break;
243  case ZOOM_1_TO_1:
244  m_cmbZoom->setCurrentText (LABEL_ZOOM_1_TO_1);
245  break;
246  case ZOOM_1_TO_2:
247  m_cmbZoom->setCurrentText (LABEL_ZOOM_1_TO_2);
248  break;
249  case ZOOM_1_TO_4:
250  m_cmbZoom->setCurrentText (LABEL_ZOOM_1_TO_4);
251  break;
252  case ZOOM_1_TO_8:
253  m_cmbZoom->setCurrentText (LABEL_ZOOM_1_TO_8);
254  break;
255  case ZOOM_1_TO_16:
256  m_cmbZoom->setCurrentText (LABEL_ZOOM_1_TO_16);
257  break;
258  case ZOOM_FILL:
259  m_cmbZoom->setCurrentText (LABEL_ZOOM_FILL);
260  }
261 }
262 
263 void StatusBar::updateCoordsText()
264 {
265  if (m_cmbUnits->currentText() == LABEL_COORDS_SCREEN) {
266  m_editCoords->setText (m_coordsScreen);
267  } else if (m_cmbUnits->currentText() == LABEL_COORDS_GRAPH) {
268  m_editCoords->setText (m_coordsGraph);
269  } else {
270  m_editCoords->setText (m_resolutionGraph);
271  }
272 }
273 
275 {
276  if (!m_cmbUnits->isEnabled ()) {
277 
278  // First file has just been read in, so enable the widgets
279  m_cmbZoom->setEnabled (true);
280  m_cmbUnits->setEnabled (true);
281  m_editCoords->setEnabled (true);
282  }
283 }
void setStatusBarMode(StatusBarMode statusBarMode)
Set the status bar visibility mode.
Definition: StatusBar.cpp:143
StatusBar(QStatusBar &statusBar)
Single constructor that accepts the previously-constructed standard QStatusBar.
Definition: StatusBar.cpp:31
void setCoordinates(const QString &coordsScreen, const QString &coordsGraph, const QString &resolutionGraph)
Populate the coordinates fields. Unavailable values are empty. Html-encoding to highlight with colors...
Definition: StatusBar.cpp:124
void slotZoom(int)
Receive zoom selection from MainWindow.
Definition: StatusBar.cpp:225
void wakeUp()
Enable all widgets in the status bar. This is called just after a Document becomes active...
Definition: StatusBar.cpp:274
void signalZoom(int)
Send zoom factor, that was just selected in the status bar, to MainWindow.
StatusBarMode statusBarMode() const
Current mode for status bar visibility. This is tracked locally so this class knows when to hide/show...
Definition: StatusBar.h:42
void showTemporaryMessage(const QString &message)
Show temporary message in status bar. After a short interval the message will disappear.
Definition: StatusBar.cpp:153