Engauge Digitizer 2
Loading...
Searching...
No Matches
MainWindow.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 "BackgroundImage.h"
8#include "BackgroundStateContext.h"
9#include "img/bannerapp_16.xpm"
10#include "img/bannerapp_32.xpm"
11#include "img/bannerapp_64.xpm"
12#include "img/bannerapp_128.xpm"
13#include "img/bannerapp_256.xpm"
14#include "ChecklistGuide.h"
15#include "ChecklistGuideWizard.h"
16#include "CmdCopy.h"
17#include "CmdCut.h"
18#include "CmdDelete.h"
19#include "CmdMediator.h"
20#include "CmdSelectCoordSystem.h"
21#include "CmdStackShadow.h"
22#include "ColorFilter.h"
23#include "Curve.h"
24#include "DataKey.h"
25#include "DigitizeStateContext.h"
26#include "DigitAxis.xpm"
27#include "DigitColorPicker.xpm"
28#include "DigitCurve.xpm"
29#include "DigitPointMatch.xpm"
30#include "DigitSegment.xpm"
31#include "DigitSelect.xpm"
32#include "DlgAbout.h"
33#include "DlgErrorReport.h"
34#include "DlgImportAdvanced.h"
35#include "DlgRequiresTransform.h"
36#include "DlgSettingsAxesChecker.h"
37#include "DlgSettingsColorFilter.h"
38#include "DlgSettingsCoords.h"
39#include "DlgSettingsCurveAddRemove.h"
40#include "DlgSettingsCurveProperties.h"
41#include "DlgSettingsDigitizeCurve.h"
42#include "DlgSettingsExportFormat.h"
43#include "DlgSettingsGeneral.h"
44#include "DlgSettingsGridRemoval.h"
45#include "DlgSettingsMainWindow.h"
46#include "DlgSettingsPointMatch.h"
47#include "DlgSettingsSegments.h"
48#include "DocumentSerialize.h"
49#include "EngaugeAssert.h"
50#include "EnumsToQt.h"
51#include "ExportToFile.h"
52#include "FileCmdScript.h"
53#include "Ghosts.h"
54#include "GraphicsItemType.h"
55#include "GraphicsScene.h"
56#include "GraphicsView.h"
57#include "HelpWindow.h"
58#ifdef ENGAUGE_JPEG2000
59#include "Jpeg2000.h"
60#endif // ENGAUGE_JPEG2000
61#include "LoadFileInfo.h"
62#include "LoadImageFromUrl.h"
63#include "Logger.h"
64#include "MainTitleBarFormat.h"
65#include "MainWindow.h"
66#include "NetworkClient.h"
67#include <QAction>
68#include <QApplication>
69#include <QCloseEvent>
70#include <QComboBox>
71#include <QDebug>
72#include <QDesktopServices>
73#include <QDockWidget>
74#include <QDomDocument>
75#include <QKeyEvent>
76#include <QFileDialog>
77#include <QFileInfo>
78#include <QGraphicsLineItem>
79#include <QImageReader>
80#include <QKeyEvent>
81#include <QKeySequence>
82#include <QLabel>
83#include <QMenu>
84#include <QMenuBar>
85#include <QMessageBox>
86#include <QMouseEvent>
87#include <QPrintDialog>
88#include <QPrinter>
89#include <QSettings>
90#include <QTextStream>
91#include <QtHelp>
92#include <QTimer>
93#include <QToolBar>
94#include <QToolButton>
95#include "QtToString.h"
96#include <QVBoxLayout>
97#include <QWhatsThis>
98#include <QXmlStreamReader>
99#include <QXmlStreamWriter>
100#include "Settings.h"
101#include "StatusBar.h"
102#include "TransformationStateContext.h"
103#include "TutorialDlg.h"
104#include "Version.h"
105#include "ViewPointStyle.h"
106#include "ViewSegmentFilter.h"
107#include "ZoomFactor.h"
108#include "ZoomFactorInitial.h"
109
110// These constants are used for the menu item text AND for tooltip text
111const QString DIGITIZE_ACTION_AXIS_POINT (QObject::tr ("Axis Point Tool"));
112const QString DIGITIZE_ACTION_COLOR_PICKER (QObject::tr ("Color Picker Tool"));
113const QString DIGITIZE_ACTION_CURVE_POINT (QObject::tr ("Curve Point Tool"));
114const QString DIGITIZE_ACTION_POINT_MATCH (QObject::tr ("Point Match Tool"));
115const QString DIGITIZE_ACTION_SEGMENT_POINTS (QObject::tr ("Segment Fill Tool"));
116const QString DIGITIZE_ACTION_SELECT (QObject::tr ("Select Tool"));
117
118const QString EMPTY_FILENAME ("");
119const QString ENGAUGE_FILENAME_DESCRIPTION ("Engauge Document");
120const QString ENGAUGE_FILENAME_EXTENSION ("dig");
121
122const unsigned int MAX_RECENT_FILE_LIST_SIZE = 8;
123
124MainWindow::MainWindow(const QString &errorReportFile,
125 const QString &fileCmdScriptFile,
126 bool isRegressionTest,
127 bool isGnuplot,
128 QStringList loadStartupFiles,
129 QWidget *parent) :
130 QMainWindow(parent),
131 m_isDocumentExported (false),
132 m_engaugeFile (EMPTY_FILENAME),
133 m_currentFile (EMPTY_FILENAME),
134 m_layout (0),
135 m_scene (0),
136 m_view (0),
137 m_cmdMediator (0),
138 m_digitizeStateContext (0),
139 m_transformationStateContext (0),
140 m_backgroundStateContext (0),
141 m_isGnuplot (isGnuplot),
142 m_ghosts (0),
143 m_timerRegressionErrorReport(0),
144 m_fileCmdScript (0),
145 m_timerRegressionFileCmdScript(0)
146{
147 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::MainWindow"
148 << " curDir=" << QDir::currentPath().toLatin1().data();
149
151
152 QString initialPath = QDir::currentPath();
153
154 setCurrentFile ("");
155 createIcons();
156 setWindowFlags (Qt::WindowContextHelpButtonHint | windowFlags ()); // Add help to default buttons
157 setWindowTitle (engaugeWindowTitle ());
158
159 createCentralWidget();
160 createActions ();
161 createStatusBar ();
162 createMenus ();
163 createToolBars ();
164 createHelpWindow ();
165 createTutorial ();
166 createScene ();
167 createNetwork ();
168 createLoadImageFromUrl ();
169 createStateContextBackground ();
170 createStateContextDigitize ();
171 createStateContextTransformation ();
172 createSettingsDialogs ();
173 createCommandStackShadow ();
174 updateControls ();
175
176 settingsRead ();
177 setCurrentFile ("");
178 setUnifiedTitleAndToolBarOnMac(true);
179
180 installEventFilter(this);
181 if (!errorReportFile.isEmpty()) {
182 loadErrorReportFile(initialPath,
183 errorReportFile);
184 if (isRegressionTest) {
185 startRegressionTestErrorReport(errorReportFile);
186 }
187 } else if (!fileCmdScriptFile.isEmpty()) {
188 m_fileCmdScript = new FileCmdScript (fileCmdScriptFile);
189 startRegressionTestFileCmdScript();
190 } else {
191
192 // Save file names for later, after gui becomes available. The file names are dropped if error report file is specified
193 // since only one of the two modes is available at any time, for simplicity
194 m_loadStartupFiles = loadStartupFiles;
195 }
196}
197
198MainWindow::~MainWindow()
199{
200}
201
202void MainWindow::applyZoomFactorAfterLoad()
203{
204 ZoomFactor zoomFactor;
205
206 switch (m_modelMainWindow.zoomFactorInitial())
207 {
208 case ZOOM_INITIAL_16_TO_1:
209 zoomFactor = ZOOM_16_TO_1;
210 break;
211
212 case ZOOM_INITIAL_8_TO_1:
213 zoomFactor = ZOOM_8_TO_1;
214 break;
215
216 case ZOOM_INITIAL_4_TO_1:
217 zoomFactor = ZOOM_4_TO_1;
218 break;
219
220 case ZOOM_INITIAL_2_TO_1:
221 zoomFactor = ZOOM_2_TO_1;
222 break;
223
224 case ZOOM_INITIAL_1_TO_1:
225 zoomFactor = ZOOM_1_TO_1;
226 break;
227
228 case ZOOM_INITIAL_1_TO_2:
229 zoomFactor = ZOOM_1_TO_2;
230 break;
231
232 case ZOOM_INITIAL_1_TO_4:
233 zoomFactor = ZOOM_1_TO_4;
234 break;
235
236 case ZOOM_INITIAL_1_TO_8:
237 zoomFactor = ZOOM_1_TO_8;
238 break;
239
240 case ZOOM_INITIAL_1_TO_16:
241 zoomFactor = ZOOM_1_TO_16;
242 break;
243
244 case ZOOM_INITIAL_FILL:
245 zoomFactor = ZOOM_FILL;
246 break;
247
248 case ZOOM_INITIAL_PREVIOUS:
249 zoomFactor = currentZoomFactor();
250 break;
251
252 default:
253 ENGAUGE_ASSERT (false);
254 zoomFactor = currentZoomFactor();
255 break;
256 }
257
258 slotViewZoom (zoomFactor);
259}
260
261void MainWindow::closeEvent(QCloseEvent *event)
262{
263 if (maybeSave()) {
264 settingsWrite ();
265 event->accept ();
266 } else {
267 event->ignore ();
268 }
269}
270
272{
273 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::cmdFileClose";
274
275 setWindowModified (false); // Prevent popup query asking if changes should be saved
276 slotFileClose();
277}
278
279void MainWindow::cmdFileExport(const QString &fileName)
280{
281 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::cmdFileExport";
282
283 ExportToFile exportStrategy;
284 fileExport(fileName,
285 exportStrategy);
286}
287
288void MainWindow::cmdFileImport(const QString &fileName)
289{
290 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::cmdFileImport";
291
292 m_regressionFile = exportFilenameFromInputFilename (fileName);
293 fileImport (fileName,
294 IMPORT_TYPE_SIMPLE);
295}
296
297void MainWindow::cmdFileOpen(const QString &fileName)
298{
299 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::cmdFileOpen";
300
301 m_regressionFile = exportFilenameFromInputFilename (fileName);
302 loadDocumentFile(fileName);
303}
304
306{
307 // We do not check m_cmdMediator with ENGAUGE_CHECK_PTR since calling code is expected to deal with null pointer at startup
308 return m_cmdMediator;
309}
310
311void MainWindow::createActions()
312{
313 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createActions";
314
315 createActionsFile ();
316 createActionsEdit ();
317 createActionsDigitize ();
318 createActionsView ();
319 createActionsSettings ();
320 createActionsHelp ();
321}
322
323void MainWindow::createActionsDigitize ()
324{
325 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createActionsDigitize";
326
327 QPixmap pixmapAxis (DigitAxis_xpm);
328 QPixmap pixmapCurve (DigitCurve_xpm);
329 QPixmap pixmapColorPicker (DigitColorPicker_xpm);
330 QPixmap pixmapPointMatch (DigitPointMatch_xpm);
331 QPixmap pixmapSegment (DigitSegment_xpm);
332 QPixmap pixmapSelect (DigitSelect_xpm);
333
334 QIcon iconAxis (pixmapAxis);
335 QIcon iconCurve (pixmapCurve);
336 QIcon iconColorPicker (pixmapColorPicker);
337 QIcon iconPointMatch (pixmapPointMatch);
338 QIcon iconSegment (pixmapSegment);
339 QIcon iconSelect (pixmapSelect);
340
341 m_actionDigitizeSelect = new QAction (iconSelect, DIGITIZE_ACTION_SELECT, this);
342 m_actionDigitizeSelect->setShortcut (QKeySequence (tr ("Shift+F2")));
343 m_actionDigitizeSelect->setCheckable (true);
344 m_actionDigitizeSelect->setStatusTip (tr ("Select points on screen."));
345 m_actionDigitizeSelect->setWhatsThis (tr ("Select\n\n"
346 "Select points on the screen."));
347 connect (m_actionDigitizeSelect, SIGNAL (triggered ()), this, SLOT (slotDigitizeSelect ()));
348
349 m_actionDigitizeAxis = new QAction (iconAxis, DIGITIZE_ACTION_AXIS_POINT, this);
350 m_actionDigitizeAxis->setShortcut (QKeySequence (tr ("Shift+F3")));
351 m_actionDigitizeAxis->setCheckable (true);
352 m_actionDigitizeAxis->setStatusTip (tr ("Digitize axis points."));
353 m_actionDigitizeAxis->setWhatsThis (tr ("Digitize Axis Point\n\n"
354 "Digitizes an axis point by placing a new point at the cursor "
355 "after a mouse click. The coordinates of the axis point are then "
356 "entered. In a graph, three axis points are required to define "
357 "the graph coordinates."));
358 connect (m_actionDigitizeAxis, SIGNAL (triggered ()), this, SLOT (slotDigitizeAxis ()));
359
360 m_actionDigitizeCurve = new QAction (iconCurve, DIGITIZE_ACTION_CURVE_POINT, this);
361 m_actionDigitizeCurve->setShortcut (QKeySequence (tr ("Shift+F4")));
362 m_actionDigitizeCurve->setCheckable (true);
363 m_actionDigitizeCurve->setStatusTip (tr ("Digitize curve points."));
364 m_actionDigitizeCurve->setWhatsThis (tr ("Digitize Curve Point\n\n"
365 "Digitizes a curve point by placing a new point at the cursor "
366 "after a mouse click. Use this mode to digitize points along curves "
367 "one by one.\n\n"
368 "New points will be assigned to the currently selected curve."));
369 connect (m_actionDigitizeCurve, SIGNAL (triggered ()), this, SLOT (slotDigitizeCurve ()));
370
371 m_actionDigitizePointMatch = new QAction (iconPointMatch, DIGITIZE_ACTION_POINT_MATCH, this);
372 m_actionDigitizePointMatch->setShortcut (QKeySequence (tr ("Shift+F5")));
373 m_actionDigitizePointMatch->setCheckable (true);
374 m_actionDigitizePointMatch->setStatusTip (tr ("Digitize curve points in a point plot by matching a point."));
375 m_actionDigitizePointMatch->setWhatsThis (tr ("Digitize Curve Points by Point Matching\n\n"
376 "Digitizes curve points in a point plot by finding points that match a sample point. The process "
377 "starts by selecting a representative sample point.\n\n"
378 "New points will be assigned to the currently selected curve."));
379 connect (m_actionDigitizePointMatch, SIGNAL (triggered ()), this, SLOT (slotDigitizePointMatch ()));
380
381 m_actionDigitizeColorPicker = new QAction (iconColorPicker, DIGITIZE_ACTION_COLOR_PICKER, this);
382 m_actionDigitizeColorPicker->setShortcut (QKeySequence (tr ("Shift+F6")));
383 m_actionDigitizeColorPicker->setCheckable (true);
384 m_actionDigitizeColorPicker->setStatusTip (tr ("Select color settings for filtering in Segment Fill mode."));
385 m_actionDigitizeColorPicker->setWhatsThis (tr ("Select color settings for Segment Fill filtering\n\n"
386 "Select a pixel along the currently selected curve. That pixel and its neighbors will "
387 "define the filter settings (color, brightness, and so on) of the currently selected curve "
388 "while in Segment Fill mode."));
389 connect (m_actionDigitizeColorPicker, SIGNAL (triggered ()), this, SLOT (slotDigitizeColorPicker ()));
390
391 m_actionDigitizeSegment = new QAction (iconSegment, DIGITIZE_ACTION_SEGMENT_POINTS, this);
392 m_actionDigitizeSegment->setShortcut (QKeySequence (tr ("Shift+F7")));
393 m_actionDigitizeSegment->setCheckable (true);
394 m_actionDigitizeSegment->setStatusTip (tr ("Digitize curve points along a segment of a curve."));
395 m_actionDigitizeSegment->setWhatsThis (tr ("Digitize Curve Points With Segment Fill\n\n"
396 "Digitizes curve points by placing new points along the highlighted "
397 "segment under the cursor. Use this mode to quickly digitize multiple points along a "
398 "curve with a single click.\n\n"
399 "New points will be assigned to the currently selected curve."));
400 connect (m_actionDigitizeSegment, SIGNAL (triggered ()), this, SLOT (slotDigitizeSegment ()));
401
402 m_groupDigitize = new QActionGroup (this);
403 m_groupDigitize->addAction (m_actionDigitizeSelect);
404 m_groupDigitize->addAction (m_actionDigitizeAxis);
405 m_groupDigitize->addAction (m_actionDigitizeCurve);
406 m_groupDigitize->addAction (m_actionDigitizePointMatch);
407 m_groupDigitize->addAction (m_actionDigitizeColorPicker);
408 m_groupDigitize->addAction (m_actionDigitizeSegment);
409}
410
411void MainWindow::createActionsEdit ()
412{
413 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createActionsEdit";
414
415 m_actionEditUndo = new QAction(tr ("&Undo"), this);
416 m_actionEditUndo->setShortcut (QKeySequence::Undo);
417 m_actionEditUndo->setStatusTip (tr ("Undo the last operation."));
418 m_actionEditUndo->setWhatsThis (tr ("Undo\n\n"
419 "Undo the last operation."));
420 // connect is applied when CmdMediator appears
421
422 m_actionEditRedo = new QAction(tr ("&Redo"), this);
423 m_actionEditRedo->setShortcut (QKeySequence::Redo);
424 m_actionEditRedo->setStatusTip (tr ("Redo the last operation."));
425 m_actionEditRedo->setWhatsThis (tr ("Redo\n\n"
426 "Redo the last operation."));
427 // connect is applied when CmdMediator appears
428
429 m_actionEditCut = new QAction (tr ("Cut"), this);
430 m_actionEditCut->setShortcut (QKeySequence::Cut);
431 m_actionEditCut->setStatusTip (tr ("Cuts the selected points and copies them to the clipboard."));
432 m_actionEditCut->setWhatsThis (tr ("Cut\n\n"
433 "Cuts the selected points and copies them to the clipboard."));
434 connect (m_actionEditCut, SIGNAL (triggered ()), this, SLOT (slotEditCut ()));
435
436 m_actionEditCopy = new QAction (tr ("Copy"), this);
437 m_actionEditCopy->setShortcut (QKeySequence::Copy);
438 m_actionEditCopy->setStatusTip (tr ("Copies the selected points to the clipboard."));
439 m_actionEditCopy->setWhatsThis (tr ("Copy\n\n"
440 "Copies the selected points to the clipboard."));
441 connect (m_actionEditCopy, SIGNAL (triggered ()), this, SLOT (slotEditCopy ()));
442
443 m_actionEditPaste = new QAction (tr ("Paste"), this);
444 m_actionEditPaste->setShortcut (QKeySequence::Paste);
445 m_actionEditPaste->setStatusTip (tr ("Pastes the selected points from the clipboard."));
446 m_actionEditPaste->setWhatsThis (tr ("Paste\n\n"
447 "Pastes the selected points from the clipboard. They will be assigned to the current curve."));
448 connect (m_actionEditPaste, SIGNAL (triggered ()), this, SLOT (slotEditPaste ()));
449
450 m_actionEditDelete = new QAction (tr ("Delete"), this);
451 m_actionEditDelete->setShortcut (QKeySequence::Delete);
452 m_actionEditDelete->setStatusTip (tr ("Deletes the selected points, after copying them to the clipboard."));
453 m_actionEditDelete->setWhatsThis (tr ("Delete\n\n"
454 "Deletes the selected points, after copying them to the clipboard."));
455 connect (m_actionEditDelete, SIGNAL (triggered ()), this, SLOT (slotEditDelete ()));
456
457 m_actionEditPasteAsNew = new QAction (tr ("Paste As New"), this);
458 m_actionEditPasteAsNew->setStatusTip (tr ("Pastes an image from the clipboard."));
459 m_actionEditPasteAsNew->setWhatsThis (tr ("Paste as New\n\n"
460 "Creates a new document by pasting an image from the clipboard."));
461 connect (m_actionEditPasteAsNew, SIGNAL (triggered ()), this, SLOT (slotEditPasteAsNew ()));
462
463 m_actionEditPasteAsNewAdvanced = new QAction (tr ("Paste As New (Advanced)..."), this);
464 m_actionEditPasteAsNewAdvanced->setStatusTip (tr ("Pastes an image from the clipboard, in advanced mode."));
465 m_actionEditPasteAsNewAdvanced->setWhatsThis (tr ("Paste as New (Advanced)\n\n"
466 "Creates a new document by pasting an image from the clipboard, in advanced mode."));
467 connect (m_actionEditPasteAsNewAdvanced, SIGNAL (triggered ()), this, SLOT (slotEditPasteAsNewAdvanced ()));
468}
469
470void MainWindow::createActionsFile ()
471{
472 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createActionsFile";
473
474 m_actionImport = new QAction(tr ("&Import..."), this);
475 m_actionImport->setShortcut (tr ("Ctrl+I"));
476 m_actionImport->setStatusTip (tr ("Creates a new document by importing an image with a single coordinate system."));
477 m_actionImport->setWhatsThis (tr ("Import Image\n\n"
478 "Creates a new document by importing an image with a single coordinate system."));
479 connect (m_actionImport, SIGNAL (triggered ()), this, SLOT (slotFileImport ()));
480
481 m_actionImportAdvanced = new QAction(tr ("Import (Advanced)..."), this);
482 m_actionImportAdvanced->setStatusTip (tr ("Creates a new document by importing an image with support for advanced feaures."));
483 m_actionImportAdvanced->setWhatsThis (tr ("Import (Advanced)\n\n"
484 "Creates a new document by importing an image with support for advanced feaures. In "
485 "advanced mode, there can be multiple coordinate systems and/or floating axes."));
486 connect (m_actionImportAdvanced, SIGNAL (triggered ()), this, SLOT (slotFileImportAdvanced ()));
487
488 m_actionOpen = new QAction(tr ("&Open..."), this);
489 m_actionOpen->setShortcut (QKeySequence::Open);
490 m_actionOpen->setStatusTip (tr ("Opens an existing document."));
491 m_actionOpen->setWhatsThis (tr ("Open Document\n\n"
492 "Opens an existing document."));
493 connect (m_actionOpen, SIGNAL (triggered ()), this, SLOT (slotFileOpen ()));
494
495 for (unsigned int i = 0; i < MAX_RECENT_FILE_LIST_SIZE; i++) {
496 QAction *recentFileAction = new QAction (this);
497 recentFileAction->setVisible (true);
498 connect (recentFileAction, SIGNAL (triggered ()), this, SLOT (slotRecentFileAction ()));
499 m_actionRecentFiles.append (recentFileAction);
500 }
501
502 m_actionClose = new QAction(tr ("&Close"), this);
503 m_actionClose->setShortcut (QKeySequence::Close);
504 m_actionClose->setStatusTip (tr ("Closes the open document document."));
505 m_actionClose->setWhatsThis (tr ("Close Document\n\n"
506 "Closes the open document."));
507 connect (m_actionClose, SIGNAL (triggered ()), this, SLOT (slotFileClose ()));
508
509 m_actionSave = new QAction(tr ("&Save"), this);
510 m_actionSave->setShortcut (QKeySequence::Save);
511 m_actionSave->setStatusTip (tr ("Saves the current document."));
512 m_actionSave->setWhatsThis (tr ("Save Document\n\n"
513 "Saves the current document."));
514 connect (m_actionSave, SIGNAL (triggered ()), this, SLOT (slotFileSave ()));
515
516 m_actionSaveAs = new QAction(tr ("Save As..."), this);
517 m_actionSaveAs->setShortcut (QKeySequence::SaveAs);
518 m_actionSaveAs->setStatusTip (tr ("Saves the current document under a new filename."));
519 m_actionSaveAs->setWhatsThis (tr ("Save Document As\n\n"
520 "Saves the current document under a new filename."));
521 connect (m_actionSaveAs, SIGNAL (triggered ()), this, SLOT (slotFileSaveAs ()));
522
523 m_actionExport = new QAction (tr ("Export..."), this);
524 m_actionExport->setShortcut (tr ("Ctrl+E"));
525 m_actionExport->setStatusTip (tr ("Exports the current document into a text file."));
526 m_actionExport->setWhatsThis (tr ("Export Document\n\n"
527 "Exports the current document into a text file."));
528 connect (m_actionExport, SIGNAL (triggered ()), this, SLOT (slotFileExport ()));
529
530 m_actionPrint = new QAction (tr ("&Print..."), this);
531 m_actionPrint->setShortcut (QKeySequence::Print);
532 m_actionPrint->setStatusTip (tr ("Print the current document."));
533 m_actionPrint->setWhatsThis (tr ("Print Document\n\n"
534 "Print the current document to a printer or file."));
535 connect (m_actionPrint, SIGNAL (triggered ()), this, SLOT (slotFilePrint ()));
536
537 m_actionExit = new QAction(tr ("&Exit"), this);
538 m_actionExit->setShortcut (QKeySequence::Quit);
539 m_actionExit->setStatusTip (tr ("Quits the application."));
540 m_actionExit->setWhatsThis (tr ("Exit\n\n"
541 "Quits the application."));
542 connect (m_actionExit, SIGNAL (triggered ()), this, SLOT (close ()));
543}
544
545void MainWindow::createActionsHelp ()
546{
547 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createActionsHelp";
548
549 m_actionHelpChecklistGuideWizard = new QAction (tr ("Checklist Guide Wizard"), this);
550 m_actionHelpChecklistGuideWizard->setCheckable (true);
551 m_actionHelpChecklistGuideWizard->setStatusTip (tr ("Open Checklist Guide Wizard during import to define digitizing steps"));
552 m_actionHelpChecklistGuideWizard->setWhatsThis (tr ("Checklist Guide Wizard\n\n"
553 "Use Checklist Guide Wizard during import to generate a checklist of steps "
554 "for the imported document"));
555
556 m_actionHelpWhatsThis = QWhatsThis::createAction(this);
557 m_actionHelpWhatsThis->setShortcut (QKeySequence::WhatsThis);
558
559 m_actionHelpTutorial = new QAction (tr ("Tutorial"), this);
560 m_actionHelpTutorial->setStatusTip (tr ("Play tutorial showing steps for digitizing curves"));
561 m_actionHelpTutorial->setWhatsThis (tr ("Tutorial\n\n"
562 "Play tutorial showing steps for digitizing points from curves drawn with lines "
563 "and/or point"));
564 connect (m_actionHelpTutorial, SIGNAL (triggered ()), this, SLOT (slotHelpTutorial()));
565
566 m_actionHelpHelp = new QAction (tr ("Help"), this);
567 m_actionHelpHelp->setShortcut (QKeySequence::HelpContents);
568 m_actionHelpHelp->setStatusTip (tr ("Help documentation"));
569 m_actionHelpHelp->setWhatsThis (tr ("Help Documentation\n\n"
570 "Searchable help documentation"));
571 // This action gets connected directly to the QDockWidget when that is created
572
573 m_actionHelpAbout = new QAction(tr ("About Engauge"), this);
574 m_actionHelpAbout->setStatusTip (tr ("About the application."));
575 m_actionHelpAbout->setWhatsThis (tr ("About Engauge\n\nAbout the application."));
576 connect (m_actionHelpAbout, SIGNAL (triggered ()), this, SLOT (slotHelpAbout ()));
577}
578
579void MainWindow::createActionsSettings ()
580{
581 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createActionsSettings";
582
583 m_actionSettingsCoords = new QAction (tr ("Coordinates..."), this);
584 m_actionSettingsCoords->setStatusTip (tr ("Edit Coordinate settings."));
585 m_actionSettingsCoords->setWhatsThis (tr ("Coordinate Settings\n\n"
586 "Coordinate settings determine how the graph coordinates are mapped to the pixels in the image"));
587 connect (m_actionSettingsCoords, SIGNAL (triggered ()), this, SLOT (slotSettingsCoords ()));
588
589 m_actionSettingsCurveAddRemove = new QAction (tr ("Add/Remove Curve..."), this);
590 m_actionSettingsCurveAddRemove->setStatusTip (tr ("Add or Remove Curves."));
591 m_actionSettingsCurveAddRemove->setWhatsThis (tr ("Add/Remove Curve\n\n"
592 "Add/Remove Curve settings control which curves are included in the current document"));
593 connect (m_actionSettingsCurveAddRemove, SIGNAL (triggered ()), this, SLOT (slotSettingsCurveAddRemove ()));
594
595 m_actionSettingsCurveProperties = new QAction (tr ("Curve Properties..."), this);
596 m_actionSettingsCurveProperties->setStatusTip (tr ("Edit Curve Properties settings."));
597 m_actionSettingsCurveProperties->setWhatsThis (tr ("Curve Properties Settings\n\n"
598 "Curves properties settings determine how each curve appears"));
599 connect (m_actionSettingsCurveProperties, SIGNAL (triggered ()), this, SLOT (slotSettingsCurveProperties ()));
600
601 m_actionSettingsDigitizeCurve = new QAction (tr ("Digitize Curve..."), this);
602 m_actionSettingsDigitizeCurve->setStatusTip (tr ("Edit Digitize Axis and Graph Curve settings."));
603 m_actionSettingsDigitizeCurve->setWhatsThis (tr ("Digitize Axis and Graph Curve Settings\n\n"
604 "Digitize Curve settings determine how points are digitized in Digitize Axis Point and "
605 "Digitize Graph Point modes"));
606 connect (m_actionSettingsDigitizeCurve, SIGNAL (triggered ()), this, SLOT (slotSettingsDigitizeCurve ()));
607
608 m_actionSettingsExport = new QAction (tr ("Export Format..."), this);
609 m_actionSettingsExport->setStatusTip (tr ("Edit Export Format settings."));
610 m_actionSettingsExport->setWhatsThis (tr ("Export Format Settings\n\n"
611 "Export format settings affect how exported files are formatted"));
612 connect (m_actionSettingsExport, SIGNAL (triggered ()), this, SLOT (slotSettingsExportFormat ()));
613
614 m_actionSettingsColorFilter = new QAction (tr ("Color Filter..."), this);
615 m_actionSettingsColorFilter->setStatusTip (tr ("Edit Color Filter settings."));
616 m_actionSettingsColorFilter->setWhatsThis (tr ("Color Filter Settings\n\n"
617 "Color filtering simplifies the graphs for easier Point Matching and Segment Filling"));
618 connect (m_actionSettingsColorFilter, SIGNAL (triggered ()), this, SLOT (slotSettingsColorFilter ()));
619
620 m_actionSettingsAxesChecker = new QAction (tr ("Axes Checker..."), this);
621 m_actionSettingsAxesChecker->setStatusTip (tr ("Edit Axes Checker settings."));
622 m_actionSettingsAxesChecker->setWhatsThis (tr ("Axes Checker Settings\n\n"
623 "Axes checker can reveal any axis point mistakes, which are otherwise hard to find."));
624 connect (m_actionSettingsAxesChecker, SIGNAL (triggered ()), this, SLOT (slotSettingsAxesChecker ()));
625
626 m_actionSettingsGridRemoval = new QAction (tr ("Grid Line Removal..."), this);
627 m_actionSettingsGridRemoval->setStatusTip (tr ("Edit Grid Line Removal settings."));
628 m_actionSettingsGridRemoval->setWhatsThis (tr ("Grid Line Removal Settings\n\n"
629 "Grid line removal isolates curve lines for easier Point Matching and Segment Filling, when "
630 "Color Filtering is not able to separate grid lines from curve lines."));
631 connect (m_actionSettingsGridRemoval, SIGNAL (triggered ()), this, SLOT (slotSettingsGridRemoval ()));
632
633 m_actionSettingsPointMatch = new QAction (tr ("Point Match..."), this);
634 m_actionSettingsPointMatch->setStatusTip (tr ("Edit Point Match settings."));
635 m_actionSettingsPointMatch->setWhatsThis (tr ("Point Match Settings\n\n"
636 "Point match settings determine how points are matched while in Point Match mode"));
637 connect (m_actionSettingsPointMatch, SIGNAL (triggered ()), this, SLOT (slotSettingsPointMatch ()));
638
639 m_actionSettingsSegments = new QAction (tr ("Segment Fill..."), this);
640 m_actionSettingsSegments->setStatusTip (tr ("Edit Segment Fill settings."));
641 m_actionSettingsSegments->setWhatsThis (tr ("Segment Fill Settings\n\n"
642 "Segment fill settings determine how points are generated in the Segment Fill mode"));
643 connect (m_actionSettingsSegments, SIGNAL (triggered ()), this, SLOT (slotSettingsSegments ()));
644
645 m_actionSettingsGeneral = new QAction (tr ("General..."), this);
646 m_actionSettingsGeneral->setStatusTip (tr ("Edit General settings."));
647 m_actionSettingsGeneral->setWhatsThis (tr ("General Settings\n\n"
648 "General settings are document-specific settings that affect multiple modes. For example, the cursor size setting affects "
649 "both Color Picker and Point Match modes"));
650 connect (m_actionSettingsGeneral, SIGNAL (triggered ()), this, SLOT (slotSettingsGeneral ()));
651
652 m_actionSettingsMainWindow = new QAction (tr ("Main Window..."), this);
653 m_actionSettingsMainWindow->setEnabled (true);
654 m_actionSettingsMainWindow->setStatusTip (tr ("Edit Main Window settings."));
655 m_actionSettingsMainWindow->setWhatsThis (tr ("Main Window Settings\n\n"
656 "Main window settings affect the user interface and are not specific to any document"));
657 connect (m_actionSettingsMainWindow, SIGNAL (triggered ()), this, SLOT (slotSettingsMainWindow ()));
658}
659
660void MainWindow::createActionsView ()
661{
662 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createActionsView";
663
664 m_actionViewBackground = new QAction (tr ("Background Toolbar"), this);
665 m_actionViewBackground->setCheckable (true);
666 m_actionViewBackground->setChecked (true);
667 m_actionViewBackground->setStatusTip (tr ("Show or hide the background toolbar."));
668 m_actionViewBackground->setWhatsThis (tr ("View Background ToolBar\n\n"
669 "Show or hide the background toolbar"));
670 connect (m_actionViewBackground, SIGNAL (triggered ()), this, SLOT (slotViewToolBarBackground ()));
671
672 m_actionViewChecklistGuide = new QAction (tr ("Checklist Guide Toolbar"), this);
673 m_actionViewChecklistGuide->setCheckable (true);
674 m_actionViewChecklistGuide->setChecked (false);
675 m_actionViewChecklistGuide->setStatusTip (tr ("Show or hide the checklist guide toolbar."));
676 m_actionViewChecklistGuide->setWhatsThis (tr ("View Checklist Guide ToolBar\n\n"
677 "Show or hide the checklist guide toolbar"));
678 connect (m_actionViewChecklistGuide, SIGNAL (changed ()), this, SLOT (slotViewToolBarChecklistGuide()));
679
680 m_actionViewDigitize = new QAction (tr ("Digitizing Tools Toolbar"), this);
681 m_actionViewDigitize->setCheckable (true);
682 m_actionViewDigitize->setChecked (true);
683 m_actionViewDigitize->setStatusTip (tr ("Show or hide the digitizing tools toolbar."));
684 m_actionViewDigitize->setWhatsThis (tr ("View Digitizing Tools ToolBar\n\n"
685 "Show or hide the digitizing tools toolbar"));
686 connect (m_actionViewDigitize, SIGNAL (triggered ()), this, SLOT (slotViewToolBarDigitize()));
687
688 m_actionViewSettingsViews = new QAction (tr ("Settings Views Toolbar"), this);
689 m_actionViewSettingsViews->setCheckable (true);
690 m_actionViewSettingsViews->setChecked (true);
691 m_actionViewSettingsViews->setStatusTip (tr ("Show or hide the settings views toolbar."));
692 m_actionViewSettingsViews->setWhatsThis (tr ("View Settings Views ToolBar\n\n"
693 "Show or hide the settings views toolbar. These views graphically show the "
694 "most important settings."));
695 connect (m_actionViewSettingsViews, SIGNAL (triggered ()), this, SLOT (slotViewToolBarSettingsViews()));
696
697 m_actionViewCoordSystem = new QAction (tr ("Coordinate System Toolbar"), this);
698 m_actionViewCoordSystem->setCheckable (true);
699 m_actionViewCoordSystem->setChecked (false);
700 m_actionViewCoordSystem->setStatusTip (tr ("Show or hide the coordinate system toolbar."));
701 m_actionViewCoordSystem->setWhatsThis (tr ("View Coordinate Systems ToolBar\n\n"
702 "Show or hide the coordinate system selection toolbar. This toolbar is used "
703 "to select the current coordinate system when the document has multiple "
704 "coordinate systems. This toolbar is also used to view and print all coordinate "
705 "systems.\n\n"
706 "This toolbar is disabled when there is only one coordinate system."));
707 connect (m_actionViewCoordSystem, SIGNAL (triggered ()), this, SLOT (slotViewToolBarCoordSystem()));
708
709 m_actionViewToolTips = new QAction (tr ("Tool Tips"), this);
710 m_actionViewToolTips->setCheckable (true);
711 m_actionViewToolTips->setChecked (true);
712 m_actionViewToolTips->setStatusTip (tr ("Show or hide the tool tips."));
713 m_actionViewToolTips->setWhatsThis (tr ("View Tool Tips\n\n"
714 "Show or hide the tool tips"));
715 connect (m_actionViewToolTips, SIGNAL (triggered ()), this, SLOT (slotViewToolTips()));
716
717 m_actionViewBackgroundNone = new QAction (tr ("No Background"), this);
718 m_actionViewBackgroundNone->setCheckable (true);
719 m_actionViewBackgroundNone->setStatusTip (tr ("Do not show the image underneath the points."));
720 m_actionViewBackgroundNone->setWhatsThis (tr ("No Background\n\n"
721 "No image is shown so points are easier to see"));
722
723 m_actionViewBackgroundOriginal = new QAction (tr ("Show Original Image"), this);
724 m_actionViewBackgroundOriginal->setCheckable (true);
725 m_actionViewBackgroundOriginal->setStatusTip (tr ("Show the original image underneath the points."));
726 m_actionViewBackgroundOriginal->setWhatsThis (tr ("Show Original Image\n\n"
727 "Show the original image underneath the points"));
728
729 m_actionViewBackgroundFiltered = new QAction (tr ("Show Filtered Image"), this);
730 m_actionViewBackgroundFiltered->setCheckable (true);
731 m_actionViewBackgroundFiltered->setChecked (true);
732 m_actionViewBackgroundFiltered->setStatusTip (tr ("Show the filtered image underneath the points."));
733 m_actionViewBackgroundFiltered->setWhatsThis (tr ("Show Filtered Image\n\n"
734 "Show the filtered image underneath the points.\n\n"
735 "The filtered image is created from the original image according to the "
736 "Filter preferences so unimportant information is hidden and important "
737 "information is emphasized"));
738
739 m_actionViewCurvesNone = new QAction (tr ("Hide All Curves"), this);
740 m_actionViewCurvesNone->setCheckable (true);
741 m_actionViewCurvesNone->setStatusTip (tr ("Hide all digitized curves."));
742 m_actionViewCurvesNone->setWhatsThis (tr ("Hide All Curves\n\n"
743 "No axis points or digitized graph curves are shown so the image is easier to see."));
744
745 m_actionViewCurvesSelected = new QAction (tr ("Show Selected Curve"), this);
746 m_actionViewCurvesSelected->setCheckable (true);
747 m_actionViewCurvesSelected->setStatusTip (tr ("Show only the currently selected curve."));
748 m_actionViewCurvesSelected->setWhatsThis (tr ("Show Selected Curve\n\n"
749 "Show only the digitized points and line that belong to the currently selected curve."));
750
751 m_actionViewCurvesAll = new QAction (tr ("Show All Curves"), this);
752 m_actionViewCurvesAll->setCheckable (true);
753 m_actionViewCurvesAll->setChecked (true);
754 m_actionViewCurvesAll->setStatusTip (tr ("Show all curves."));
755 m_actionViewCurvesAll->setWhatsThis (tr ("Show All Curves\n\n"
756 "Show all digitized axis points and graph curves"));
757
758 m_groupBackground = new QActionGroup(this);
759 m_groupBackground->addAction (m_actionViewBackgroundNone);
760 m_groupBackground->addAction (m_actionViewBackgroundOriginal);
761 m_groupBackground->addAction (m_actionViewBackgroundFiltered);
762 connect (m_groupBackground, SIGNAL(triggered (QAction*)), this, SLOT (slotViewGroupBackground(QAction*)));
763
764 m_groupCurves = new QActionGroup(this);
765 m_groupCurves->addAction (m_actionViewCurvesNone);
766 m_groupCurves->addAction (m_actionViewCurvesSelected);
767 m_groupCurves->addAction (m_actionViewCurvesAll);
768 connect (m_groupCurves, SIGNAL(triggered (QAction*)), this, SLOT (slotViewGroupCurves(QAction*)));
769
770 m_actionStatusNever = new QAction (tr ("Hide Always"), this);
771 m_actionStatusNever->setCheckable(true);
772 m_actionStatusNever->setStatusTip (tr ("Always hide the status bar."));
773 m_actionStatusNever->setWhatsThis (tr ("Hide the status bar. No temporary status or feedback messages will appear."));
774
775 m_actionStatusTemporary = new QAction (tr ("Show Temporary Messages"), this);
776 m_actionStatusTemporary->setCheckable(true);
777 m_actionStatusTemporary->setStatusTip (tr ("Hide the status bar except when display temporary messages."));
778 m_actionStatusTemporary->setWhatsThis (tr ("Hide the status bar, except when displaying temporary status and feedback messages."));
779
780 m_actionStatusAlways = new QAction (tr ("Show Always"), this);
781 m_actionStatusAlways->setCheckable(true);
782 m_actionStatusAlways->setStatusTip (tr ("Always show the status bar."));
783 m_actionStatusAlways->setWhatsThis (tr ("Show the status bar. Besides displaying temporary status and feedback messages, "
784 "the status bar also displays information about the cursor position."));
785
786 m_groupStatus = new QActionGroup(this);
787 m_groupStatus->addAction (m_actionStatusNever);
788 m_groupStatus->addAction (m_actionStatusTemporary);
789 m_groupStatus->addAction (m_actionStatusAlways);
790 connect (m_groupStatus, SIGNAL (triggered (QAction*)), this, SLOT (slotViewGroupStatus(QAction*)));
791
792 m_actionZoomOut = new QAction (tr ("Zoom Out"), this);
793 m_actionZoomOut->setStatusTip (tr ("Zoom out"));
794 // setShortCut is called by updateSettingsMainWindow
795 connect (m_actionZoomOut, SIGNAL (triggered ()), this, SLOT (slotViewZoomOut ()));
796
797 m_actionZoomIn = new QAction (tr ("Zoom In"), this);
798 m_actionZoomIn->setStatusTip (tr ("Zoom in"));
799 // setShortCut is called by updateSettingsMainWindow
800 connect (m_actionZoomIn, SIGNAL (triggered ()), this, SLOT (slotViewZoomIn ()));
801
802 m_actionZoom16To1 = new QAction (tr ("16:1 (1600%)"), this);
803 m_actionZoom16To1->setCheckable (true);
804 m_actionZoom16To1->setStatusTip (tr ("Zoom 16:1"));
805 connect (m_actionZoom16To1, SIGNAL (triggered ()), this, SLOT (slotViewZoom16To1 ()));
806
807 m_actionZoom8To1 = new QAction (tr ("8:1 (800%)"), this);
808 m_actionZoom8To1->setCheckable (true);
809 m_actionZoom8To1->setStatusTip (tr ("Zoom 8:1"));
810 connect (m_actionZoom8To1, SIGNAL (triggered ()), this, SLOT (slotViewZoom8To1 ()));
811
812 m_actionZoom4To1 = new QAction (tr ("4:1 (400%)"), this);
813 m_actionZoom4To1->setCheckable (true);
814 m_actionZoom4To1->setStatusTip (tr ("Zoom 4:1"));
815 connect (m_actionZoom4To1, SIGNAL (triggered ()), this, SLOT (slotViewZoom4To1 ()));
816
817 m_actionZoom2To1 = new QAction (tr ("2:1 (200%)"), this);
818 m_actionZoom2To1->setCheckable (true);
819 m_actionZoom2To1->setStatusTip (tr ("Zoom 2:1"));
820 connect (m_actionZoom2To1, SIGNAL (triggered ()), this, SLOT (slotViewZoom2To1 ()));
821
822 m_actionZoom1To1 = new QAction (tr ("1:1 (100%)"), this);
823 m_actionZoom1To1->setCheckable (true);
824 m_actionZoom1To1->setChecked (true);
825 m_actionZoom1To1->setStatusTip (tr ("Zoom 6:1"));
826 connect (m_actionZoom1To1, SIGNAL (triggered ()), this, SLOT (slotViewZoom1To1 ()));
827
828 m_actionZoom1To2 = new QAction (tr ("1:2 (50%)"), this);
829 m_actionZoom1To2->setCheckable (true);
830 m_actionZoom1To2->setStatusTip (tr ("Zoom 1:2"));
831 connect (m_actionZoom1To2, SIGNAL (triggered ()), this, SLOT (slotViewZoom1To2 ()));
832
833 m_actionZoom1To4 = new QAction (tr ("1:4 (25%)"), this);
834 m_actionZoom1To4->setCheckable (true);
835 m_actionZoom1To4->setStatusTip (tr ("Zoom 1:4"));
836 connect (m_actionZoom1To4, SIGNAL (triggered ()), this, SLOT (slotViewZoom1To4 ()));
837
838 m_actionZoom1To8 = new QAction (tr ("1:8 (12.5%)"), this);
839 m_actionZoom1To8->setCheckable (true);
840 m_actionZoom1To8->setStatusTip (tr ("Zoom 1:8"));
841 connect (m_actionZoom1To8, SIGNAL (triggered ()), this, SLOT (slotViewZoom1To8 ()));
842
843 m_actionZoom1To16 = new QAction (tr ("1:16 (6.25%)"), this);
844 m_actionZoom1To16->setCheckable (true);
845 m_actionZoom1To16->setStatusTip (tr ("Zoom 1:16"));
846 connect (m_actionZoom1To16, SIGNAL (triggered ()), this, SLOT (slotViewZoom1To16 ()));
847
848 m_actionZoomFill = new QAction (tr ("Fill"), this);
849 m_actionZoomFill->setCheckable (true);
850 m_actionZoomFill->setStatusTip (tr ("Zoom with stretching to fill window"));
851 connect (m_actionZoomFill, SIGNAL (triggered ()), this, SLOT (slotViewZoomFill ()));
852
853 m_groupZoom = new QActionGroup (this);
854 m_groupZoom->addAction (m_actionZoom16To1);
855 m_groupZoom->addAction (m_actionZoom8To1);
856 m_groupZoom->addAction (m_actionZoom4To1);
857 m_groupZoom->addAction (m_actionZoom2To1);
858 m_groupZoom->addAction (m_actionZoom1To1);
859 m_groupZoom->addAction (m_actionZoom1To2);
860 m_groupZoom->addAction (m_actionZoom1To4);
861 m_groupZoom->addAction (m_actionZoom1To8);
862 m_groupZoom->addAction (m_actionZoom1To16);
863 m_groupZoom->addAction (m_actionZoomFill);
864}
865
866void MainWindow::createCentralWidget ()
867{
868 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createCentralWidget";
869
870 QWidget *widget = new QWidget;
871 setCentralWidget (widget);
872 m_layout = new QVBoxLayout;
873 widget->setLayout (m_layout);
874}
875
876void MainWindow::createCommandStackShadow ()
877{
878 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createCommandStackShadow";
879
880 m_cmdStackShadow = new CmdStackShadow;
881}
882
883void MainWindow::createHelpWindow ()
884{
885 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createHelpWindow";
886
887 m_helpWindow = new HelpWindow (this);
888 m_helpWindow->hide ();
889 addDockWidget (Qt::RightDockWidgetArea,
890 m_helpWindow); // Dock area is required by addDockWidget but immediately overridden in next line
891 m_helpWindow->setFloating (true);
892
893 connect (m_actionHelpHelp, SIGNAL (triggered ()), m_helpWindow, SLOT (show ()));
894}
895
896void MainWindow::createIcons()
897{
898 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createIcons";
899
900 QIcon icon;
901 QPixmap icon16 (bannerapp_16);
902 QPixmap icon32 (bannerapp_32);
903 QPixmap icon64 (bannerapp_64);
904 QPixmap icon128 (bannerapp_128);
905 QPixmap icon256 (bannerapp_256);
906
907 icon.addPixmap (icon16);
908 icon.addPixmap (icon32);
909 icon.addPixmap (icon64);
910 icon.addPixmap (icon128);
911 icon.addPixmap (icon256);
912
913 setWindowIcon (icon);
914}
915
916void MainWindow::createLoadImageFromUrl ()
917{
918 m_loadImageFromUrl = new LoadImageFromUrl (*this);
919}
920
921void MainWindow::createMenus()
922{
923 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createMenus";
924
925 m_menuFile = menuBar()->addMenu(tr("&File"));
926 m_menuFile->addAction (m_actionImport);
927 m_menuFile->addAction (m_actionImportAdvanced);
928 m_menuFile->addAction (m_actionOpen);
929 m_menuFileOpenRecent = new QMenu (tr ("Open &Recent"));
930 for (unsigned int i = 0; i < MAX_RECENT_FILE_LIST_SIZE; i++) {
931 m_menuFileOpenRecent->addAction (m_actionRecentFiles.at (i));
932 }
933 m_menuFile->addMenu (m_menuFileOpenRecent);
934 m_menuFile->addAction (m_actionClose);
935 m_menuFile->insertSeparator (m_actionSave);
936 m_menuFile->addAction (m_actionSave);
937 m_menuFile->addAction (m_actionSaveAs);
938 m_menuFile->addAction (m_actionExport);
939 m_menuFile->insertSeparator (m_actionPrint);
940 m_menuFile->addAction (m_actionPrint);
941 m_menuFile->insertSeparator (m_actionExit);
942 m_menuFile->addAction (m_actionExit);
943
944 m_menuEdit = menuBar()->addMenu(tr("&Edit"));
945 connect (m_menuEdit, SIGNAL (aboutToShow ()), this, SLOT (slotEditMenu ()));
946 m_menuEdit->addAction (m_actionEditUndo);
947 m_menuEdit->addAction (m_actionEditRedo);
948 m_menuEdit->insertSeparator (m_actionEditCut);
949 m_menuEdit->addAction (m_actionEditCut);
950 m_menuEdit->addAction (m_actionEditCopy);
951 m_menuEdit->addAction (m_actionEditPaste);
952 m_menuEdit->addAction (m_actionEditDelete);
953 m_menuEdit->insertSeparator (m_actionEditPasteAsNew);
954 m_menuEdit->addAction (m_actionEditPasteAsNew);
955 m_menuEdit->addAction (m_actionEditPasteAsNewAdvanced);
956
957 m_menuDigitize = menuBar()->addMenu(tr("Digitize"));
958 m_menuDigitize->addAction (m_actionDigitizeSelect);
959 m_menuDigitize->addAction (m_actionDigitizeAxis);
960 m_menuDigitize->addAction (m_actionDigitizeCurve);
961 m_menuDigitize->addAction (m_actionDigitizePointMatch);
962 m_menuDigitize->addAction (m_actionDigitizeColorPicker);
963 m_menuDigitize->addAction (m_actionDigitizeSegment);
964
965 m_menuView = menuBar()->addMenu(tr("View"));
966 m_menuView->addAction (m_actionViewBackground);
967 m_menuView->addAction (m_actionViewDigitize);
968 m_menuView->addAction (m_actionViewChecklistGuide);
969 m_menuView->addAction (m_actionViewSettingsViews);
970 m_menuView->addAction (m_actionViewCoordSystem);
971 m_menuView->insertSeparator (m_actionViewToolTips);
972 m_menuView->addAction (m_actionViewToolTips);
973 m_menuView->insertSeparator (m_actionViewBackgroundNone);
974 m_menuViewBackground = new QMenu (tr ("Background"));
975 m_menuViewBackground->addAction (m_actionViewBackgroundNone);
976 m_menuViewBackground->addAction (m_actionViewBackgroundOriginal);
977 m_menuViewBackground->addAction (m_actionViewBackgroundFiltered);
978 m_menuView->addMenu (m_menuViewBackground);
979 m_menuViewCurves = new QMenu (tr ("Curves"));
980 m_menuViewCurves->addAction (m_actionViewCurvesNone);
981 m_menuViewCurves->addAction (m_actionViewCurvesSelected);
982 m_menuViewCurves->addAction (m_actionViewCurvesAll);
983 m_menuView->addMenu (m_menuViewCurves);
984 m_menuViewStatus = new QMenu (tr ("Status Bar"));
985 m_menuViewStatus->addAction (m_actionStatusNever);
986 m_menuViewStatus->addAction (m_actionStatusTemporary);
987 m_menuViewStatus->addAction (m_actionStatusAlways);
988 m_menuView->addMenu (m_menuViewStatus);
989 m_menuViewZoom = new QMenu (tr ("Zoom"));
990 m_menuViewZoom->addAction (m_actionZoomOut);
991 m_menuViewZoom->addAction (m_actionZoomIn);
992 m_menuViewZoom->insertSeparator (m_actionZoom16To1);
993 m_menuViewZoom->addAction (m_actionZoom16To1);
994 m_menuViewZoom->addAction (m_actionZoom8To1);
995 m_menuViewZoom->addAction (m_actionZoom4To1);
996 m_menuViewZoom->addAction (m_actionZoom2To1);
997 m_menuViewZoom->addAction (m_actionZoom1To1);
998 m_menuViewZoom->addAction (m_actionZoom1To2);
999 m_menuViewZoom->addAction (m_actionZoom1To4);
1000 m_menuViewZoom->addAction (m_actionZoom1To8);
1001 m_menuViewZoom->addAction (m_actionZoom1To16);
1002 m_menuViewZoom->addAction (m_actionZoomFill);
1003 m_menuView->addMenu (m_menuViewZoom);
1004
1005 m_menuSettings = menuBar()->addMenu(tr ("Settings"));
1006 m_menuSettings->addAction (m_actionSettingsCoords);
1007 m_menuSettings->addAction (m_actionSettingsCurveAddRemove);
1008 m_menuSettings->addAction (m_actionSettingsCurveProperties);
1009 m_menuSettings->addAction (m_actionSettingsDigitizeCurve);
1010 m_menuSettings->addAction (m_actionSettingsExport);
1011 m_menuSettings->addAction (m_actionSettingsColorFilter);
1012 m_menuSettings->addAction (m_actionSettingsAxesChecker);
1013 m_menuSettings->addAction (m_actionSettingsGridRemoval);
1014 m_menuSettings->addAction (m_actionSettingsPointMatch);
1015 m_menuSettings->addAction (m_actionSettingsSegments);
1016 m_menuSettings->insertSeparator (m_actionSettingsGeneral);
1017 m_menuSettings->addAction (m_actionSettingsGeneral);
1018 m_menuSettings->addAction (m_actionSettingsMainWindow);
1019
1020 m_menuHelp = menuBar()->addMenu(tr("&Help"));
1021 m_menuHelp->addAction (m_actionHelpChecklistGuideWizard);
1022 m_menuHelp->insertSeparator(m_actionHelpWhatsThis);
1023 m_menuHelp->addAction (m_actionHelpWhatsThis);
1024 m_menuHelp->addAction (m_actionHelpTutorial);
1025 m_menuHelp->addAction (m_actionHelpHelp);
1026 m_menuHelp->addAction (m_actionHelpAbout);
1027
1028 updateRecentFileList();
1029}
1030
1031void MainWindow::createNetwork ()
1032{
1033 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createNetwork";
1034
1035 m_networkClient = new NetworkClient (this);
1036}
1037
1038void MainWindow::createSettingsDialogs ()
1039{
1040 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createSettingsDialogs";
1041
1042 m_dlgSettingsCoords = new DlgSettingsCoords (*this);
1043 m_dlgSettingsCurveAddRemove = new DlgSettingsCurveAddRemove (*this);
1044 m_dlgSettingsCurveProperties = new DlgSettingsCurveProperties (*this);
1045 m_dlgSettingsDigitizeCurve = new DlgSettingsDigitizeCurve (*this);
1046 m_dlgSettingsExportFormat = new DlgSettingsExportFormat (*this);
1047 m_dlgSettingsColorFilter = new DlgSettingsColorFilter (*this);
1048 m_dlgSettingsAxesChecker = new DlgSettingsAxesChecker (*this);
1049 m_dlgSettingsGridRemoval = new DlgSettingsGridRemoval (*this);
1050 m_dlgSettingsPointMatch = new DlgSettingsPointMatch (*this);
1051 m_dlgSettingsSegments = new DlgSettingsSegments (*this);
1052 m_dlgSettingsGeneral = new DlgSettingsGeneral (*this);
1053 m_dlgSettingsMainWindow = new DlgSettingsMainWindow (*this);
1054
1055 m_dlgSettingsCoords->setVisible (false);
1056 m_dlgSettingsCurveAddRemove->setVisible (false);
1057 m_dlgSettingsCurveProperties->setVisible (false);
1058 m_dlgSettingsDigitizeCurve->setVisible (false);
1059 m_dlgSettingsExportFormat->setVisible (false);
1060 m_dlgSettingsColorFilter->setVisible (false);
1061 m_dlgSettingsAxesChecker->setVisible (false);
1062 m_dlgSettingsGridRemoval->setVisible (false);
1063 m_dlgSettingsPointMatch->setVisible (false);
1064 m_dlgSettingsSegments->setVisible (false);
1065 m_dlgSettingsGeneral->setVisible (false);
1066 m_dlgSettingsMainWindow->setVisible (false);
1067}
1068
1069void MainWindow::createScene ()
1070{
1071 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createScene";
1072
1073 m_scene = new GraphicsScene (this);
1074 m_view = new GraphicsView (m_scene, *this);
1075 m_layout->addWidget (m_view);
1076}
1077
1078void MainWindow::createStateContextBackground ()
1079{
1080 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createStateContextBackground";
1081
1082 m_backgroundStateContext = new BackgroundStateContext (*this);
1083}
1084
1085void MainWindow::createStateContextDigitize ()
1086{
1087 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createStateContextDigitize";
1088
1089 m_digitizeStateContext = new DigitizeStateContext (*this,
1090 *m_view,
1091 m_isGnuplot);
1092}
1093
1094void MainWindow::createStateContextTransformation ()
1095{
1096 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createStateContextTransformation";
1097
1098 ENGAUGE_CHECK_PTR (m_scene);
1099
1100 m_transformationStateContext = new TransformationStateContext (*m_scene,
1101 m_isGnuplot);
1102}
1103
1104void MainWindow::createStatusBar ()
1105{
1106 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createStatusBar";
1107
1108 m_statusBar = new StatusBar (*statusBar ());
1109 connect (this, SIGNAL (signalZoom(int)), m_statusBar, SLOT (slotZoom(int)));
1110 connect (m_statusBar, SIGNAL (signalZoom (int)), this, SLOT (slotViewZoom (int)));
1111}
1112
1113void MainWindow::createToolBars ()
1114{
1115 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createToolBars";
1116
1117 const int VIEW_SIZE = 22;
1118
1119 // Background toolbar widgets
1120 m_cmbBackground = new QComboBox ();
1121 m_cmbBackground->setEnabled (false);
1122 m_cmbBackground->setStatusTip (tr ("Select background image"));
1123 m_cmbBackground->setWhatsThis (tr ("Selected Background\n\n"
1124 "Select background image:\n"
1125 "1) No background which highlights points\n"
1126 "2) Original image which shows everything\n"
1127 "3) Filtered image which highlights important details"));
1128 m_cmbBackground->addItem (tr ("No background"), QVariant (BACKGROUND_IMAGE_NONE));
1129 m_cmbBackground->addItem (tr ("Original image"), QVariant (BACKGROUND_IMAGE_ORIGINAL));
1130 m_cmbBackground->addItem (tr ("Filtered image"), QVariant (BACKGROUND_IMAGE_FILTERED));
1131 // selectBackgroundOriginal needs currentIndexChanged
1132 connect (m_cmbBackground, SIGNAL (currentIndexChanged (int)), this, SLOT (slotCmbBackground (int)));
1133
1134 // Background toolbar
1135 m_toolBackground = new QToolBar (tr ("Background"), this);
1136 m_toolBackground->addWidget (m_cmbBackground);
1137 addToolBar (m_toolBackground);
1138
1139 // Digitize toolbar widgets that are not created elsewhere
1140 m_cmbCurve = new QComboBox ();
1141 m_cmbCurve->setEnabled (false);
1142 m_cmbCurve->setMinimumWidth (180);
1143 m_cmbCurve->setStatusTip (tr ("Select curve for new points."));
1144 m_cmbCurve->setWhatsThis (tr ("Selected Curve Name\n\n"
1145 "Select curve for any new points. Every point belongs to one curve."));
1146 connect (m_cmbCurve, SIGNAL (activated (int)), this, SLOT (slotCmbCurve (int))); // activated() ignores code changes
1147
1148 // Digitize toolbar
1149 m_toolDigitize = new QToolBar (tr ("Drawing"), this);
1150 m_toolDigitize->addAction (m_actionDigitizeSelect);
1151 m_toolDigitize->insertSeparator (m_actionDigitizeAxis);
1152 m_toolDigitize->addAction (m_actionDigitizeAxis);
1153 m_toolDigitize->insertSeparator (m_actionDigitizeCurve);
1154 m_toolDigitize->addAction (m_actionDigitizeCurve);
1155 m_toolDigitize->addAction (m_actionDigitizePointMatch);
1156 m_toolDigitize->addAction (m_actionDigitizeColorPicker);
1157 m_toolDigitize->addAction (m_actionDigitizeSegment);
1158 m_toolDigitize->addWidget (m_cmbCurve);
1159 addToolBar (m_toolDigitize);
1160
1161 // Views toolbar widgets
1162 m_viewPointStyle = new ViewPointStyle();
1163 m_viewPointStyle->setMinimumSize(VIEW_SIZE, VIEW_SIZE);
1164 m_viewPointStyle->setMaximumSize(VIEW_SIZE, VIEW_SIZE);
1165 m_viewPointStyle->setStatusTip (tr ("Points style for the currently selected curve"));
1166 m_viewPointStyle->setWhatsThis (tr ("Points Style\n\n"
1167 "Points style for the currently selected curve. The points style is only "
1168 "displayed in this toolbar. To change the points style, "
1169 "use the Curve Properties dialog."));
1170
1171 m_viewSegmentFilter = new ViewSegmentFilter();
1172 m_viewSegmentFilter->setMinimumSize(VIEW_SIZE, VIEW_SIZE);
1173 m_viewSegmentFilter->setMaximumSize(VIEW_SIZE, VIEW_SIZE);
1174 m_viewSegmentFilter->setStatusTip (tr ("View of filter for current curve in Segment Fill mode"));
1175 m_viewSegmentFilter->setWhatsThis (tr ("Segment Fill Filter\n\n"
1176 "View of filter for the current curve in Segment Fill mode. The filter settings are only "
1177 "displayed in this toolbar. To changed the filter settings, "
1178 "use the Color Picker mode or the Filter Settings dialog."));
1179
1180 // Settings views toolbar
1181 m_toolSettingsViews = new QToolBar (tr ("Views"), this);
1182 m_toolSettingsViews->addWidget (m_viewPointStyle);
1183 m_toolSettingsViews->addWidget (new QLabel (" ")); // A hack, but this works to put some space between the adjacent widgets
1184 m_toolSettingsViews->addWidget (m_viewSegmentFilter);
1185 addToolBar (m_toolSettingsViews);
1186
1187 // Coordinate system toolbar
1188 m_cmbCoordSystem = new QComboBox;
1189 m_cmbCoordSystem->setEnabled (false);
1190 m_cmbCoordSystem->setStatusTip (tr ("Currently selected coordinate system"));
1191 m_cmbCoordSystem->setWhatsThis (tr ("Selected Coordinate System\n\n"
1192 "Currently selected coordinate system. This is used to switch between coordinate systems "
1193 "in documents with multiple coordinate systems"));
1194 connect (m_cmbCoordSystem, SIGNAL (activated (int)), this, SLOT (slotCmbCoordSystem (int)));
1195
1196 m_btnShowAll = new QPushButton(QIcon(":/engauge/img/icon_show_all.png"), "");
1197 m_btnShowAll->setEnabled (false);
1198 m_btnShowAll->setAcceptDrops(false);
1199 m_btnShowAll->setStatusTip (tr ("Show all coordinate systems"));
1200 m_btnShowAll->setWhatsThis (tr ("Show All Coordinate Systems\n\n"
1201 "When pressed and held, this button shows all digitized points and lines for all coordinate systems."));
1202 connect (m_btnShowAll, SIGNAL (pressed ()), this, SLOT (slotBtnShowAllPressed ()));
1203 connect (m_btnShowAll, SIGNAL (released ()), this, SLOT (slotBtnShowAllReleased ()));
1204
1205 m_btnPrintAll = new QPushButton(QIcon(":/engauge/img/icon_print_all.png"), "");
1206 m_btnPrintAll->setEnabled (false);
1207 m_btnPrintAll->setAcceptDrops(false);
1208 m_btnPrintAll->setStatusTip (tr ("Print all coordinate systems"));
1209 m_btnPrintAll->setWhatsThis (tr ("Print All Coordinate Systems\n\n"
1210 "When pressed, this button Prints all digitized points and lines for all coordinate systems."));
1211 connect (m_btnPrintAll, SIGNAL (pressed ()), this, SLOT (slotBtnPrintAll ()));
1212
1213 m_toolCoordSystem = new QToolBar (tr ("Coordinate System"), this);
1214 m_toolCoordSystem->addWidget (m_cmbCoordSystem);
1215 m_toolCoordSystem->addWidget (m_btnShowAll);
1216 m_toolCoordSystem->addWidget (m_btnPrintAll);
1217 addToolBar (m_toolCoordSystem);
1218
1219 // Checklist guide starts out hidden. It will be positioned in settingsRead
1220 m_dockChecklistGuide = new ChecklistGuide (this);
1221 connect (m_dockChecklistGuide, SIGNAL (signalChecklistClosed()), this, SLOT (slotChecklistClosed()));
1222}
1223
1224void MainWindow::createTutorial ()
1225{
1226 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::createTutorial";
1227
1228 m_tutorialDlg = new TutorialDlg (this);
1229 m_tutorialDlg->setModal (true);
1230 m_tutorialDlg->setMinimumSize (500, 400);
1231 m_tutorialDlg->hide();
1232}
1233
1234ZoomFactor MainWindow::currentZoomFactor () const
1235{
1236 if (m_actionZoom1To1->isChecked()) {
1237 return ZOOM_1_TO_1;
1238 } else if (m_actionZoom1To2->isChecked()) {
1239 return ZOOM_1_TO_2;
1240 } else if (m_actionZoom1To4->isChecked()) {
1241 return ZOOM_1_TO_4;
1242 } else if (m_actionZoom1To8->isChecked()) {
1243 return ZOOM_1_TO_8;
1244 } else if (m_actionZoom1To16->isChecked()) {
1245 return ZOOM_1_TO_16;
1246 } else if (m_actionZoom2To1->isChecked()) {
1247 return ZOOM_2_TO_1;
1248 } else if (m_actionZoom4To1->isChecked()) {
1249 return ZOOM_4_TO_1;
1250 } else if (m_actionZoom8To1->isChecked()) {
1251 return ZOOM_8_TO_1;
1252 } else if (m_actionZoom16To1->isChecked()) {
1253 return ZOOM_16_TO_1;
1254 } else if (m_actionZoomFill->isChecked()) {
1255 return ZOOM_FILL;
1256 } else {
1257 ENGAUGE_ASSERT (false);
1258 return ZOOM_1_TO_1;
1259 }
1260}
1261bool MainWindow::eventFilter(QObject *target, QEvent *event)
1262{
1263 if (event->type () == QEvent::KeyPress) {
1264
1265 QKeyEvent *eventKeyPress = (QKeyEvent *) event;
1266
1267 // Special shortcuts. All of these are probably only useful for debugging and/or regression testing
1268 if ((eventKeyPress->key() == Qt::Key_E) &&
1269 ((eventKeyPress->modifiers() & Qt::ShiftModifier) != 0) &&
1270 ((eventKeyPress->modifiers() & Qt::ControlModifier) != 0)) {
1271
1272 saveErrorReportFileAndExit ("Shift+Control+E",
1273 __FILE__,
1274 __LINE__,
1275 "userTriggered");
1276
1277 }
1278 }
1279
1280 return QObject::eventFilter (target, event);
1281}
1282
1283void MainWindow::exportAllCoordinateSystems()
1284{
1285 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::exportAllCoordinateSystems";
1286
1287 ExportToFile exportStrategy;
1288
1289 // Output the regression test results. One file is output for every coordinate system
1290 for (CoordSystemIndex index = 0; index < m_cmdMediator->document().coordSystemCount(); index++) {
1291
1292 updateCoordSystem (index); // Switch to the specified coordinate system
1293
1294 QString regressionFile = QString ("%1_%2")
1295 .arg (m_regressionFile)
1296 .arg (index + 1); // Append the coordinate system index
1297 fileExport (regressionFile,
1298 exportStrategy);
1299 }
1300}
1301
1302QString MainWindow::exportFilenameFromInputFilename (const QString &fileName) const
1303{
1304 QString outFileName = fileName;
1305
1306 outFileName = outFileName.replace (".xml", ".csv_actual"); // Applies when extension is xml
1307 outFileName = outFileName.replace (".dig", ".csv_actual"); // Applies when extension is dig
1308
1309 return outFileName;
1310}
1311
1312void MainWindow::fileExport(const QString &fileName,
1313 ExportToFile exportStrategy)
1314{
1315 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::fileExport"
1316 << " fileName=" << fileName.toLatin1().data();
1317
1318 QFile file (fileName);
1319 if (file.open(QIODevice::WriteOnly)) {
1320
1321 QTextStream str (&file);
1322
1323 DocumentModelExportFormat modelExportFormat = modelExportOverride (m_cmdMediator->document().modelExport(),
1324 exportStrategy,
1325 fileName);
1326 exportStrategy.exportToFile (modelExportFormat,
1327 m_cmdMediator->document(),
1328 m_modelMainWindow,
1329 transformation (),
1330 str);
1331
1332 // Update checklist guide status
1333 m_isDocumentExported = true; // Set for next line and for all checklist guide updates after this
1334 m_dockChecklistGuide->update (*m_cmdMediator,
1335 m_isDocumentExported);
1336
1337 } else {
1338
1339 QMessageBox::critical (0,
1340 engaugeWindowTitle(),
1341 tr ("Unable to export to file ") + fileName);
1342 }
1343}
1344
1345void MainWindow::fileImport (const QString &fileName,
1346 ImportType importType)
1347{
1348 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::fileImport"
1349 << " fileName=" << fileName.toLatin1 ().data ()
1350 << " curDir=" << QDir::currentPath().toLatin1().data()
1351 << " importType=" << importType;
1352
1353 QString originalFileOld = m_originalFile;
1354 bool originalFileWasImported = m_originalFileWasImported;
1355
1356 m_originalFile = fileName; // Make this available for logging in case an error occurs during the load
1357 m_originalFileWasImported = true;
1358
1359 if (importType == IMPORT_TYPE_ADVANCED) {
1360
1361 // Remove any existing points, axes checker(s) and such from the previous Document so they do not appear in setupAfterLoad
1362 // when previewing for IMAGE_TYPE_ADVANCED
1363 slotFileClose();
1364
1365 // Restore the background just closed by slotFileClose. This is required so when the image is loaded for preview, it will appear
1366 m_backgroundStateContext->setBackgroundImage(BACKGROUND_IMAGE_ORIGINAL);
1367 }
1368
1369 QImage image;
1370 bool loaded = false;
1371#ifdef ENGAUGE_JPEG2000
1372 Jpeg2000 jpeg2000;
1373 loaded = jpeg2000.load (fileName,
1374 image);
1375#endif // ENGAUGE_JPEG2000
1376 if (!loaded) {
1377 loaded = image.load (fileName);
1378 }
1379
1380 if (!loaded) {
1381 QMessageBox::warning (this,
1382 engaugeWindowTitle(),
1383 QString("%1 %2.")
1384 .arg (tr ("Cannot read file"))
1385 .arg(fileName));
1386
1387 // Reset
1388 m_originalFile = originalFileOld;
1389 m_originalFileWasImported = originalFileWasImported;
1390
1391 } else {
1392
1393 loaded = loadImage (fileName,
1394 image,
1395 importType);
1396
1397 if (!loaded) {
1398
1399 // Failed
1400 if (importType == IMPORT_TYPE_ADVANCED) {
1401
1402 // User cancelled after another file was imported so it could be previewed. In anticipation of the loading-for-preview,
1403 // we closed the current Document at the top of this method so we cannot reload. So, the only option is to close again
1404 // so the half-imported current Document is removed
1405 slotFileClose();
1406
1407 } else {
1408
1409 // Reset
1410 m_originalFile = originalFileOld;
1411 m_originalFileWasImported = originalFileWasImported;
1412 }
1413 }
1414 }
1415}
1416
1417void MainWindow::fileImportWithPrompts (ImportType importType)
1418{
1419 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::fileImportWithPrompts"
1420 << " importType=" << importType;
1421
1422 if (maybeSave ()) {
1423
1424 QString filter;
1425 QTextStream str (&filter);
1426
1427 // Compile a list of supported formats into a filter
1428 QList<QByteArray>::const_iterator itr;
1429 QList<QByteArray> supportedImageFormats = QImageReader::supportedImageFormats();
1430 QStringList supportedImageFormatStrings;
1431 for (itr = supportedImageFormats.begin (); itr != supportedImageFormats.end (); itr++) {
1432 QByteArray arr = *itr;
1433 QString extensionAsWildcard = QString ("*.%1").arg (QString (arr));
1434 supportedImageFormatStrings << extensionAsWildcard;
1435 }
1436#ifdef ENGAUGE_JPEG2000
1437 Jpeg2000 jpeg2000;
1438 supportedImageFormatStrings << jpeg2000.supportedImageWildcards();
1439#endif // ENGAUGE_JPEG2000
1440
1441 supportedImageFormatStrings.sort();
1442
1443 str << "Image Files (" << supportedImageFormatStrings.join (" ") << ")";
1444
1445 // Allow selection of files with strange suffixes in case the file extension was changed. Since
1446 // the default is the first filter, we add this afterwards (it is the off-nominal case)
1447 str << ";; All Files (*.*)";
1448
1449 QString fileName = QFileDialog::getOpenFileName (this,
1450 tr("Import Image"),
1451 QDir::currentPath (),
1452 filter);
1453 if (!fileName.isEmpty ()) {
1454
1455 // We import the file BEFORE asking the number of coordinate systems, so user can see how many there are
1456 fileImport (fileName,
1457 importType);
1458 }
1459 }
1460}
1461
1462void MainWindow::filePaste (ImportType importType)
1463{
1464 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::filePaste"
1465 << " importType=" << importType;
1466
1467 QString originalFileOld = m_originalFile;
1468 bool originalFileWasImported = m_originalFileWasImported;
1469
1470 QString fileName ("clipboard");
1471 m_originalFile = fileName; // Make this available for logging in case an error occurs during the load
1472 m_originalFileWasImported = true;
1473
1474 if (importType == IMPORT_TYPE_ADVANCED) {
1475
1476 // Remove any existing points, axes checker(s) and such from the previous Document so they do not appear in setupAfterLoad
1477 // when previewing for IMAGE_TYPE_ADVANCED
1478 slotFileClose();
1479
1480 // Restore the background just closed by slotFileClose. This is required so when the image is loaded for preview, it will appear
1481 m_backgroundStateContext->setBackgroundImage(BACKGROUND_IMAGE_ORIGINAL);
1482 }
1483
1484 // An image was in the clipboard when this method was called but it may have disappeared
1485 QImage image = QApplication::clipboard()->image();
1486
1487 bool loaded = false;
1488 if (!loaded) {
1489 loaded = !image.isNull();
1490 }
1491
1492 if (!loaded) {
1493 QMessageBox::warning (this,
1494 engaugeWindowTitle(),
1495 QString("%1 %2.")
1496 .arg (tr ("Cannot read file"))
1497 .arg(fileName));
1498
1499 // Reset
1500 m_originalFile = originalFileOld;
1501 m_originalFileWasImported = originalFileWasImported;
1502
1503 } else {
1504
1505 loaded = loadImage (fileName,
1506 image,
1507 importType);
1508
1509 if (!loaded) {
1510
1511 // Failed
1512 if (importType == IMPORT_TYPE_ADVANCED) {
1513
1514 // User cancelled after another file was imported so it could be previewed. In anticipation of the loading-for-preview,
1515 // we closed the current Document at the top of this method so we cannot reload. So, the only option is to close again
1516 // so the half-imported current Document is removed
1517 slotFileClose();
1518
1519 } else {
1520
1521 // Reset
1522 m_originalFile = originalFileOld;
1523 m_originalFileWasImported = originalFileWasImported;
1524 }
1525 }
1526 }
1527}
1528
1529void MainWindow::ghostsCreate ()
1530{
1531 LOG4CPP_DEBUG_S ((*mainCat)) << "MainWindow::ghostsCreate";
1532
1533 ENGAUGE_ASSERT (m_ghosts == 0);
1534 m_ghosts = new Ghosts (m_cmdMediator->document().coordSystemIndex());
1535
1536 for (unsigned int index = 0; index < m_cmdMediator->document().coordSystemCount(); index++) {
1537
1538 // Skip this coordinate system if it is the selected coordinate system since it will be displayed anyway, so no ghosts are required
1539 if (index != m_ghosts->coordSystemIndexToBeRestored ()) {
1540
1541 updateCoordSystem (index);
1542
1543 // Take a snapshot of the graphics items
1544 m_ghosts->captureGraphicsItems (*m_scene);
1545 }
1546 }
1547
1548 // Restore the coordinate system that was originally selected, so its points/lines are visible
1550
1551 // Make visible ghosts
1552 m_ghosts->createGhosts (*m_scene);
1553}
1554
1555void MainWindow::ghostsDestroy ()
1556{
1557 LOG4CPP_DEBUG_S ((*mainCat)) << "MainWindow::ghostsDestroy";
1558
1559 ENGAUGE_CHECK_PTR (m_ghosts);
1560
1561 m_ghosts->destroyGhosts(*m_scene);
1562
1563 delete m_ghosts;
1564 m_ghosts = 0;
1565}
1566
1568{
1569 return m_backgroundStateContext->imageForCurveState();
1570}
1571
1573{
1574 return m_isGnuplot;
1575}
1576
1577void MainWindow::loadCoordSystemListFromCmdMediator ()
1578{
1579 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::loadCoordSystemListFromCmdMediator";
1580
1581 m_cmbCoordSystem->clear();
1582
1583 unsigned int numberCoordSystem = m_cmdMediator->document().coordSystemCount();
1584
1585 for (unsigned int i = 0; i < numberCoordSystem; i++) {
1586 int index1Based = i + 1;
1587 m_cmbCoordSystem->addItem (QString::number (index1Based),
1588 QVariant (i));
1589 }
1590
1591 // Always start with the first entry selected
1592 m_cmbCoordSystem->setCurrentIndex (0);
1593
1594 // Disable the controls if there is only one entry. Hopefully the user will not even notice it, thus simplifying the interface
1595 bool enable = (m_cmbCoordSystem->count() > 1);
1596 m_cmbCoordSystem->setEnabled (enable);
1597 m_btnShowAll->setEnabled (enable);
1598 m_btnPrintAll->setEnabled (enable);
1599}
1600
1601void MainWindow::loadCurveListFromCmdMediator ()
1602{
1603 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::loadCurveListFromCmdMediator";
1604
1605 m_cmbCurve->clear ();
1606 QStringList curvesGraphsNames = m_cmdMediator->curvesGraphsNames ();
1607 QStringList::iterator itr;
1608 for (itr = curvesGraphsNames.begin (); itr != curvesGraphsNames.end (); itr++) {
1609
1610 QString curvesGraphName = *itr;
1611 m_cmbCurve->addItem (curvesGraphName);
1612 }
1613
1614 // Arbitrarily pick the first curve
1615 m_cmbCurve->setCurrentIndex (0);
1616}
1617
1618void MainWindow::loadDocumentFile (const QString &fileName)
1619{
1620 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::loadDocumentFile fileName=" << fileName.toLatin1 ().data ();
1621
1622 QApplication::setOverrideCursor(Qt::WaitCursor);
1623 CmdMediator *cmdMediator = new CmdMediator (*this,
1624 fileName);
1625 QApplication::restoreOverrideCursor();
1626
1627 if (cmdMediator->successfulRead ()) {
1628
1629 setCurrentPathFromFile (fileName);
1630 rebuildRecentFileListForCurrentFile(fileName);
1631 m_currentFile = fileName; // This enables the FileSaveAs menu option
1632
1633 if (m_cmdMediator != 0) {
1634 delete m_cmdMediator;
1635 m_cmdMediator = 0;
1636 }
1637
1638 m_cmdMediator = cmdMediator;
1639 setupAfterLoad(fileName,
1640 "File opened",
1641 IMPORT_TYPE_SIMPLE);
1642
1643 // Start select mode
1644 m_actionDigitizeSelect->setChecked (true); // We assume user wants to first select existing stuff
1645 slotDigitizeSelect(); // Trigger transition so cursor gets updated immediately
1646
1647 m_engaugeFile = fileName;
1648 m_originalFile = fileName; // This is needed by updateAfterCommand below if an error report is generated
1649 m_originalFileWasImported = false;
1650
1651 updateAfterCommand (); // Enable Save button now that m_engaugeFile is set
1652
1653 } else {
1654
1655 QMessageBox::warning (this,
1656 engaugeWindowTitle(),
1657 QString("%1 %2:\n%3.")
1658 .arg (tr ("Cannot read file"))
1659 .arg(fileName)
1661 delete cmdMediator;
1662
1663 }
1664}
1665
1666void MainWindow::loadErrorReportFile(const QString &initialPath,
1667 const QString &errorReportFile)
1668{
1669 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::loadErrorReportFile"
1670 << " path=" << initialPath.toLatin1().data()
1671 << " file=" << errorReportFile.toLatin1().data();
1672
1673 // The default path has been changed from its original executable-based initial value to the last directory used
1674 // according to the settings. Since the executable-based directory is much more stable, and we want a predictable
1675 // directory in the likely event that the error report file has a relative path, we temporarily switch the default path
1676 // back to the executable-based initial value
1677 QString originalPath = QDir::currentPath();
1678 QDir::setCurrent(initialPath);
1679
1680 QFile file (errorReportFile);
1681 if (!file.exists()) {
1682 // Convert path from relative to absolute so file-not-found errors are easier to fix
1683 QFileInfo fileInfo (errorReportFile);
1684
1685 QMessageBox::critical (this,
1686 engaugeWindowTitle(),
1687 tr ("File not found:") + " " + fileInfo.absoluteFilePath());
1688 exit (-1);
1689 }
1690
1691 // Open the error report file as if it was a regular Document file
1692 QXmlStreamReader reader (&file);
1693 file.open(QIODevice::ReadOnly | QIODevice::Text);
1694 m_cmdMediator = new CmdMediator(*this,
1695 errorReportFile);
1696
1697 // Load the commands into the shadow command stack
1698 m_cmdStackShadow->loadCommands (*this,
1699 m_cmdMediator->document(),
1700 reader);
1701 file.close();
1702
1703 // Reset the original path now that the error report file has been read in
1704 QDir::setCurrent(originalPath);
1705
1706 setupAfterLoad(errorReportFile,
1707 "Error report opened",
1708 IMPORT_TYPE_SIMPLE);
1709
1710 // Start select mode
1711 m_actionDigitizeSelect->setChecked (true); // We assume user wants to first select existing stuff
1712 slotDigitizeSelect(); // Trigger transition so cursor gets updated immediately
1713
1715}
1716
1717bool MainWindow::loadImage (const QString &fileName,
1718 const QImage &image,
1719 ImportType importType)
1720{
1721 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::loadImage"
1722 << " fileName=" << fileName.toLatin1 ().data ()
1723 << " importType=" << importType;
1724
1725 QApplication::setOverrideCursor(Qt::WaitCursor);
1726 CmdMediator *cmdMediator = new CmdMediator (*this,
1727 image);
1728 QApplication::restoreOverrideCursor();
1729
1730 setCurrentPathFromFile (fileName);
1731 // We do not call rebuildRecentFileListForCurrentFile for an image file, so only proper Engauge document files appear in the recent file list
1732 m_engaugeFile = EMPTY_FILENAME; // Forces first Save to be treated as Save As
1733
1734 if (m_cmdMediator != 0) {
1735 delete m_cmdMediator;
1736 m_cmdMediator = 0;
1737 }
1738
1739 m_cmdMediator = cmdMediator;
1740 bool accepted = setupAfterLoad(fileName,
1741 tr ("File imported"),
1742 importType);
1743
1744 if (accepted) {
1745
1746 // Show the wizard if user selected it and we are not running a script
1747 if (m_actionHelpChecklistGuideWizard->isChecked () &&
1748 (m_fileCmdScript == 0)) {
1749
1750 // Show wizard
1751 ChecklistGuideWizard *wizard = new ChecklistGuideWizard (*this,
1752 m_cmdMediator->document().coordSystemCount());
1753 if (wizard->exec() == QDialog::Accepted) {
1754
1755 for (CoordSystemIndex coordSystemIndex = 0; coordSystemIndex < m_cmdMediator->document().coordSystemCount(); coordSystemIndex++) {
1756
1757 // Populate the checklist guide
1758 m_dockChecklistGuide->setTemplateHtml (wizard->templateHtml(coordSystemIndex),
1759 wizard->curveNames(coordSystemIndex));
1760
1761 // Update Document
1762 CurvesGraphs curvesGraphs;
1763 wizard->populateCurvesGraphs (coordSystemIndex,
1764 curvesGraphs);
1765 m_cmdMediator->document().setCurvesGraphs(coordSystemIndex,
1766 curvesGraphs);
1767 }
1768
1769 // Unhide the checklist guide
1770 m_actionViewChecklistGuide->setChecked (true);
1771
1772 // Update the curve dropdown
1773 loadCurveListFromCmdMediator();
1774
1775 // Update the CoordSystem dropdown
1776 loadCoordSystemListFromCmdMediator();
1777 }
1778 delete wizard;
1779 }
1780
1781 // Start axis mode
1782 m_actionDigitizeAxis->setChecked (true); // We assume user first wants to digitize axis points
1783 slotDigitizeAxis (); // Trigger transition so cursor gets updated immediately
1784
1785 updateControls ();
1786 }
1787
1788 return accepted;
1789}
1790
1791void MainWindow::loadInputFileForErrorReport(QDomDocument &domInputFile) const
1792{
1793 QFile file (m_originalFile);
1794
1795 // File should be available for opening, if not then the dom will be left empty. We assume it has not been
1796 // modified since opened
1797 if (!file.open (QIODevice::ReadOnly)) {
1798 return;
1799 }
1800
1801 domInputFile.setContent (&file);
1802 file.close();
1803}
1804
1805void MainWindow::loadToolTips()
1806{
1807 if (m_actionViewToolTips->isChecked ()) {
1808
1809 // Show tool tips
1810 m_actionDigitizeSelect->setToolTip (DIGITIZE_ACTION_SELECT);
1811 m_actionDigitizeAxis->setToolTip (DIGITIZE_ACTION_AXIS_POINT);
1812 m_actionDigitizeCurve->setToolTip (DIGITIZE_ACTION_CURVE_POINT);
1813 m_actionDigitizePointMatch->setToolTip (DIGITIZE_ACTION_POINT_MATCH);
1814 m_actionDigitizeColorPicker->setToolTip (DIGITIZE_ACTION_COLOR_PICKER);
1815 m_actionDigitizeSegment->setToolTip (DIGITIZE_ACTION_SEGMENT_POINTS);
1816 m_cmbBackground->setToolTip (tr ("Background image."));
1817 m_cmbCurve->setToolTip (tr ("Currently selected curve."));
1818 m_viewPointStyle->setToolTip (tr ("Point style for currently selected curve."));
1819 m_viewSegmentFilter->setToolTip (tr ("Segment Fill filter for currently selected curve."));
1820
1821 } else {
1822
1823 // Remove any previous tool tips
1824 m_actionDigitizeSelect->setToolTip ("");
1825 m_actionDigitizeAxis->setToolTip ("");
1826 m_actionDigitizeCurve->setToolTip ("");
1827 m_actionDigitizePointMatch->setToolTip ("");
1828 m_actionDigitizeColorPicker->setToolTip ("");
1829 m_actionDigitizeSegment->setToolTip ("");
1830 m_cmbBackground->setToolTip ("");
1831 m_cmbCurve->setToolTip ("");
1832 m_viewPointStyle->setToolTip ("");
1833 m_viewSegmentFilter->setToolTip ("");
1834
1835 }
1836}
1837
1838bool MainWindow::maybeSave()
1839{
1840 if (m_cmdMediator != 0) {
1841 if (m_cmdMediator->isModified()) {
1842 QMessageBox::StandardButton ret = QMessageBox::warning (this,
1843 engaugeWindowTitle(),
1844 tr("The document has been modified.\n"
1845 "Do you want to save your changes?"),
1846 QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
1847 if (ret == QMessageBox::Save) {
1848 return slotFileSave();
1849 } else if (ret == QMessageBox::Cancel) {
1850 return false;
1851 }
1852 }
1853 }
1854
1855 return true;
1856}
1857
1858DocumentModelExportFormat MainWindow::modelExportOverride (const DocumentModelExportFormat &modelExportFormatBefore,
1859 const ExportToFile &exportStrategy,
1860 const QString &fileName) const
1861{
1862 DocumentModelExportFormat modelExportFormatAfter = modelExportFormatBefore;
1863
1864 // Extract file extensions
1865 QString csvExtension = QString (".%1")
1866 .arg (exportStrategy.fileExtensionCsv());
1867 QString tsvExtension = QString (".%1")
1868 .arg (exportStrategy.fileExtensionTsv());
1869 QString fileExtensionVersusCsv = fileName.right (csvExtension.size());
1870 QString fileExtensionVersusTsv = fileName.right (tsvExtension.size());
1871
1872 // Override if CSV or TSV was selected. We cannot use QFileDialog::selecedNameFilter() since that is
1873 // broken in Linux, so we use the file extension
1874 if (csvExtension.compare (fileExtensionVersusCsv, Qt::CaseInsensitive) == 0) {
1875 modelExportFormatAfter.setDelimiter (EXPORT_DELIMITER_COMMA);
1876 } else if (tsvExtension.compare (fileExtensionVersusTsv, Qt::CaseInsensitive) == 0) {
1877 modelExportFormatAfter.setDelimiter (EXPORT_DELIMITER_TAB);
1878 }
1879
1880 return modelExportFormatAfter;
1881}
1882
1884{
1885 return m_modelMainWindow;
1886}
1887
1888void MainWindow::rebuildRecentFileListForCurrentFile(const QString &filePath)
1889{
1890 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::rebuildRecentFileListForCurrentFile";
1891
1892 setWindowFilePath (filePath);
1893
1894 QSettings settings (SETTINGS_ENGAUGE, SETTINGS_DIGITIZER);
1895 QStringList recentFilePaths = settings.value (SETTINGS_RECENT_FILE_LIST).toStringList();
1896 recentFilePaths.removeAll (filePath); // Remove previous instance of the current filePath
1897 recentFilePaths.prepend (filePath); // Insert current filePath at start
1898 while (recentFilePaths.count () > (int) MAX_RECENT_FILE_LIST_SIZE) {
1899 recentFilePaths.removeLast (); // Remove entry since the number of entries exceeds the limit
1900 }
1901 settings.setValue (SETTINGS_RECENT_FILE_LIST, recentFilePaths);
1902
1903 updateRecentFileList();
1904}
1905
1906void MainWindow::resizeEvent(QResizeEvent * /* event */)
1907{
1908 LOG4CPP_DEBUG_S ((*mainCat)) << "MainWindow::resizeEvent";
1909
1910 if (m_actionZoomFill->isChecked ()) {
1911 slotViewZoomFill();
1912 }
1913}
1914
1915bool MainWindow::saveDocumentFile (const QString &fileName)
1916{
1917 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::saveDocumentFile fileName=" << fileName.toLatin1 ().data ();
1918
1919 QFile file(fileName);
1920 if (!file.open(QFile::WriteOnly)) {
1921 QMessageBox::warning (this,
1922 engaugeWindowTitle(),
1923 QString ("%1 %2: \n%3.")
1924 .arg(tr ("Cannot write file"))
1925 .arg(fileName)
1926 .arg(file.errorString()));
1927 return false;
1928 }
1929
1930 rebuildRecentFileListForCurrentFile (fileName);
1931
1932 QApplication::setOverrideCursor (Qt::WaitCursor);
1933 QXmlStreamWriter writer(&file);
1934 writer.setAutoFormatting(true);
1935 writer.writeStartDocument();
1936 writer.writeDTD("<!DOCTYPE engauge>");
1937 m_cmdMediator->document().saveXml(writer);
1938 writer.writeEndDocument();
1939 QApplication::restoreOverrideCursor ();
1940
1941 // Notify the undo stack that the current state is now considered "clean". This will automatically trigger a
1942 // signal back to this class that will update the modified marker in the title bar
1943 m_cmdMediator->setClean ();
1944
1945 setCurrentFile(fileName);
1946 m_engaugeFile = fileName;
1947 updateAfterCommand (); // Enable Save button now that m_engaugeFile is set
1948 m_statusBar->showTemporaryMessage("File saved");
1949
1950 return true;
1951}
1952
1954 const char *file,
1955 int line,
1956 const char *comment) const
1957{
1958 if (m_cmdMediator != 0) {
1959
1960 QString report = saveErrorReportFileAndExitXml (context,
1961 file,
1962 line,
1963 comment);
1964 DlgErrorReport dlg (report);
1965
1966 // Ask user if report should be uploaded, and if the document is included when it is uploaded
1967 if (dlg.exec() == QDialog::Accepted) {
1968
1969 // Upload the error report to the server
1970 m_networkClient->uploadErrorReport (dlg.xmlToUpload());
1971 }
1972 }
1973}
1974
1975QString MainWindow::saveErrorReportFileAndExitXml (const char *context,
1976 const char *file,
1977 int line,
1978 const char *comment) const
1979{
1980 const bool DEEP_COPY = true;
1981
1982 QString xmlErrorReport;
1983 QXmlStreamWriter writer (&xmlErrorReport);
1984 writer.setAutoFormatting(true);
1985
1986 // Entire error report contains metadata, commands and other details
1987 writer.writeStartElement(DOCUMENT_SERIALIZE_ERROR_REPORT);
1988
1989 // Version
1990 writer.writeStartElement(DOCUMENT_SERIALIZE_APPLICATION);
1991 writer.writeAttribute(DOCUMENT_SERIALIZE_APPLICATION_VERSION_NUMBER, VERSION_NUMBER);
1992 writer.writeEndElement();
1993
1994 // Document
1995 // Insert snapshot xml into writer stream, by reading from reader stream. Highest level of snapshot is DOCUMENT_SERIALIZE_APPLICATION
1996 QXmlStreamReader reader (m_startingDocumentSnapshot);
1997 while (!reader.atEnd ()) {
1998 reader.readNext ();
1999 if (reader.tokenType() != QXmlStreamReader::StartDocument &&
2000 reader.tokenType() != QXmlStreamReader::EndDocument) {
2001 writer.writeCurrentToken (reader);
2002 }
2003 }
2004
2005 // Operating system
2006 writer.writeStartElement(DOCUMENT_SERIALIZE_OPERATING_SYSTEM);
2007 writer.writeAttribute(DOCUMENT_SERIALIZE_OPERATING_SYSTEM_ENDIAN, EndianToString (QSysInfo::ByteOrder));
2008 writer.writeAttribute(DOCUMENT_SERIALIZE_OPERATING_SYSTEM_WORD_SIZE, QString::number (QSysInfo::WordSize));
2009 writer.writeEndElement();
2010
2011 // Placeholder for original file, before the commands in the command stack were applied
2012 writer.writeStartElement(DOCUMENT_SERIALIZE_FILE);
2013 writer.writeAttribute(DOCUMENT_SERIALIZE_FILE_IMPORTED,
2014 m_originalFileWasImported ? DOCUMENT_SERIALIZE_BOOL_TRUE : DOCUMENT_SERIALIZE_BOOL_FALSE);
2015 writer.writeEndElement();
2016
2017 // Commands
2018 m_cmdMediator->saveXml(writer);
2019
2020 // Error
2021 writer.writeStartElement(DOCUMENT_SERIALIZE_ERROR);
2022 writer.writeAttribute(DOCUMENT_SERIALIZE_ERROR_CONTEXT, context);
2023 writer.writeAttribute(DOCUMENT_SERIALIZE_ERROR_FILE, file);
2024 writer.writeAttribute(DOCUMENT_SERIALIZE_ERROR_LINE, QString::number (line));
2025 writer.writeAttribute(DOCUMENT_SERIALIZE_ERROR_COMMENT, comment);
2026 writer.writeEndElement();
2027
2028 writer.writeEndElement();
2029
2030 // Put string into DOM
2031 QDomDocument domErrorReport ("ErrorReport");
2032 domErrorReport.setContent (xmlErrorReport);
2033
2034 // Postprocessing
2035 if (!m_originalFileWasImported) {
2036
2037 // Insert the original file into its placeholder, by manipulating the source and target xml as DOM documents. Very early
2038 // in the loading process, the original file may not be specified yet (m_originalFile is empty)
2039 QDomDocument domInputFile;
2040 loadInputFileForErrorReport (domInputFile);
2041 QDomDocumentFragment fragmentFileFrom = domErrorReport.createDocumentFragment();
2042 if (!domInputFile.isNull()) {
2043 fragmentFileFrom.appendChild (domErrorReport.importNode (domInputFile.documentElement(), DEEP_COPY));
2044 }
2045 QDomNodeList nodesFileTo = domErrorReport.elementsByTagName (DOCUMENT_SERIALIZE_FILE);
2046 if (nodesFileTo.count () > 0) {
2047 QDomNode nodeFileTo = nodesFileTo.at (0);
2048 nodeFileTo.appendChild (fragmentFileFrom);
2049 }
2050
2051 // Replace DOCUMENT_SERIALIZE_IMAGE by same node with CDATA removed, since:
2052 // 1) it is very big and working with smaller files, especially in emails, is easier
2053 // 2) removing the image better preserves user's privacy
2054 // 3) having the actual image does not help that much when debugging
2055 QDomNodeList nodesDocument = domErrorReport.elementsByTagName (DOCUMENT_SERIALIZE_DOCUMENT);
2056 for (int i = 0 ; i < nodesDocument.count(); i++) {
2057 QDomNode nodeDocument = nodesDocument.at (i);
2058 QDomElement elemImage = nodeDocument.firstChildElement(DOCUMENT_SERIALIZE_IMAGE);
2059 if (!elemImage.isNull()) {
2060
2061 // Get old image attributes so we can create an empty document with the same size
2062 if (elemImage.hasAttribute (DOCUMENT_SERIALIZE_IMAGE_WIDTH) &&
2063 elemImage.hasAttribute (DOCUMENT_SERIALIZE_IMAGE_HEIGHT)) {
2064
2065 int width = elemImage.attribute(DOCUMENT_SERIALIZE_IMAGE_WIDTH).toInt();
2066 int height = elemImage.attribute(DOCUMENT_SERIALIZE_IMAGE_HEIGHT).toInt();
2067
2068 QDomNode nodeReplacement;
2069 QDomElement elemReplacement = nodeReplacement.toElement();
2070 elemReplacement.setAttribute (DOCUMENT_SERIALIZE_IMAGE_WIDTH, width);
2071 elemReplacement.setAttribute (DOCUMENT_SERIALIZE_IMAGE_HEIGHT, height);
2072
2073 // Replace with the new and then remove the old
2074 nodeDocument.insertBefore (nodeReplacement,
2075 elemImage);
2076 nodeDocument.removeChild(elemImage);
2077 }
2078 }
2079 }
2080 }
2081
2082 return domErrorReport.toString();
2083}
2084
2085void MainWindow::saveStartingDocumentSnapshot()
2086{
2087 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::saveStartingDocumentSnapshot";
2088
2089 QXmlStreamWriter writer (&m_startingDocumentSnapshot);
2090 writer.setAutoFormatting (true);
2091 m_cmdMediator->document().saveXml (writer);
2092}
2093
2095{
2096 ENGAUGE_CHECK_PTR (m_scene);
2097 return *m_scene;
2098}
2099
2100BackgroundImage MainWindow::selectOriginal(BackgroundImage backgroundImage)
2101{
2102 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::selectBackgroundOriginal";
2103
2104 BackgroundImage previousBackground = (BackgroundImage) m_cmbBackground->currentData().toInt();
2105
2106 int index = m_cmbBackground->findData (backgroundImage);
2107 ENGAUGE_ASSERT (index >= 0);
2108
2109 m_cmbBackground->setCurrentIndex(index);
2110
2111 return previousBackground;
2112}
2113
2115{
2116 return m_cmbCurve->currentText ();
2117}
2118
2119void MainWindow::setCurrentFile (const QString &fileName)
2120{
2121 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::setCurrentFile";
2122
2123 QString fileNameStripped;
2124 if (!fileName.isEmpty()) {
2125
2126 // Strip out path and file extension
2127 QFileInfo fileInfo (fileName);
2128 fileNameStripped = fileInfo.baseName();
2129 }
2130
2131 m_currentFile = fileNameStripped;
2132 m_currentFileWithPathAndFileExtension = fileName;
2133
2134 updateWindowTitle ();
2135}
2136
2137void MainWindow::setCurrentPathFromFile (const QString &fileName)
2138{
2139 QDir dir = QFileInfo (fileName).absoluteDir();
2140
2141 if (dir.exists ()) {
2142
2143 bool success = QDir::setCurrent (dir.absolutePath ()); // Return to chosen directory the next time
2144 ENGAUGE_ASSERT (success);
2145
2146 } else {
2147
2148 // File was a url so it is irrelevant to the current directory
2149 }
2150}
2151
2152void MainWindow::setPixmap (const QPixmap &pixmap)
2153{
2154 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::setPixmap";
2155
2156 m_digitizeStateContext->setImageIsLoaded (m_cmdMediator,
2157 true);
2158 m_backgroundStateContext->setPixmap (m_transformation,
2159 m_cmdMediator->document().modelGridRemoval(),
2160 m_cmdMediator->document().modelColorFilter(),
2161 pixmap);
2162}
2163
2164void MainWindow::settingsRead ()
2165{
2166 QSettings settings (SETTINGS_ENGAUGE, SETTINGS_DIGITIZER);
2167
2168 settingsReadEnvironment (settings);
2169 settingsReadMainWindow (settings);
2170}
2171
2172void MainWindow::settingsReadEnvironment (QSettings &settings)
2173{
2174 settings.beginGroup (SETTINGS_GROUP_ENVIRONMENT);
2175 QDir::setCurrent (settings.value (SETTINGS_CURRENT_DIRECTORY,
2176 QDir::currentPath ()).toString ());
2177 settings.endGroup ();
2178}
2179
2180void MainWindow::settingsReadMainWindow (QSettings &settings)
2181{
2182 settings.beginGroup(SETTINGS_GROUP_MAIN_WINDOW);
2183
2184 // Main window geometry
2185 resize (settings.value (SETTINGS_SIZE,
2186 QSize (400, 400)).toSize ());
2187 move (settings.value (SETTINGS_POS,
2188 QPoint (200, 200)).toPoint ());
2189
2190 // Help window geometry
2191 QSize helpSize = settings.value (SETTINGS_HELP_SIZE,
2192 QSize (900, 600)).toSize();
2193 m_helpWindow->resize (helpSize);
2194 if (settings.contains (SETTINGS_HELP_POS)) {
2195 QPoint helpPos = settings.value (SETTINGS_HELP_POS).toPoint();
2196 m_helpWindow->move (helpPos);
2197 }
2198
2199 // Checklist guide wizard
2200 m_actionHelpChecklistGuideWizard->setChecked (settings.value (SETTINGS_CHECKLIST_GUIDE_WIZARD,
2201 true).toBool ());
2202
2203 // Background toolbar visibility
2204 bool viewBackgroundToolBar = settings.value (SETTINGS_VIEW_BACKGROUND_TOOLBAR,
2205 true).toBool ();
2206 m_actionViewBackground->setChecked (viewBackgroundToolBar);
2207 m_toolBackground->setVisible (viewBackgroundToolBar);
2208 BackgroundImage backgroundImage = (BackgroundImage) settings.value (SETTINGS_BACKGROUND_IMAGE,
2209 BACKGROUND_IMAGE_FILTERED).toInt ();
2210 int indexBackground = m_cmbBackground->findData (QVariant (backgroundImage));
2211 m_cmbBackground->setCurrentIndex (indexBackground);
2212
2213 // Digitize toolbar visibility
2214 bool viewDigitizeToolBar = settings.value (SETTINGS_VIEW_DIGITIZE_TOOLBAR,
2215 true).toBool ();
2216 m_actionViewDigitize->setChecked (viewDigitizeToolBar);
2217 m_toolDigitize->setVisible (viewDigitizeToolBar);
2218
2219 // Views toolbar visibility
2220 bool viewSettingsViewsToolBar = settings.value (SETTINGS_VIEW_SETTINGS_VIEWS_TOOLBAR,
2221 true).toBool ();
2222 m_actionViewSettingsViews->setChecked (viewSettingsViewsToolBar);
2223 m_toolSettingsViews->setVisible (viewSettingsViewsToolBar);
2224
2225 // Coordinate system toolbar visibility
2226 bool viewCoordSystemToolbar = settings.value (SETTINGS_VIEW_COORD_SYSTEM_TOOLBAR,
2227 false).toBool ();
2228 m_actionViewCoordSystem->setChecked (viewCoordSystemToolbar);
2229 m_toolCoordSystem->setVisible (viewCoordSystemToolbar);
2230
2231 // Tooltips visibility
2232 bool viewToolTips = settings.value (SETTINGS_VIEW_TOOL_TIPS,
2233 true).toBool ();
2234 m_actionViewToolTips->setChecked (viewToolTips);
2235 loadToolTips ();
2236
2237 // Statusbar visibility
2238 StatusBarMode statusBarMode = (StatusBarMode) settings.value (SETTINGS_VIEW_STATUS_BAR,
2239 false).toInt ();
2240 m_statusBar->setStatusBarMode (statusBarMode);
2241 m_actionStatusNever->setChecked (statusBarMode == STATUS_BAR_MODE_NEVER);
2242 m_actionStatusTemporary->setChecked (statusBarMode == STATUS_BAR_MODE_TEMPORARY);
2243 m_actionStatusAlways->setChecked (statusBarMode == STATUS_BAR_MODE_ALWAYS);
2244
2245 // Checklist guide is docked or undocked. Default is undocked so user knows it can be undocked
2246 Qt::DockWidgetArea area = (Qt::DockWidgetArea) settings.value (SETTINGS_CHECKLIST_GUIDE_DOCK_AREA,
2247 Qt::NoDockWidgetArea).toInt();
2248
2249 if (area == Qt::NoDockWidgetArea) {
2250
2251 addDockWidget (Qt::RightDockWidgetArea,
2252 m_dockChecklistGuide); // Add on the right to prevent error message, then immediately make undocked
2253 m_dockChecklistGuide->setFloating(true); // Undock
2254 if (settings.contains (SETTINGS_CHECKLIST_GUIDE_DOCK_GEOMETRY)) {
2255 m_dockChecklistGuide->restoreGeometry (settings.value (SETTINGS_CHECKLIST_GUIDE_DOCK_GEOMETRY).toByteArray());
2256 }
2257
2258 } else {
2259
2260 addDockWidget (area,
2261 m_dockChecklistGuide);
2262
2263 }
2264
2265 // Main window settings. Preference for initial zoom factor is 100%, rather than fill mode, for issue #25. Some or all
2266 // settings are saved to the application AND saved to m_modelMainWindow for use in DlgSettingsMainWindow
2267 QLocale localeDefault;
2268 QLocale::Language language = (QLocale::Language) settings.value (SETTINGS_LOCALE_LANGUAGE,
2269 QVariant (localeDefault.language())).toInt();
2270 QLocale::Country country = (QLocale::Country) settings.value (SETTINGS_LOCALE_COUNTRY,
2271 QVariant (localeDefault.country())).toInt();
2272 QLocale locale (language,
2273 country);
2274 slotViewZoom ((ZoomFactor) settings.value (SETTINGS_ZOOM_FACTOR,
2275 QVariant (ZOOM_1_TO_1)).toInt());
2276 m_modelMainWindow.setLocale (locale);
2277 m_modelMainWindow.setZoomFactorInitial((ZoomFactorInitial) settings.value (SETTINGS_ZOOM_FACTOR_INITIAL,
2278 QVariant (DEFAULT_ZOOM_FACTOR_INITIAL)).toInt());
2279 m_modelMainWindow.setZoomControl ((ZoomControl) settings.value (SETTINGS_ZOOM_CONTROL,
2280 QVariant (ZOOM_CONTROL_MENU_WHEEL_PLUSMINUS)).toInt());
2281 m_modelMainWindow.setMainTitleBarFormat ((MainTitleBarFormat) settings.value (SETTINGS_MAIN_TITLE_BAR_FORMAT,
2282 QVariant (MAIN_TITLE_BAR_FORMAT_PATH)).toInt());
2284
2285 settings.endGroup();
2286}
2287
2288void MainWindow::settingsWrite ()
2289{
2290 QSettings settings (SETTINGS_ENGAUGE, SETTINGS_DIGITIZER);
2291
2292 settings.beginGroup (SETTINGS_GROUP_ENVIRONMENT);
2293 settings.setValue (SETTINGS_CURRENT_DIRECTORY, QDir::currentPath ());
2294 settings.endGroup ();
2295
2296 settings.beginGroup (SETTINGS_GROUP_MAIN_WINDOW);
2297 settings.setValue (SETTINGS_SIZE, size ());
2298 settings.setValue (SETTINGS_POS, pos ());
2299 settings.setValue (SETTINGS_HELP_SIZE, m_helpWindow->size());
2300 settings.setValue (SETTINGS_HELP_POS, m_helpWindow->pos ());
2301 if (m_dockChecklistGuide->isFloating()) {
2302
2303 settings.setValue (SETTINGS_CHECKLIST_GUIDE_DOCK_AREA, Qt::NoDockWidgetArea);
2304 settings.setValue (SETTINGS_CHECKLIST_GUIDE_DOCK_GEOMETRY, m_dockChecklistGuide->saveGeometry ());
2305
2306 } else {
2307
2308 settings.setValue (SETTINGS_CHECKLIST_GUIDE_DOCK_AREA, dockWidgetArea (m_dockChecklistGuide));
2309
2310 }
2311 settings.setValue (SETTINGS_CHECKLIST_GUIDE_WIZARD, m_actionHelpChecklistGuideWizard->isChecked ());
2312 settings.setValue (SETTINGS_LOCALE_LANGUAGE, m_modelMainWindow.locale().language());
2313 settings.setValue (SETTINGS_LOCALE_COUNTRY, m_modelMainWindow.locale().country());
2314 settings.setValue (SETTINGS_VIEW_BACKGROUND_TOOLBAR, m_actionViewBackground->isChecked());
2315 settings.setValue (SETTINGS_BACKGROUND_IMAGE, m_cmbBackground->currentData().toInt());
2316 settings.setValue (SETTINGS_VIEW_DIGITIZE_TOOLBAR, m_actionViewDigitize->isChecked ());
2317 settings.setValue (SETTINGS_VIEW_STATUS_BAR, m_statusBar->statusBarMode ());
2318 settings.setValue (SETTINGS_VIEW_SETTINGS_VIEWS_TOOLBAR, m_actionViewSettingsViews->isChecked ());
2319 settings.setValue (SETTINGS_VIEW_COORD_SYSTEM_TOOLBAR, m_actionViewCoordSystem->isChecked ());
2320 settings.setValue (SETTINGS_VIEW_TOOL_TIPS, m_actionViewToolTips->isChecked ());
2321 settings.setValue (SETTINGS_ZOOM_CONTROL, m_modelMainWindow.zoomControl());
2322 settings.setValue (SETTINGS_ZOOM_FACTOR, currentZoomFactor ());
2323 settings.setValue (SETTINGS_ZOOM_FACTOR_INITIAL, m_modelMainWindow.zoomFactorInitial());
2324 settings.setValue (SETTINGS_MAIN_TITLE_BAR_FORMAT, m_modelMainWindow.mainTitleBarFormat());
2325 settings.endGroup ();
2326}
2327
2328bool MainWindow::setupAfterLoad (const QString &fileName,
2329 const QString &temporaryMessage ,
2330 ImportType importType)
2331{
2332 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::setupAfterLoad"
2333 << " file=" << fileName.toLatin1().data()
2334 << " message=" << temporaryMessage.toLatin1().data()
2335 << " importType=" << importType;
2336
2337 const QString EMPTY_CURVE_NAME_TO_SKIP_BACKGROUND_PROCESSING; // For bootstrapping the preview
2338
2339 // At this point the code assumes CmdMediator for the NEW Document is already stored in m_cmdMediator
2340
2341 m_digitizeStateContext->resetOnLoad (m_cmdMediator); // Before setPixmap
2342 m_backgroundStateContext->setCurveSelected (m_transformation,
2343 m_cmdMediator->document().modelGridRemoval(),
2344 m_cmdMediator->document().modelColorFilter(),
2345 EMPTY_CURVE_NAME_TO_SKIP_BACKGROUND_PROCESSING); // Before setPixmap
2346 setPixmap (m_cmdMediator->pixmap ()); // Set background immediately so it is visible as a preview when any dialogs are displayed
2347
2348 // Image is visible now so the user can refer to it when we ask for the number of coordinate systems. Note that the Document
2349 // may already have multiple CoordSystem if user loaded a file that had multiple CoordSystem entries
2350 if (importType == IMPORT_TYPE_ADVANCED) {
2351
2352 applyZoomFactorAfterLoad(); // Apply the currently selected zoom factor
2353
2354 DlgImportAdvanced dlgImportAdvanced (*this);
2355 dlgImportAdvanced.exec();
2356
2357 if (dlgImportAdvanced.result() == QDialog::Rejected) {
2358 return false;
2359 }
2360
2361 int numberCoordSystem = dlgImportAdvanced.numberCoordSystem();
2362 m_cmdMediator->document().addCoordSystems (numberCoordSystem - 1);
2363 m_cmdMediator->setDocumentAxesPointsRequired (dlgImportAdvanced.documentAxesPointsRequired());
2364 }
2365
2366 m_transformation.resetOnLoad();
2367 m_transformationStateContext->resetOnLoad();
2368 m_scene->resetOnLoad();
2369
2370 connect (m_actionEditUndo, SIGNAL (triggered ()), m_cmdMediator, SLOT (undo ()));
2371 connect (m_actionEditUndo, SIGNAL (triggered ()), m_cmdStackShadow, SLOT (slotUndo ()));
2372 connect (m_actionEditRedo, SIGNAL (triggered ()), m_cmdMediator, SLOT (redo ())); // No effect until CmdMediator::undo and CmdStackShadow::slotUndo get called
2373 connect (m_actionEditRedo, SIGNAL (triggered ()), m_cmdStackShadow, SLOT (slotRedo ())); // No effect after CmdMediator::undo and CmdStackShadow::slotUndo get called
2374 connect (m_cmdMediator, SIGNAL (canRedoChanged(bool)), this, SLOT (slotCanRedoChanged (bool)));
2375 connect (m_cmdMediator, SIGNAL (canUndoChanged(bool)), this, SLOT (slotCanUndoChanged (bool)));
2376 connect (m_cmdMediator, SIGNAL (redoTextChanged (const QString &)), this, SLOT (slotRedoTextChanged (const QString &)));
2377 connect (m_cmdMediator, SIGNAL (undoTextChanged (const QString &)), this, SLOT (slotUndoTextChanged (const QString &)));
2378 loadCurveListFromCmdMediator ();
2379 loadCoordSystemListFromCmdMediator ();
2381
2382 m_isDocumentExported = false;
2383
2384 // Background must be set (by setPixmap) before slotViewZoomFill which relies on the background. At this point
2385 // the transformation is undefined (unless the code is changed) so grid removal will not work
2386 // but updateTransformationAndItsDependencies will call this again to fix that issue. Note that the selected
2387 // curve name was set (by setCurveSelected) earlier before the call to setPixmap
2388 m_backgroundStateContext->setCurveSelected (m_transformation,
2389 m_cmdMediator->document().modelGridRemoval(),
2390 m_cmdMediator->document().modelColorFilter(),
2391 m_cmbCurve->currentText ());
2392 m_backgroundStateContext->setBackgroundImage ((BackgroundImage) m_cmbBackground->currentIndex ());
2393
2394 applyZoomFactorAfterLoad(); // Zoom factor must be reapplied after background image is set, to have any effect
2395
2396 setCurrentFile(fileName);
2397 m_statusBar->showTemporaryMessage (temporaryMessage);
2398 m_statusBar->wakeUp ();
2399
2400 saveStartingDocumentSnapshot();
2401
2402 updateAfterCommand(); // Replace stale points by points in new Document
2403
2404 return true;
2405}
2406
2407void MainWindow::showEvent (QShowEvent *event)
2408{
2409 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::showEvent"
2410 << " files=" << m_loadStartupFiles.join (",").toLatin1().data();
2411
2412 QMainWindow::showEvent (event);
2413
2414 if (m_loadStartupFiles.count() > 0) {
2415
2416 m_timerLoadStartupFiles = new QTimer;
2417 m_timerLoadStartupFiles->setSingleShot (true);
2418 connect (m_timerLoadStartupFiles, SIGNAL (timeout ()), this, SLOT (slotLoadStartupFiles ()));
2419 m_timerLoadStartupFiles->start (0); // Zero delay still waits until execution finishes and gui is available
2420
2421 }
2422}
2423
2424void MainWindow::showTemporaryMessage (const QString &temporaryMessage)
2425{
2426 m_statusBar->showTemporaryMessage (temporaryMessage);
2427}
2428
2429void MainWindow::slotBtnPrintAll ()
2430{
2431 LOG4CPP_DEBUG_S ((*mainCat)) << "MainWindow::slotBtnPrintAll";
2432
2433 ghostsCreate ();
2434
2435 QPrinter printer (QPrinter::HighResolution);
2436 QPrintDialog dlg (&printer, this);
2437 if (dlg.exec() == QDialog::Accepted) {
2438 QPainter painter (&printer);
2439 m_view->render (&painter);
2440 painter.end();
2441 }
2442
2443 ghostsDestroy ();
2444}
2445
2446void MainWindow::slotBtnShowAllPressed ()
2447{
2448 LOG4CPP_DEBUG_S ((*mainCat)) << "MainWindow::slotBtnShowAllPressed";
2449
2450 // Start of press-release sequence
2451 ghostsCreate ();
2452}
2453
2454void MainWindow::slotBtnShowAllReleased ()
2455{
2456 LOG4CPP_DEBUG_S ((*mainCat)) << "MainWindow::slotBtnShowAllReleased";
2457
2458 // End of press-release sequence
2459 ghostsDestroy ();
2460}
2461
2462void MainWindow::slotCanRedoChanged (bool canRedo)
2463{
2464 LOG4CPP_DEBUG_S ((*mainCat)) << "MainWindow::slotCanRedoChanged";
2465
2466 m_actionEditRedo->setEnabled (canRedo || m_cmdStackShadow->canRedo());
2467}
2468
2469void MainWindow::slotCanUndoChanged (bool canUndo)
2470{
2471 LOG4CPP_DEBUG_S ((*mainCat)) << "MainWindow::slotCanUndoChanged";
2472
2473 m_actionEditUndo->setEnabled (canUndo);
2474}
2475
2476void MainWindow::slotChecklistClosed()
2477{
2478 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotChecklistClosed";
2479
2480 m_actionViewChecklistGuide->setChecked (false);
2481}
2482
2483void MainWindow::slotCleanChanged(bool clean)
2484{
2485 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotCleanChanged";
2486
2487 setWindowModified (!clean);
2488}
2489
2490void MainWindow::slotCmbBackground(int currentIndex)
2491{
2492 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotCmbBackground";
2493
2494 switch (currentIndex) {
2495 case BACKGROUND_IMAGE_NONE:
2496 if (!m_actionViewBackgroundNone->isChecked()) {
2497 m_actionViewBackgroundNone->toggle();
2498 }
2499 break;
2500
2501 case BACKGROUND_IMAGE_ORIGINAL:
2502 if (!m_actionViewBackgroundOriginal->isChecked ()) {
2503 m_actionViewBackgroundOriginal->toggle();
2504 }
2505 break;
2506
2507 case BACKGROUND_IMAGE_FILTERED:
2508 if (!m_actionViewBackgroundFiltered->isChecked ()) {
2509 m_actionViewBackgroundFiltered->toggle();
2510 }
2511 break;
2512 }
2513
2514 m_backgroundStateContext->setBackgroundImage ((BackgroundImage) currentIndex);
2515}
2516
2517void MainWindow::slotCmbCoordSystem(int index)
2518{
2519 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotCmbCoordSystem";
2520
2522 m_cmdMediator->document(),
2523 index);
2524
2525 m_cmdMediator->push (cmd);
2526}
2527
2528void MainWindow::slotCmbCurve(int /* index */)
2529{
2530 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotCmbCurve";
2531
2532 m_backgroundStateContext->setCurveSelected (m_transformation,
2533 m_cmdMediator->document().modelGridRemoval(),
2534 m_cmdMediator->document().modelColorFilter(),
2535 m_cmbCurve->currentText ());
2536 m_digitizeStateContext->handleCurveChange (m_cmdMediator);
2537
2538 updateViewedCurves();
2540}
2541
2542void MainWindow::slotContextMenuEvent (QString pointIdentifier)
2543{
2544 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotContextMenuEvent point=" << pointIdentifier.toLatin1 ().data ();
2545
2546 m_digitizeStateContext->handleContextMenuEvent (m_cmdMediator,
2547 pointIdentifier);
2548}
2549
2550void MainWindow::slotDigitizeAxis ()
2551{
2552 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotDigitizeAxis";
2553
2554 m_digitizeStateContext->requestImmediateStateTransition (m_cmdMediator,
2555 DIGITIZE_STATE_AXIS);
2556 m_cmbCurve->setEnabled (false); // Graph curve is irrelevant in this mode
2557 m_viewPointStyle->setEnabled (true); // Point style is important in this mode
2558 m_viewSegmentFilter->setEnabled (true); // Filtering is important in this mode
2559}
2560
2561void MainWindow::slotDigitizeColorPicker ()
2562{
2563 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotDigitizeColorPicker";
2564
2565 m_digitizeStateContext->requestImmediateStateTransition (m_cmdMediator,
2566 DIGITIZE_STATE_COLOR_PICKER);
2567 m_cmbCurve->setEnabled (true);
2568 m_viewPointStyle->setEnabled (true);
2569 m_viewSegmentFilter->setEnabled (true);
2570}
2571
2572void MainWindow::slotDigitizeCurve ()
2573{
2574 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotDigitizeCurve";
2575
2576 m_digitizeStateContext->requestImmediateStateTransition (m_cmdMediator,
2577 DIGITIZE_STATE_CURVE);
2578 m_cmbCurve->setEnabled (true);
2579 m_viewPointStyle->setEnabled (true);
2580 m_viewSegmentFilter->setEnabled (true);
2581}
2582
2583void MainWindow::slotDigitizePointMatch ()
2584{
2585 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotDigitizePointMatch";
2586
2587 m_digitizeStateContext->requestImmediateStateTransition (m_cmdMediator,
2588 DIGITIZE_STATE_POINT_MATCH);
2589 m_cmbCurve->setEnabled (true);
2590 m_viewPointStyle->setEnabled (true);
2591 m_viewSegmentFilter->setEnabled (true);
2592}
2593
2594void MainWindow::slotDigitizeSegment ()
2595{
2596 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotDigitizeSegment";
2597
2598 m_digitizeStateContext->requestImmediateStateTransition (m_cmdMediator,
2599 DIGITIZE_STATE_SEGMENT);
2600 m_cmbCurve->setEnabled (true);
2601 m_viewPointStyle->setEnabled (true);
2602 m_viewSegmentFilter->setEnabled (true);
2603}
2604
2605void MainWindow::slotDigitizeSelect ()
2606{
2607 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotDigitizeSelect";
2608
2609 m_digitizeStateContext->requestImmediateStateTransition (m_cmdMediator,
2610 DIGITIZE_STATE_SELECT);
2611 m_cmbCurve->setEnabled (false);
2612 m_viewPointStyle->setEnabled (false);
2613 m_viewSegmentFilter->setEnabled (false);
2614}
2615
2616void MainWindow::slotEditCopy ()
2617{
2618 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotEditCopy";
2619
2620 CmdCopy *cmd = new CmdCopy (*this,
2621 m_cmdMediator->document(),
2622 m_scene->selectedPointIdentifiers ());
2623 m_digitizeStateContext->appendNewCmd (m_cmdMediator,
2624 cmd);
2625}
2626
2627void MainWindow::slotEditCut ()
2628{
2629 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotEditCut";
2630
2631 CmdCut *cmd = new CmdCut (*this,
2632 m_cmdMediator->document(),
2633 m_scene->selectedPointIdentifiers ());
2634 m_digitizeStateContext->appendNewCmd (m_cmdMediator,
2635 cmd);
2636}
2637
2638void MainWindow::slotEditDelete ()
2639{
2640 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotEditDelete";
2641
2642 CmdDelete *cmd = new CmdDelete (*this,
2643 m_cmdMediator->document(),
2644 m_scene->selectedPointIdentifiers ());
2645 m_digitizeStateContext->appendNewCmd (m_cmdMediator,
2646 cmd);
2647}
2648
2649void MainWindow::slotEditMenu ()
2650{
2651 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotEditMenu";
2652
2653 m_actionEditPasteAsNew->setEnabled (!QApplication::clipboard()->image().isNull());
2654 m_actionEditPasteAsNewAdvanced->setEnabled (!QApplication::clipboard()->image().isNull());
2655}
2656
2657void MainWindow::slotEditPaste ()
2658{
2659 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotEditPaste";
2660}
2661
2662void MainWindow::slotEditPasteAsNew ()
2663{
2664 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotEditPasteAsNew";
2665
2666 filePaste (IMPORT_TYPE_SIMPLE);
2667}
2668
2669void MainWindow::slotEditPasteAsNewAdvanced ()
2670{
2671 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotEditPasteAsNewAdvanced";
2672
2673 filePaste (IMPORT_TYPE_ADVANCED);
2674}
2675
2676void MainWindow::slotFileClose()
2677{
2678 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotFileClose";
2679
2680 if (maybeSave ()) {
2681
2682 // Transition from defined to undefined. This must be after the clearing of the screen
2683 // since the axes checker screen item (and maybe others) must still exist
2684 m_transformationStateContext->triggerStateTransition(TRANSFORMATION_STATE_UNDEFINED,
2685 *m_cmdMediator,
2686 m_transformation,
2688
2689 // Transition to empty state so an inadvertent mouse press does not trigger, for example,
2690 // the creation of an axis point on a non-existent GraphicsScene (=crash)
2691 m_digitizeStateContext->requestImmediateStateTransition (m_cmdMediator,
2692 DIGITIZE_STATE_EMPTY);
2693
2694 // Remove screen objects
2695 m_scene->resetOnLoad ();
2696
2697 // Remove background
2698 m_backgroundStateContext->close ();
2699
2700 // Remove scroll bars if they exist
2701 m_scene->setSceneRect (QRectF (0, 0, 1, 1));
2702
2703 // Deallocate Document
2704 delete m_cmdMediator;
2705
2706 // Remove file information
2707 m_cmdMediator = 0;
2708 m_currentFile = "";
2709 m_engaugeFile = "";
2710 setWindowTitle (engaugeWindowTitle ());
2711
2712 updateControls();
2713 }
2714}
2715
2716void MainWindow::slotFileExport ()
2717{
2718 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotFileExport";
2719
2720 if (m_transformation.transformIsDefined()) {
2721
2722 ExportToFile exportStrategy;
2723 QString filter = QString ("%1;;%2;;All files (*.*)")
2724 .arg (exportStrategy.filterCsv ())
2725 .arg (exportStrategy.filterTsv ());
2726 QString defaultFileName = QString ("%1/%2.%3")
2727 .arg (QDir::currentPath ())
2728 .arg (m_currentFile)
2729 .arg (exportStrategy.fileExtensionCsv ());
2730 QFileDialog dlg;
2731 QString filterCsv = exportStrategy.filterCsv ();
2732 QString fileName = dlg.getSaveFileName (this,
2733 tr("Export"),
2734 defaultFileName,
2735 filter,
2736 &filterCsv);
2737 if (!fileName.isEmpty ()) {
2738
2739 fileExport(fileName,
2740 exportStrategy);
2741 }
2742 } else {
2743 DlgRequiresTransform dlg ("Export");
2744 dlg.exec ();
2745 }
2746}
2747
2748void MainWindow::slotFileImport ()
2749{
2750 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotFileImport";
2751
2752 fileImportWithPrompts (IMPORT_TYPE_SIMPLE);
2753}
2754
2755void MainWindow::slotFileImportAdvanced ()
2756{
2757 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotFileImportAdvanced";
2758
2759 fileImportWithPrompts (IMPORT_TYPE_ADVANCED);
2760}
2761
2762void MainWindow::slotFileImportDraggedImage(QImage image)
2763{
2764 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotFileImportDraggedImage";
2765
2766 // No need to check return value from loadImage since there are no prompts that give the user a chance to cancel
2767 loadImage ("",
2768 image,
2769 IMPORT_TYPE_SIMPLE);
2770}
2771
2772void MainWindow::slotFileImportDraggedImageUrl(QUrl url)
2773{
2774 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotFileImportDraggedImageUrl url=" << url.toString ().toLatin1 ().data ();
2775
2776 m_loadImageFromUrl->startLoadImage (url);
2777}
2778
2779void MainWindow::slotFileImportImage(QString fileName, QImage image)
2780{
2781 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotFileImportImage fileName=" << fileName.toLatin1 ().data ();
2782
2783 // No need to check return value from loadImage since there are no prompts that give the user a chance to cancel
2784 loadImage (fileName,
2785 image,
2786 IMPORT_TYPE_SIMPLE);
2787}
2788
2789void MainWindow::slotFileOpen()
2790{
2791 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotFileOpen";
2792
2793 if (maybeSave ()) {
2794
2795 // Allow selection of files with strange suffixes in case the file extension was changed. Since
2796 // the default is the first filter, the wildcard filter is added afterwards (it is the off-nominal case)
2797 QString filter = QString ("%1 (*.%2);; All Files (*.*)")
2798 .arg (ENGAUGE_FILENAME_DESCRIPTION)
2799 .arg (ENGAUGE_FILENAME_EXTENSION);
2800
2801 QString fileName = QFileDialog::getOpenFileName (this,
2802 tr("Open Document"),
2803 QDir::currentPath (),
2804 filter);
2805 if (!fileName.isEmpty ()) {
2806
2807 loadDocumentFile (fileName);
2808
2809 }
2810 }
2811}
2812
2813void MainWindow::slotFileOpenDraggedDigFile (QString fileName)
2814{
2815 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotFileOpenDraggedDigFile";
2816
2817 loadDocumentFile (fileName);
2818}
2819
2820void MainWindow::slotFilePrint()
2821{
2822 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotFilePrint";
2823
2824 QPrinter printer (QPrinter::HighResolution);
2825 QPrintDialog dlg (&printer, this);
2826 if (dlg.exec() == QDialog::Accepted) {
2827 QPainter painter (&printer);
2828 m_view->render (&painter);
2829 painter.end();
2830 }
2831}
2832
2833bool MainWindow::slotFileSave()
2834{
2835 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotFileSave";
2836
2837 if (m_engaugeFile.isEmpty()) {
2838 return slotFileSaveAs();
2839 } else {
2840 return saveDocumentFile (m_engaugeFile);
2841 }
2842}
2843
2844bool MainWindow::slotFileSaveAs()
2845{
2846 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotFileSaveAs";
2847
2848 // Append engauge file extension if it is not already there
2849 QString filenameDefault = m_currentFile;
2850 if (!m_currentFile.endsWith (ENGAUGE_FILENAME_EXTENSION)) {
2851 filenameDefault = QString ("%1.%2")
2852 .arg (m_currentFile)
2853 .arg (ENGAUGE_FILENAME_EXTENSION);
2854 }
2855
2856 if (!m_engaugeFile.isEmpty()) {
2857 filenameDefault = m_engaugeFile;
2858 }
2859
2860 QString filterDigitizer = QString ("%1 (*.%2)")
2861 .arg (ENGAUGE_FILENAME_DESCRIPTION)
2862 .arg (ENGAUGE_FILENAME_EXTENSION);
2863 QString filterAll ("All files (*. *)");
2864
2865 QStringList filters;
2866 filters << filterDigitizer;
2867 filters << filterAll;
2868
2869 QFileDialog dlg(this);
2870 dlg.selectNameFilter (filterDigitizer);
2871 dlg.setNameFilters (filters);
2872 dlg.setWindowModality(Qt::WindowModal);
2873 dlg.setAcceptMode(QFileDialog::AcceptSave);
2874 dlg.selectFile(filenameDefault);
2875 if (dlg.exec()) {
2876
2877 QStringList files = dlg.selectedFiles();
2878 return saveDocumentFile(files.at(0));
2879 }
2880
2881 return false;
2882}
2883
2884void MainWindow::slotHelpAbout()
2885{
2886 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotHelpAbout";
2887
2888 DlgAbout dlg (*this);
2889 dlg.exec ();
2890}
2891
2892void MainWindow::slotHelpTutorial()
2893{
2894 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotHelpTutorial";
2895
2896 m_tutorialDlg->show ();
2897 m_tutorialDlg->exec ();
2898}
2899
2900void MainWindow::slotKeyPress (Qt::Key key,
2901 bool atLeastOneSelectedItem)
2902{
2903 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotKeyPress"
2904 << " key=" << QKeySequence (key).toString().toLatin1 ().data ()
2905 << " atLeastOneSelectedItem=" << (atLeastOneSelectedItem ? "true" : "false");
2906
2907 m_digitizeStateContext->handleKeyPress (m_cmdMediator,
2908 key,
2909 atLeastOneSelectedItem);
2910}
2911
2912void MainWindow::slotLeave ()
2913{
2914 LOG4CPP_DEBUG_S ((*mainCat)) << "MainWindow::slotLeave";
2915
2916 m_digitizeStateContext->handleLeave (m_cmdMediator);
2917}
2918
2919void MainWindow::slotLoadStartupFiles ()
2920{
2921 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotLoadStartupFiles";
2922
2923 ENGAUGE_ASSERT (m_loadStartupFiles.count() > 0);
2924
2925 QString fileName = m_loadStartupFiles.front(); // Get next file name
2926 m_loadStartupFiles.pop_front(); // Remove next file name
2927
2928 // Load next file into this instance of Engauge
2929 LoadFileInfo loadFileInfo;
2930 if (loadFileInfo.loadsAsDigFile(fileName)) {
2931
2932 loadDocumentFile (fileName);
2933
2934 } else {
2935
2936 fileImport (fileName,
2937 IMPORT_TYPE_SIMPLE);
2938
2939 }
2940
2941 if (m_loadStartupFiles.count() > 0) {
2942
2943 // Fork off another instance of this application to handle the remaining files recursively. New process
2944 // is detached so killing/terminating this process does not automatically kill the child process(es) also
2945 QProcess::startDetached (QCoreApplication::applicationFilePath(),
2946 m_loadStartupFiles);
2947 }
2948}
2949
2950void MainWindow::slotMouseMove (QPointF pos)
2951{
2952// LOG4CPP_DEBUG_S ((*mainCat)) << "MainWindow::slotMouseMove pos=" << QPointFToString (pos).toLatin1 ().data ();
2953
2954 // Ignore mouse moves before Document is loaded
2955 if (m_cmdMediator != 0) {
2956
2957 // Get status bar coordinates
2958 QString coordsScreen, coordsGraph, resolutionGraph;
2959 m_transformation.coordTextForStatusBar (pos,
2960 coordsScreen,
2961 coordsGraph,
2962 resolutionGraph);
2963
2964 // Update status bar coordinates
2965 m_statusBar->setCoordinates (coordsScreen,
2966 coordsGraph,
2967 resolutionGraph);
2968
2969 // There used to be a call to updateGraphicsLinesToMatchGraphicsPoints here, but that resulted
2970 // in hundreds of gratuitous log messages as the cursor was moved around, and nothing important happened
2971
2972 m_digitizeStateContext->handleMouseMove (m_cmdMediator,
2973 pos);
2974 }
2975}
2976
2977void MainWindow::slotMousePress (QPointF pos)
2978{
2979 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotMousePress";
2980
2982
2983 m_digitizeStateContext->handleMousePress (m_cmdMediator,
2984 pos);
2985}
2986
2987void MainWindow::slotMouseRelease (QPointF pos)
2988{
2989 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotMouseRelease";
2990
2991 if (pos.x() < 0 || pos.y() < 0) {
2992
2993 // Cursor is outside the image so drop this event. However, call updateControls since this may be
2994 // a click-and-drag to select in which case the controls (especially Copy and Cut) reflect the new selection
2995 updateControls ();
2996
2997 } else {
2998
2999 // Cursor is within the image so process this as a normal mouse release
3000 m_digitizeStateContext->handleMouseRelease (m_cmdMediator,
3001 pos);
3002 }
3003}
3004
3005void MainWindow::slotRecentFileAction ()
3006{
3007 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotRecentFileAction";
3008
3009 QAction *action = qobject_cast<QAction*>(sender ());
3010
3011 if (action) {
3012 QString fileName = action->data().toString();
3013 loadDocumentFile (fileName);
3014 }
3015}
3016
3017void MainWindow::slotRecentFileClear ()
3018{
3019 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotRecentFileClear";
3020
3021 QStringList emptyList;
3022
3023 QSettings settings (SETTINGS_ENGAUGE, SETTINGS_DIGITIZER);
3024 settings.setValue (SETTINGS_RECENT_FILE_LIST,
3025 emptyList);
3026
3027 updateRecentFileList();
3028}
3029
3030void MainWindow::slotRedoTextChanged (const QString &text)
3031{
3032 LOG4CPP_DEBUG_S ((*mainCat)) << "MainWindow::slotRedoTextChanged";
3033
3034 QString completeText ("Redo");
3035 if (!text.isEmpty ()) {
3036 completeText += QString (" \"%1\"").arg (text);
3037 }
3038 m_actionEditRedo->setText (completeText);
3039}
3040
3041void MainWindow::slotSetOverrideCursor (QCursor cursor)
3042{
3043 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotSetOverrideCursor";
3044
3045 m_digitizeStateContext->handleSetOverrideCursor (m_cmdMediator,
3046 cursor);
3047}
3048
3049void MainWindow::slotSettingsAxesChecker ()
3050{
3051 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotSettingsAxesChecker";
3052
3053 m_dlgSettingsAxesChecker->load (*m_cmdMediator);
3054 m_dlgSettingsAxesChecker->show ();
3055}
3056
3057void MainWindow::slotSettingsColorFilter ()
3058{
3059 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotSettingsColorFilter";
3060
3061 m_dlgSettingsColorFilter->load (*m_cmdMediator);
3062 m_dlgSettingsColorFilter->show ();
3063}
3064
3065void MainWindow::slotSettingsCoords ()
3066{
3067 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotSettingsCoords";
3068
3069 m_dlgSettingsCoords->load (*m_cmdMediator);
3070 m_dlgSettingsCoords->show ();
3071}
3072
3073void MainWindow::slotSettingsCurveAddRemove ()
3074{
3075 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotSettingsCurveAddRemove";
3076
3077 m_dlgSettingsCurveAddRemove->load (*m_cmdMediator);
3078 m_dlgSettingsCurveAddRemove->show ();
3079}
3080
3081void MainWindow::slotSettingsCurveProperties ()
3082{
3083 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotSettingsCurveProperties";
3084
3085 m_dlgSettingsCurveProperties->load (*m_cmdMediator);
3086 m_dlgSettingsCurveProperties->setCurveName (selectedGraphCurve ());
3087 m_dlgSettingsCurveProperties->show ();
3088}
3089
3090void MainWindow::slotSettingsDigitizeCurve ()
3091{
3092 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotSettingsDigitizeCurve";
3093
3094 m_dlgSettingsDigitizeCurve->load (*m_cmdMediator);
3095 m_dlgSettingsDigitizeCurve->show ();
3096}
3097
3098void MainWindow::slotSettingsExportFormat ()
3099{
3100 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotSettingsExportFormat";
3101
3102 if (transformIsDefined()) {
3103 m_dlgSettingsExportFormat->load (*m_cmdMediator);
3104 m_dlgSettingsExportFormat->show ();
3105 } else {
3106 DlgRequiresTransform dlg ("Export settings");
3107 dlg.exec();
3108 }
3109}
3110
3111void MainWindow::slotSettingsGeneral ()
3112{
3113 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotSettingsGeneral";
3114
3115 m_dlgSettingsGeneral->load (*m_cmdMediator);
3116 m_dlgSettingsGeneral->show ();
3117}
3118
3119void MainWindow::slotSettingsGridRemoval ()
3120{
3121 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotSettingsGridRemoval";
3122
3123 m_dlgSettingsGridRemoval->load (*m_cmdMediator);
3124 m_dlgSettingsGridRemoval->show ();
3125}
3126
3127void MainWindow::slotSettingsPointMatch ()
3128{
3129 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotSettingsPointMatch";
3130
3131 m_dlgSettingsPointMatch->load (*m_cmdMediator);
3132 m_dlgSettingsPointMatch->show ();
3133}
3134
3135void MainWindow::slotSettingsSegments ()
3136{
3137 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotSettingsSegments";
3138
3139 m_dlgSettingsSegments->load (*m_cmdMediator);
3140 m_dlgSettingsSegments->show ();
3141}
3142
3143void MainWindow::slotSettingsMainWindow ()
3144{
3145 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotSettingsMainWindow";
3146
3147 m_dlgSettingsMainWindow->loadMainWindowModel (*m_cmdMediator,
3148 m_modelMainWindow);
3149 m_dlgSettingsMainWindow->show ();
3150}
3151
3152void MainWindow::slotTimeoutRegressionErrorReport ()
3153{
3154 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotTimeoutRegressionErrorReport"
3155 << " cmdStackIndex=" << m_cmdMediator->index()
3156 << " cmdStackCount=" << m_cmdMediator->count();
3157
3158 if (m_cmdStackShadow->canRedo()) {
3159
3160 m_cmdStackShadow->slotRedo();
3161
3162 } else {
3163
3164 exportAllCoordinateSystems ();
3165
3166 // Regression test has finished so exit. We unset the dirty flag so there is no prompt
3167 m_cmdMediator->setClean();
3168 close();
3169
3170 }
3171}
3172
3173void MainWindow::slotTimeoutRegressionFileCmdScript ()
3174{
3175 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotTimeoutRegressionFileCmdScript";
3176
3177 if (m_fileCmdScript->canRedo()) {
3178
3179 m_fileCmdScript->redo(*this);
3180
3181 } else {
3182
3183 // Script file might already have closed the Document so export only if last was not closed
3184 if (m_cmdMediator != 0) {
3185
3186 exportAllCoordinateSystems ();
3187
3188 // We unset the dirty flag so there is no "Save changes?" prompt
3189 m_cmdMediator->setClean();
3190
3191 }
3192
3193 // Regression test has finished so exit
3194 close();
3195
3196 }
3197}
3198
3199void MainWindow::slotUndoTextChanged (const QString &text)
3200{
3201 LOG4CPP_DEBUG_S ((*mainCat)) << "MainWindow::slotUndoTextChanged";
3202
3203 QString completeText ("Undo");
3204 if (!text.isEmpty ()) {
3205 completeText += QString (" \"%1\"").arg (text);
3206 }
3207 m_actionEditUndo->setText (completeText);
3208}
3209
3210void MainWindow::slotViewGroupBackground(QAction *action)
3211{
3212 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewGroupBackground";
3213
3214 // Set the combobox
3215 BackgroundImage backgroundImage;
3216 int indexBackground;
3217 if (action == m_actionViewBackgroundNone) {
3218 indexBackground = m_cmbBackground->findData (QVariant (BACKGROUND_IMAGE_NONE));
3219 backgroundImage = BACKGROUND_IMAGE_NONE;
3220 } else if (action == m_actionViewBackgroundOriginal) {
3221 indexBackground = m_cmbBackground->findData (QVariant (BACKGROUND_IMAGE_ORIGINAL));
3222 backgroundImage = BACKGROUND_IMAGE_ORIGINAL;
3223 } else if (action == m_actionViewBackgroundFiltered) {
3224 indexBackground = m_cmbBackground->findData (QVariant (BACKGROUND_IMAGE_FILTERED));
3225 backgroundImage = BACKGROUND_IMAGE_FILTERED;
3226 } else {
3227 ENGAUGE_ASSERT (false);
3228
3229 // Defaults if assert is disabled so execution continues
3230 indexBackground = m_cmbBackground->findData (QVariant (BACKGROUND_IMAGE_ORIGINAL));
3231 backgroundImage = BACKGROUND_IMAGE_ORIGINAL;
3232 }
3233
3234 m_cmbBackground->setCurrentIndex (indexBackground);
3235 m_backgroundStateContext->setBackgroundImage (backgroundImage);
3236}
3237
3238void MainWindow::slotViewGroupCurves(QAction * /* action */)
3239{
3240 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewGroupCurves";
3241
3242 updateViewedCurves ();
3243}
3244
3245void MainWindow::slotViewGroupStatus(QAction *action)
3246{
3247 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewGroupStatus";
3248
3249 ENGAUGE_CHECK_PTR (m_statusBar); // At startup, make sure status bar is already set up when View menu gets initialized
3250
3251 if (action == m_actionStatusNever) {
3252 m_statusBar->setStatusBarMode(STATUS_BAR_MODE_NEVER);
3253 } else if (action == m_actionStatusTemporary) {
3254 m_statusBar->setStatusBarMode(STATUS_BAR_MODE_TEMPORARY);
3255 } else {
3256 m_statusBar->setStatusBarMode(STATUS_BAR_MODE_ALWAYS);
3257 }
3258}
3259
3260void MainWindow::slotViewToolBarBackground ()
3261{
3262 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewToolBarBackground";
3263
3264 if (m_actionViewBackground->isChecked ()) {
3265 m_toolBackground->show();
3266 } else {
3267 m_toolBackground->hide();
3268 }
3269}
3270
3271void MainWindow::slotViewToolBarChecklistGuide ()
3272{
3273 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewToolBarChecklistGuide";
3274
3275 if (m_actionViewChecklistGuide->isChecked ()) {
3276 m_dockChecklistGuide->show();
3277 } else {
3278 m_dockChecklistGuide->hide();
3279 }
3280}
3281
3282void MainWindow::slotViewToolBarCoordSystem ()
3283{
3284 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewToolBarCoordSystem";
3285
3286 if (m_actionViewCoordSystem->isChecked ()) {
3287 m_toolCoordSystem->show();
3288 } else {
3289 m_toolCoordSystem->hide();
3290 }
3291}
3292
3293void MainWindow::slotViewToolBarDigitize ()
3294{
3295 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewToolBarDigitize";
3296
3297 if (m_actionViewDigitize->isChecked ()) {
3298 m_toolDigitize->show();
3299 } else {
3300 m_toolDigitize->hide();
3301 }
3302}
3303
3304void MainWindow::slotViewToolBarSettingsViews ()
3305{
3306 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewToolBarSettingsViews";
3307
3308 if (m_actionViewSettingsViews->isChecked ()) {
3309 m_toolSettingsViews->show();
3310 } else {
3311 m_toolSettingsViews->hide();
3312 }
3313}
3314
3315void MainWindow::slotViewToolTips ()
3316{
3317 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewToolTips";
3318
3319 loadToolTips();
3320}
3321
3322void MainWindow::slotViewZoom(int zoom)
3323{
3324 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewZoom";
3325
3326 // Update zoom controls and apply the zoom factor
3327 switch ((ZoomFactor) zoom) {
3328 case ZOOM_16_TO_1:
3329 m_actionZoom16To1->setChecked(true);
3330 slotViewZoom16To1 ();
3331 break;
3332 case ZOOM_8_TO_1:
3333 m_actionZoom8To1->setChecked(true);
3334 slotViewZoom8To1 ();
3335 break;
3336 case ZOOM_4_TO_1:
3337 m_actionZoom4To1->setChecked(true);
3338 slotViewZoom4To1 ();
3339 break;
3340 case ZOOM_2_TO_1:
3341 m_actionZoom2To1->setChecked(true);
3342 slotViewZoom2To1 ();
3343 break;
3344 case ZOOM_1_TO_1:
3345 m_actionZoom1To1->setChecked(true);
3346 slotViewZoom1To1 ();
3347 break;
3348 case ZOOM_1_TO_2:
3349 m_actionZoom1To2->setChecked(true);
3350 slotViewZoom1To2 ();
3351 break;
3352 case ZOOM_1_TO_4:
3353 m_actionZoom1To4->setChecked(true);
3354 slotViewZoom1To4 ();
3355 break;
3356 case ZOOM_1_TO_8:
3357 m_actionZoom1To8->setChecked(true);
3358 slotViewZoom1To8 ();
3359 break;
3360 case ZOOM_1_TO_16:
3361 m_actionZoom1To16->setChecked(true);
3362 slotViewZoom1To16 ();
3363 break;
3364 case ZOOM_FILL:
3365 m_actionZoomFill->setChecked(true);
3366 slotViewZoomFill ();
3367 break;
3368 }
3369}
3370
3371void MainWindow::slotViewZoom16To1 ()
3372{
3373 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewZoom16To1";
3374
3375 QTransform transform;
3376 transform.scale (16.0, 16.0);
3377 m_view->setTransform (transform);
3378 emit signalZoom(ZOOM_16_TO_1);
3379}
3380
3381void MainWindow::slotViewZoom8To1 ()
3382{
3383 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewZoom8To1";
3384
3385 QTransform transform;
3386 transform.scale (8.0, 8.0);
3387 m_view->setTransform (transform);
3388 emit signalZoom(ZOOM_8_TO_1);
3389}
3390
3391void MainWindow::slotViewZoom4To1 ()
3392{
3393 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewZoom4To1";
3394
3395 QTransform transform;
3396 transform.scale (4.0, 4.0);
3397 m_view->setTransform (transform);
3398 emit signalZoom(ZOOM_4_TO_1);
3399}
3400
3401void MainWindow::slotViewZoom2To1 ()
3402{
3403 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotZoom2To1";
3404
3405 QTransform transform;
3406 transform.scale (2.0, 2.0);
3407 m_view->setTransform (transform);
3408 emit signalZoom(ZOOM_2_TO_1);
3409}
3410
3411void MainWindow::slotViewZoom1To1 ()
3412{
3413 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewZoom1To1";
3414
3415 QTransform transform;
3416 transform.scale (1.0, 1.0);
3417 m_view->setTransform (transform);
3418 emit signalZoom(ZOOM_1_TO_1);
3419}
3420
3421void MainWindow::slotViewZoom1To2 ()
3422{
3423 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotZoom1To2";
3424
3425 QTransform transform;
3426 transform.scale (0.5, 0.5);
3427 m_view->setTransform (transform);
3428 emit signalZoom(ZOOM_1_TO_2);
3429}
3430
3431void MainWindow::slotViewZoom1To4 ()
3432{
3433 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotZoom1To4";
3434
3435 QTransform transform;
3436 transform.scale (0.25, 0.25);
3437 m_view->setTransform (transform);
3438 emit signalZoom(ZOOM_1_TO_4);
3439}
3440
3441void MainWindow::slotViewZoom1To8 ()
3442{
3443 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotZoom1To8";
3444
3445 QTransform transform;
3446 transform.scale (0.125, 0.125);
3447 m_view->setTransform (transform);
3448 emit signalZoom(ZOOM_1_TO_8);
3449}
3450
3451void MainWindow::slotViewZoom1To16 ()
3452{
3453 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotZoom1To16";
3454
3455 QTransform transform;
3456 transform.scale (0.0625, 0.0625);
3457 m_view->setTransform (transform);
3458 emit signalZoom(ZOOM_1_TO_16);
3459}
3460
3461void MainWindow::slotViewZoomFill ()
3462{
3463 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewZoomFill";
3464
3465 m_backgroundStateContext->fitInView (*m_view);
3466
3467 emit signalZoom(ZOOM_FILL);
3468}
3469
3470void MainWindow::slotViewZoomIn ()
3471{
3472 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewZoomIn";
3473
3474 // Try to zoom in. First determine what the next zoom factor should be
3475
3476 bool goto16To1 = false, goto8To1 = false, goto4To1 = false, goto2To1 = false;
3477 bool goto1To1 = false;
3478 bool goto1To2 = false, goto1To4 = false, goto1To8 = false, goto1To16 = false;
3479 if (m_actionZoomFill->isChecked ()) {
3480
3481 // Zooming in means user probably wants the more squished direction to be zoomed in by one step
3482 double xScale = m_view->transform().m11();
3483 double yScale = m_view->transform().m22();
3484 double scale = qMin(xScale, yScale);
3485 if (scale < 0.125) {
3486 goto1To8 = true;
3487 } else if (scale < 0.25) {
3488 goto1To4 = true;
3489 } else if (scale < 0.5) {
3490 goto1To2 = true;
3491 } else if (scale < 1) {
3492 goto1To1 = true;
3493 } else if (scale < 2) {
3494 goto2To1 = true;
3495 } else if (scale < 4) {
3496 goto4To1 = true;
3497 } else if (scale < 8) {
3498 goto8To1 = true;
3499 } else {
3500 goto1To16 = true;
3501 }
3502 } else {
3503 goto16To1 = m_actionZoom8To1->isChecked ();
3504 goto8To1 = m_actionZoom4To1->isChecked ();
3505 goto4To1 = m_actionZoom2To1->isChecked ();
3506 goto2To1 = m_actionZoom1To1->isChecked ();
3507 goto1To1 = m_actionZoom1To2->isChecked ();
3508 goto1To2 = m_actionZoom1To4->isChecked ();
3509 goto1To4 = m_actionZoom1To8->isChecked ();
3510 goto1To8 = m_actionZoom1To16->isChecked ();
3511 }
3512
3513 // Update controls and apply zoom factor
3514 if (goto16To1) {
3515 m_actionZoom16To1->setChecked (true);
3516 slotViewZoom16To1 ();
3517 } else if (goto8To1) {
3518 m_actionZoom8To1->setChecked (true);
3519 slotViewZoom8To1 ();
3520 } else if (goto4To1) {
3521 m_actionZoom4To1->setChecked (true);
3522 slotViewZoom4To1 ();
3523 } else if (goto2To1) {
3524 m_actionZoom2To1->setChecked (true);
3525 slotViewZoom2To1 ();
3526 } else if (goto1To1) {
3527 m_actionZoom1To1->setChecked (true);
3528 slotViewZoom1To1 ();
3529 } else if (goto1To2) {
3530 m_actionZoom1To2->setChecked (true);
3531 slotViewZoom1To2 ();
3532 } else if (goto1To4) {
3533 m_actionZoom1To4->setChecked (true);
3534 slotViewZoom1To4 ();
3535 } else if (goto1To8) {
3536 m_actionZoom1To8->setChecked (true);
3537 slotViewZoom1To8 ();
3538 } else if (goto1To16) {
3539 m_actionZoom1To16->setChecked (true);
3540 slotViewZoom1To16 ();
3541 }
3542}
3543
3544void MainWindow::slotViewZoomInFromWheelEvent ()
3545{
3546 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewZoomInFromWheelEvent";
3547
3548 if ((m_modelMainWindow.zoomControl() == ZOOM_CONTROL_MENU_WHEEL) ||
3549 (m_modelMainWindow.zoomControl() == ZOOM_CONTROL_MENU_WHEEL_PLUSMINUS)) {
3550
3551 // Forward this event
3552 slotViewZoomIn ();
3553 }
3554}
3555
3556void MainWindow::slotViewZoomOut ()
3557{
3558 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewZoomOut";
3559
3560 // Try to zoom out. First determine what the next zoom factor should be
3561
3562 bool goto16To1 = false, goto8To1 = false, goto4To1 = false, goto2To1 = false;
3563 bool goto1To1 = false;
3564 bool goto1To2 = false, goto1To4 = false, goto1To8 = false, goto1To16 = false;
3565 if (m_actionZoomFill->isChecked ()) {
3566
3567 // Zooming out means user probably wants the less squished direction to be zoomed out by one step
3568 double xScale = m_view->transform().m11();
3569 double yScale = m_view->transform().m22();
3570 double scale = qMax(xScale, yScale);
3571 if (scale > 8) {
3572 goto8To1 = true;
3573 } else if (scale > 4) {
3574 goto4To1 = true;
3575 } else if (scale > 2) {
3576 goto2To1 = true;
3577 } else if (scale > 1) {
3578 goto1To1 = true;
3579 } else if (scale > 0.5) {
3580 goto1To2 = true;
3581 } else if (scale > 0.25) {
3582 goto1To4 = true;
3583 } else if (scale > 0.125) {
3584 goto1To8 = true;
3585 } else {
3586 goto1To16 = true;
3587 }
3588 } else {
3589 goto8To1 = m_actionZoom16To1->isChecked ();
3590 goto4To1 = m_actionZoom8To1->isChecked ();
3591 goto2To1 = m_actionZoom4To1->isChecked ();
3592 goto1To1 = m_actionZoom2To1->isChecked ();
3593 goto1To2 = m_actionZoom1To1->isChecked ();
3594 goto1To4 = m_actionZoom1To2->isChecked ();
3595 goto1To8 = m_actionZoom1To4->isChecked ();
3596 goto1To16 = m_actionZoom1To8->isChecked ();
3597 }
3598
3599 // Update controls and apply zoom factor
3600 if (goto1To16) {
3601 m_actionZoom1To16->setChecked (true);
3602 slotViewZoom1To16 ();
3603 } else if (goto1To8) {
3604 m_actionZoom1To8->setChecked (true);
3605 slotViewZoom1To8 ();
3606 } else if (goto1To4) {
3607 m_actionZoom1To4->setChecked (true);
3608 slotViewZoom1To4 ();
3609 } else if (goto1To2) {
3610 m_actionZoom1To2->setChecked (true);
3611 slotViewZoom1To2 ();
3612 } else if (goto1To1) {
3613 m_actionZoom1To1->setChecked (true);
3614 slotViewZoom1To1 ();
3615 } else if (goto2To1) {
3616 m_actionZoom2To1->setChecked (true);
3617 slotViewZoom2To1 ();
3618 } else if (goto4To1) {
3619 m_actionZoom4To1->setChecked (true);
3620 slotViewZoom4To1 ();
3621 } else if (goto8To1) {
3622 m_actionZoom8To1->setChecked (true);
3623 slotViewZoom8To1 ();
3624 } else if (goto16To1) {
3625 m_actionZoom16To1->setChecked (true);
3626 slotViewZoom16To1 ();
3627 }
3628}
3629
3630void MainWindow::slotViewZoomOutFromWheelEvent ()
3631{
3632 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::slotViewZoomOutFromWheelEvent";
3633
3634 if ((m_modelMainWindow.zoomControl() == ZOOM_CONTROL_MENU_WHEEL) ||
3635 (m_modelMainWindow.zoomControl() == ZOOM_CONTROL_MENU_WHEEL_PLUSMINUS)) {
3636
3637 // Forward this event
3638 slotViewZoomOut ();
3639 }
3640}
3641
3642void MainWindow::startRegressionTestErrorReport(const QString &regressionInputFile)
3643{
3644 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::startRegressionTestErrorReport";
3645
3646 const int REGRESSION_INTERVAL = 400; // Milliseconds
3647
3648 // Save output/export file name
3649 m_regressionFile = exportFilenameFromInputFilename (regressionInputFile);
3650
3651 m_timerRegressionErrorReport = new QTimer();
3652 m_timerRegressionErrorReport->setSingleShot(false);
3653 connect (m_timerRegressionErrorReport, SIGNAL (timeout()), this, SLOT (slotTimeoutRegressionErrorReport()));
3654
3655 m_timerRegressionErrorReport->start(REGRESSION_INTERVAL);
3656}
3657
3658void MainWindow::startRegressionTestFileCmdScript()
3659{
3660 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::startRegressionTestFileCmdScript";
3661
3662 const int REGRESSION_INTERVAL = 400; // Milliseconds
3663
3664 m_timerRegressionFileCmdScript = new QTimer();
3665 m_timerRegressionFileCmdScript->setSingleShot(false);
3666 connect (m_timerRegressionFileCmdScript, SIGNAL (timeout()), this, SLOT (slotTimeoutRegressionFileCmdScript()));
3667
3668 m_timerRegressionFileCmdScript->start(REGRESSION_INTERVAL);
3669}
3670
3672{
3673 return m_transformation;
3674}
3675
3677{
3678 return m_transformation.transformIsDefined();
3679}
3680
3682{
3683 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateAfterCommand";
3684
3685 ENGAUGE_CHECK_PTR (m_cmdMediator);
3686
3687 // Update transformation stuff, including the graph coordinates of every point in the Document, so coordinates in
3688 // status bar are up to date. Point coordinates in Document are also updated
3689 updateAfterCommandStatusBarCoords ();
3690
3691 // Update the QGraphicsScene with the populated Curves. This requires the points in the Document to be already updated
3692 // by updateAfterCommandStatusBarCoords
3693 m_scene->updateAfterCommand (*m_cmdMediator);
3694
3695 updateControls ();
3696
3697 // Update checklist guide status
3698 m_dockChecklistGuide->update (*m_cmdMediator,
3699 m_isDocumentExported);
3700
3701 // Final action at the end of a redo/undo is to checkpoint the Document and GraphicsScene to log files
3702 // so proper state can be verified
3703 writeCheckpointToLogFile ();
3704}
3705
3706void MainWindow::updateAfterCommandStatusBarCoords ()
3707{
3708 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateAfterCommandStatusBarCoords";
3709
3710 // For some reason, mapFromGlobal(QCursor::pos) differs from event->pos by a little bit. We must compensate for
3711 // this so cursor coordinates in status bar match the DlgEditPoint inputs initially. After the mouse moves
3712 // the problem disappears since event->pos is available and QCursor::pos is no longer needed
3713 const QPoint HACK_SO_GRAPH_COORDINATE_MATCHES_INPUT (1, 1);
3714
3715 Transformation m_transformationBefore (m_transformation);
3716
3717 updateTransformationAndItsDependencies();
3718
3719 // Trigger state transitions for transformation if appropriate
3720 if (!m_transformationBefore.transformIsDefined() && m_transformation.transformIsDefined()) {
3721
3722 // Transition from undefined to defined
3723 m_transformationStateContext->triggerStateTransition(TRANSFORMATION_STATE_DEFINED,
3724 *m_cmdMediator,
3725 m_transformation,
3727
3728 } else if (m_transformationBefore.transformIsDefined() && !m_transformation.transformIsDefined()) {
3729
3730 // Transition from defined to undefined
3731 m_transformationStateContext->triggerStateTransition(TRANSFORMATION_STATE_UNDEFINED,
3732 *m_cmdMediator,
3733 m_transformation,
3735
3736 } else if (m_transformation.transformIsDefined() && (m_transformationBefore != m_transformation)) {
3737
3738 // There was not a define/undefined or undefined/defined transition, but the transformation changed so we
3739 // need to update the Checker
3740 m_transformationStateContext->updateAxesChecker(*m_cmdMediator,
3741 m_transformation);
3742
3743 }
3744
3745 QPoint posLocal = m_view->mapFromGlobal (QCursor::pos ()) - HACK_SO_GRAPH_COORDINATE_MATCHES_INPUT;
3746 QPointF posScreen = m_view->mapToScene (posLocal);
3747
3748 slotMouseMove (posScreen); // Update the status bar coordinates to reflect the newly updated transformation
3749}
3750
3752{
3753 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateAfterMouseRelease";
3754
3755 updateControls ();
3756}
3757
3758void MainWindow::updateControls ()
3759{
3760 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateControls"
3761 << " selectedItems=" << m_scene->selectedItems().count();
3762
3763 m_cmbBackground->setEnabled (!m_currentFile.isEmpty ());
3764
3765 m_menuFileOpenRecent->setEnabled ((m_actionRecentFiles.count () > 0) &&
3766 (m_actionRecentFiles.at(0)->isVisible ())); // Need at least one visible recent file entry
3767 m_actionClose->setEnabled (!m_currentFile.isEmpty ());
3768 m_actionSave->setEnabled (!m_currentFile.isEmpty ());
3769 m_actionSaveAs->setEnabled (!m_currentFile.isEmpty ());
3770 m_actionExport->setEnabled (!m_currentFile.isEmpty ());
3771 m_actionPrint->setEnabled (!m_currentFile.isEmpty ());
3772
3773 if (m_cmdMediator == 0) {
3774 m_actionEditUndo->setEnabled (false);
3775 m_actionEditRedo->setEnabled (false);
3776 } else {
3777 m_actionEditUndo->setEnabled (m_cmdMediator->canUndo ());
3778 m_actionEditRedo->setEnabled (m_cmdMediator->canRedo () || m_cmdStackShadow->canRedo ());
3779 }
3780 m_actionEditCut->setEnabled (m_scene->selectedItems().count () > 0);
3781 m_actionEditCopy->setEnabled (m_scene->selectedItems().count () > 0);
3782 m_actionEditPaste->setEnabled (false);
3783 m_actionEditDelete->setEnabled (m_scene->selectedItems().count () > 0);
3784 // m_actionEditPasteAsNew and m_actionEditPasteAsNewAdvanced are updated when m_menuEdit is about to be shown
3785
3786 m_actionDigitizeAxis->setEnabled (!m_currentFile.isEmpty ());
3787 m_actionDigitizeCurve ->setEnabled (!m_currentFile.isEmpty ());
3788 m_actionDigitizePointMatch->setEnabled (!m_currentFile.isEmpty ());
3789 m_actionDigitizeColorPicker->setEnabled (!m_currentFile.isEmpty ());
3790 m_actionDigitizeSegment->setEnabled (!m_currentFile.isEmpty ());
3791 m_actionDigitizeSelect->setEnabled (!m_currentFile.isEmpty ());
3792
3793 m_actionViewBackground->setEnabled (!m_currentFile.isEmpty());
3794 m_actionViewChecklistGuide->setEnabled (!m_dockChecklistGuide->browserIsEmpty());
3795 m_actionViewDigitize->setEnabled (!m_currentFile.isEmpty ());
3796 m_actionViewSettingsViews->setEnabled (!m_currentFile.isEmpty ());
3797
3798 m_actionSettingsCoords->setEnabled (!m_currentFile.isEmpty ());
3799 m_actionSettingsCurveAddRemove->setEnabled (!m_currentFile.isEmpty ());
3800 m_actionSettingsCurveProperties->setEnabled (!m_currentFile.isEmpty ());
3801 m_actionSettingsDigitizeCurve->setEnabled (!m_currentFile.isEmpty ());
3802 m_actionSettingsExport->setEnabled (!m_currentFile.isEmpty ());
3803 m_actionSettingsColorFilter->setEnabled (!m_currentFile.isEmpty ());
3804 m_actionSettingsAxesChecker->setEnabled (!m_currentFile.isEmpty ());
3805 m_actionSettingsGridRemoval->setEnabled (!m_currentFile.isEmpty ());
3806 m_actionSettingsPointMatch->setEnabled (!m_currentFile.isEmpty ());
3807 m_actionSettingsSegments->setEnabled (!m_currentFile.isEmpty ());
3808 m_actionSettingsGeneral->setEnabled (!m_currentFile.isEmpty ());
3809
3810 m_groupBackground->setEnabled (!m_currentFile.isEmpty ());
3811 m_groupCurves->setEnabled (!m_currentFile.isEmpty ());
3812 m_groupZoom->setEnabled (!m_currentFile.isEmpty ());
3813
3814 m_actionZoomIn->setEnabled (!m_currentFile.isEmpty ()); // Disable at startup so shortcut has no effect
3815 m_actionZoomOut->setEnabled (!m_currentFile.isEmpty ()); // Disable at startup so shortcut has no effect
3816}
3817
3818void MainWindow::updateCoordSystem(CoordSystemIndex coordSystemIndex)
3819{
3820 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateCoordSystem";
3821
3822 m_cmdMediator->document().setCoordSystemIndex (coordSystemIndex);
3823 updateTransformationAndItsDependencies(); // Transformation state may have changed
3824 updateSettingsAxesChecker(m_cmdMediator->document().modelAxesChecker()); // Axes checker dependes on transformation state
3825
3826 // Nice trick for showing that a new coordinate system is in effect is to show the axes checker
3827 m_transformationStateContext->updateAxesChecker (*m_cmdMediator,
3828 m_transformation);
3829
3831}
3832
3834{
3835 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateDigitizeStateIfSoftwareTriggered";
3836
3837 switch (digitizeState) {
3838 case DIGITIZE_STATE_AXIS:
3839 m_actionDigitizeAxis->setChecked(true);
3840 slotDigitizeAxis(); // Call the slot that the setChecked call fails to trigger
3841 break;
3842
3843 case DIGITIZE_STATE_COLOR_PICKER:
3844 m_actionDigitizeColorPicker->setChecked(true);
3845 slotDigitizeColorPicker(); // Call the slot that the setChecked call fails to trigger
3846 break;
3847
3848 case DIGITIZE_STATE_CURVE:
3849 m_actionDigitizeCurve->setChecked(true);
3850 slotDigitizeCurve(); // Call the slot that the setChecked call fails to trigger
3851 break;
3852
3853 case DIGITIZE_STATE_EMPTY:
3854 break;
3855
3856 case DIGITIZE_STATE_POINT_MATCH:
3857 m_actionDigitizePointMatch->setChecked(true);
3858 slotDigitizePointMatch(); // Call the slot that the setChecked call fails to trigger
3859 break;
3860
3861 case DIGITIZE_STATE_SEGMENT:
3862 m_actionDigitizeSegment->setChecked(true);
3863 slotDigitizeSegment(); // Call the slot that the setChecked call fails to trigger
3864 break;
3865
3866 case DIGITIZE_STATE_SELECT:
3867 m_actionDigitizeSelect->setChecked(true);
3868 slotDigitizeSelect(); // Call the slot that the setChecked call fails to trigger
3869 break;
3870
3871 default:
3872 LOG4CPP_ERROR_S ((*mainCat)) << "MainWindow::updateDigitizeStateIfSoftwareTriggered";
3873 break;
3874 }
3875}
3876
3878{
3879 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateGraphicsLinesToMatchGraphicsPoints";
3880
3882 m_transformation);
3883}
3884
3885void MainWindow::updateRecentFileList()
3886{
3887 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateRecentFileList";
3888
3889 QSettings settings (SETTINGS_ENGAUGE, SETTINGS_DIGITIZER);
3890 QStringList recentFilePaths = settings.value(SETTINGS_RECENT_FILE_LIST).toStringList();
3891
3892 // Determine the desired size of the path list
3893 unsigned int count = recentFilePaths.size();
3894 if (count > MAX_RECENT_FILE_LIST_SIZE) {
3895 count = MAX_RECENT_FILE_LIST_SIZE;
3896 }
3897
3898 // Add visible entries
3899 unsigned int i;
3900 for (i = 0; i < count; i++) {
3901 QString strippedName = QFileInfo (recentFilePaths.at(i)).fileName();
3902 m_actionRecentFiles.at (i)->setText (strippedName);
3903 m_actionRecentFiles.at (i)->setData (recentFilePaths.at (i));
3904 m_actionRecentFiles.at (i)->setVisible (true);
3905 }
3906
3907 // Hide any extra entries
3908 for (i = count; i < MAX_RECENT_FILE_LIST_SIZE; i++) {
3909 m_actionRecentFiles.at (i)->setVisible (false);
3910 }
3911}
3912
3914{
3915 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateSettingsAxesChecker";
3916
3917 m_cmdMediator->document().setModelAxesChecker(modelAxesChecker);
3918 if (m_transformation.transformIsDefined()) {
3919 m_transformationStateContext->triggerStateTransition(TRANSFORMATION_STATE_DEFINED,
3920 *m_cmdMediator,
3921 m_transformation,
3922 m_cmbCurve->currentText());
3923 } else {
3924 m_transformationStateContext->triggerStateTransition(TRANSFORMATION_STATE_UNDEFINED,
3925 *m_cmdMediator,
3926 m_transformation,
3927 m_cmbCurve->currentText());
3928 }
3929}
3930
3932{
3933 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateSettingsColorFilter";
3934
3935 m_cmdMediator->document().setModelColorFilter(modelColorFilter);
3936 m_backgroundStateContext->updateColorFilter (m_transformation,
3937 m_cmdMediator->document().modelGridRemoval(),
3938 modelColorFilter);
3939 m_digitizeStateContext->handleCurveChange (m_cmdMediator);
3941}
3942
3944{
3945 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateSettingsCoords";
3946
3947 m_cmdMediator->document().setModelCoords(modelCoords);
3948}
3949
3951{
3952 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateSettingsCurveAddRemove";
3953
3954 m_cmdMediator->document().setCurvesGraphs (curvesGraphs);
3955 loadCurveListFromCmdMediator();
3957}
3958
3960{
3961 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateSettingsCurveStyles";
3962
3963 m_scene->updateCurveStyles(modelCurveStyles);
3964 m_cmdMediator->document().setModelCurveStyles(modelCurveStyles);
3966}
3967
3969{
3970 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateSettingsDigitizeCurve";
3971
3972 m_cmdMediator->document().setModelDigitizeCurve(modelDigitizeCurve);
3973 m_digitizeStateContext->updateModelDigitizeCurve (m_cmdMediator,
3974 modelDigitizeCurve);
3975}
3976
3978{
3979 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateSettingsExportFormat";
3980
3981 m_cmdMediator->document().setModelExport (modelExport);
3982}
3983
3985{
3986 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateSettingsGeneral";
3987
3988 m_cmdMediator->document().setModelGeneral(modelGeneral);
3989}
3990
3992{
3993 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateSettingsGridRemoval";
3994
3995 m_cmdMediator->document().setModelGridRemoval(modelGridRemoval);
3996}
3997
3998void MainWindow::updateSettingsMainWindow()
3999{
4000 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateSettingsMainWindow";
4001
4002 if (m_modelMainWindow.zoomControl() == ZOOM_CONTROL_MENU_ONLY ||
4003 m_modelMainWindow.zoomControl() == ZOOM_CONTROL_MENU_WHEEL) {
4004
4005 m_actionZoomIn->setShortcut (tr (""));
4006 m_actionZoomOut->setShortcut (tr (""));
4007
4008 } else {
4009
4010 m_actionZoomIn->setShortcut (tr ("+"));
4011 m_actionZoomOut->setShortcut (tr ("-"));
4012
4013 }
4014
4015 updateWindowTitle();
4016}
4017
4019{
4020 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateSettingsMainWindow";
4021
4022 m_modelMainWindow = modelMainWindow;
4024}
4025
4027{
4028 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateSettingsPointMatch";
4029
4030 m_cmdMediator->document().setModelPointMatch(modelPointMatch);
4031}
4032
4034{
4035 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateSettingsSegments";
4036
4037 m_cmdMediator->document().setModelSegments(modelSegments);
4038 m_digitizeStateContext->updateModelSegments(modelSegments);
4039}
4040
4041void MainWindow::updateTransformationAndItsDependencies()
4042{
4043 m_transformation.update (!m_currentFile.isEmpty (),
4044 *m_cmdMediator,
4045 m_modelMainWindow);
4046
4047 // Grid removal is affected by new transformation
4048 m_backgroundStateContext->setCurveSelected (m_transformation,
4049 m_cmdMediator->document().modelGridRemoval(),
4050 m_cmdMediator->document().modelColorFilter(),
4051 m_cmbCurve->currentText ());
4052}
4053
4054void MainWindow::updateViewedCurves ()
4055{
4056 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateViewedCurves";
4057
4058 if (m_actionViewCurvesAll->isChecked ()) {
4059
4060 m_scene->showCurves (true, true);
4061
4062 } else if (m_actionViewCurvesSelected->isChecked ()) {
4063
4064 m_scene->showCurves (true, false, selectedGraphCurve ());
4065
4066 } else if (m_actionViewCurvesNone->isChecked ()) {
4067
4068 m_scene->showCurves (false);
4069
4070 } else {
4071 ENGAUGE_ASSERT (false);
4072 }
4073}
4074
4076{
4077 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateViewsOfSettings";
4078
4079 QString activeCurve = m_digitizeStateContext->activeCurve ();
4080
4081 updateViewsOfSettings (activeCurve);
4082}
4083
4084void MainWindow::updateViewsOfSettings (const QString &activeCurve)
4085{
4086 if (activeCurve.isEmpty ()) {
4087
4088 m_viewPointStyle->unsetPointStyle ();
4089 m_viewSegmentFilter->unsetColorFilterSettings ();
4090
4091
4092 } else {
4093
4094 PointStyle pointStyle = m_cmdMediator->document().modelCurveStyles().curveStyle(activeCurve).pointStyle();
4095 m_viewPointStyle->setPointStyle (pointStyle);
4096
4097 ColorFilterSettings colorFilterSettings = m_cmdMediator->document().modelColorFilter().colorFilterSettings(activeCurve);
4098 m_viewSegmentFilter->setColorFilterSettings (colorFilterSettings,
4099 m_cmdMediator->pixmap ());
4100
4101 }
4102}
4103
4104void MainWindow::updateWindowTitle ()
4105{
4106 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::updateWindowTitle";
4107
4108 const QString PLACEHOLDER ("[*]");
4109
4110 QString title = QString (tr ("Engauge Digitizer %1")
4111 .arg (VERSION_NUMBER));
4112
4113 QString fileNameMaybeStripped;
4114 if (!m_currentFileWithPathAndFileExtension.isEmpty()) {
4115
4116 QFileInfo fileInfo (m_currentFileWithPathAndFileExtension);
4117
4118 switch (m_modelMainWindow.mainTitleBarFormat())
4119 {
4120 case MAIN_TITLE_BAR_FORMAT_NO_PATH:
4121 fileNameMaybeStripped = fileInfo.baseName(); // Remove file extension and path for "clean look"
4122 break;
4123
4124 case MAIN_TITLE_BAR_FORMAT_PATH:
4125 fileNameMaybeStripped = m_currentFileWithPathAndFileExtension;
4126 break;
4127 }
4128
4129 title += QString (": %1")
4130 .arg (fileNameMaybeStripped);
4131 }
4132
4133 // To prevent "QWidget::setWindowModified: The window title does not contain a [*] placeholder" warnings,
4134 // we always append a placeholder
4135 title += PLACEHOLDER;
4136
4137 setWindowTitle (title);
4138}
4139
4141{
4142 ENGAUGE_CHECK_PTR (m_view);
4143 return *m_view;
4144}
4145
4147{
4148 ENGAUGE_CHECK_PTR (m_view);
4149 return *m_view;
4150}
4151
4152void MainWindow::writeCheckpointToLogFile ()
4153{
4154 // Document
4155 QString checkpointDoc;
4156 QTextStream strDoc (&checkpointDoc);
4157 m_cmdMediator->document().printStream(INDENTATION_PAST_TIMESTAMP,
4158 strDoc);
4159
4160 // Scene
4161 QString checkpointScene;
4162 QTextStream strScene (&checkpointScene);
4163 m_scene->printStream (INDENTATION_PAST_TIMESTAMP,
4164 strScene);
4165
4166 // Skip slow string manipulation if BEFORE call to LOG4CPP_DEBUG_S
4167 if (mainCat->getPriority() == log4cpp::Priority::DEBUG) {
4168
4169 LOG4CPP_DEBUG_S ((*mainCat)) << "MainWindow::writeCheckpointToLogFile\n"
4170 << "--------------DOCUMENT CHECKPOINT START----------" << "\n"
4171 << checkpointDoc.toLatin1().data()
4172 << "---------------DOCUMENT CHECKPOINT END-----------" << "\n"
4173 << "----------------SCENE CHECKPOINT START-----------" << "\n"
4174 << checkpointScene.toLatin1().data()
4175 << "-----------------SCENE CHECKPOINT END------------" ;
4176 }
4177}
Context class that manages the background image state machine.
void updateColorFilter(const Transformation &transformation, const DocumentModelGridRemoval &modelGridRemoval, const DocumentModelColorFilter &colorFilter)
Apply color filter settings.
void setBackgroundImage(BackgroundImage backgroundImage)
Transition to the specified state. This method is used by classes outside of the state machine to tri...
QImage imageForCurveState() const
Image for the Curve state, even if the current state is different.
void fitInView(GraphicsView &view)
Zoom so background fills the window.
void setCurveSelected(const Transformation &transformation, const DocumentModelGridRemoval &modelGridRemoval, const DocumentModelColorFilter &modelColorFilter, const QString &curveSelected)
Update the selected curve.
void close()
Open Document is being closed so remove the background.
void setPixmap(const Transformation &transformation, const DocumentModelGridRemoval &modelGridRemoval, const DocumentModelColorFilter &modelColorFilter, const QPixmap &pixmapOriginal)
Update the images of all states, rather than just the current state.
Wizard for setting up the checklist guide.
QStringList curveNames(CoordSystemIndex coordSystemIndex) const
Curve names to be placed into Document.
QString templateHtml(CoordSystemIndex coordSystemIndex) const
Template html comprising the checklist for display.
void populateCurvesGraphs(CoordSystemIndex coordSystemIndex, CurvesGraphs &curvesGraphs)
Create entries in CurvesGraphs for each curve name that user provided.
Dockable text window containing checklist guide.
bool browserIsEmpty() const
When browser is empty, it is pointless to show it.
void setTemplateHtml(const QString &html, const QStringList &curveNames)
Populate the browser with template html.
void update(const CmdMediator &cmdMediator, bool documentIsExported)
Update using current CmdMediator/Document state.
Command for moving all selected Points by a specified translation.
Definition CmdCopy.h:19
Command for cutting all selected Points.
Definition CmdCut.h:19
Command for deleting all selected Points.
Definition CmdDelete.h:19
Command queue stack.
Definition CmdMediator.h:24
QString reasonForUnsuccessfulRead() const
See Document::reasonForUnsuccessfulRead.
QPixmap pixmap() const
See Document::pixmap.
bool isModified() const
Dirty flag.
void saveXml(QXmlStreamWriter &writer) const
Serialize to xml.
QStringList curvesGraphsNames() const
See CurvesGraphs::curvesGraphsNames.
bool successfulRead() const
Wrapper for Document::successfulRead.
void setDocumentAxesPointsRequired(DocumentAxesPointsRequired documentAxesPointsRequired)
Set the number of axes points required.
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Command for changing the currently selected CoordSystem.
Command stack that shadows the CmdMediator command stack at startup when reading commands from an err...
bool canRedo() const
Return true if there is a command available.
void slotRedo()
Move next command from list to CmdMediator. Noop if there are no more commands.
void loadCommands(MainWindow &mainWindow, Document &document, QXmlStreamReader &reader)
Load commands from serialized xml.
Color filter parameters for one curve. For a class, this is handled the same as LineStyle and PointSt...
PointStyle pointStyle() const
Get method for PointStyle.
Model for DlgSettingsCurveProperties and CmdSettingsCurveProperties.
Definition CurveStyles.h:23
CurveStyle curveStyle(const QString &curveName) const
CurveStyle in specified curve.
Container for all graph curves. The axes point curve is external to this class.
Container for all DigitizeStateAbstractBase subclasses. This functions as the context class in a stan...
void resetOnLoad(CmdMediator *cmdMediator)
Resetting makes re-initializes for documents after the first.
void handleMouseRelease(CmdMediator *cmdMediator, QPointF pos)
See DigitizeStateAbstractBase::handleMouseRelease.
void handleContextMenuEvent(CmdMediator *cmdMediator, const QString &pointIdentifier)
See DigitizeStateAbstractBase::handleContextMenuEvent.
void handleMouseMove(CmdMediator *cmdMediator, QPointF pos)
See DigitizeStateAbstractBase::handleMouseMove.
void requestImmediateStateTransition(CmdMediator *cmdMediator, DigitizeState digitizeState)
Perform immediate state transition. Called from outside state machine.
void updateModelDigitizeCurve(CmdMediator *cmdMediator, const DocumentModelDigitizeCurve &modelDigitizeCurve)
Update the digitize curve settings.
void handleMousePress(CmdMediator *cmdMediator, QPointF pos)
See DigitizeStateAbstractBase::handleMousePress.
void appendNewCmd(CmdMediator *cmdMediator, QUndoCommand *cmd)
Append just-created QUndoCommand to command stack. This is called from DigitizeStateAbstractBase subc...
void handleSetOverrideCursor(CmdMediator *cmdMediator, const QCursor &cursor)
See DigitizeStateAbstractBase::handleSetOverrideCursor.
void setImageIsLoaded(CmdMediator *cmdMediator, bool imageIsLoaded)
Set the image so QGraphicsView cursor and drag mode are accessible.
QString activeCurve() const
Curve name for active Curve. This can include AXIS_CURVE_NAME, and empty string.
void handleKeyPress(CmdMediator *cmdMediator, Qt::Key key, bool atLeastOneSelectedItem)
See DigitizeStateAbstractBase::handleKeyPress.
void updateModelSegments(const DocumentModelSegments &modelSegments)
Update the segments given the new settings.
void handleCurveChange(CmdMediator *cmdMediator)
See DigitizeStateAbstractBase::handleCurveChange.
void handleLeave(CmdMediator *cmdMediator)
See DigitizeStateAbstractBase::handleLeave.
About Engauge dialog. This provides a hidden shortcut for triggering ENGAUGE_ASSERT.
Definition DlgAbout.h:16
Dialog for sending error report.
QString xmlToUpload() const
Xml to be uploaded. Includes document if user has approved.
Dialog for setting the advanced parameters in a newly imported Document.
Dialog to be displayed whenever some operation or processing cannot be performed since the axis point...
Dialog for editing axes checker settings.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
Dialog for editing filtering settings.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
Dialog for editing coordinates settings.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
Dialog for editing curve names settings.
void load(CmdMediator &cmdMediator)
Load settings from Document.
Dialog for editing curve properties settings.
void setCurveName(const QString &curveName)
Load information for the specified curve name. When called externally, the load method must have been...
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
Dialog for editing DigitizeStateCurve settings.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
Dialog for editing exporting settings.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
Dialog for editing general settings.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
Dialog for editing grid removal settings.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
Dialog for editing main window settings, which are entirely independent of all documents.
void loadMainWindowModel(CmdMediator &cmdMediator, const MainWindowModel &modelMainWindow)
Replaced load method since the main window settings are independent of document, unlike other DlgSett...
Dialog for editing point match settings, for DigitizeStatePointMatch.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
Dialog for editing Segments settings, for DigitizeStateSegment.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
Model for DlgSettingsAxesChecker and CmdSettingsAxesChecker.
Model for DlgSettingsColorFilter and CmdSettingsColorFilter.
const ColorFilterSettings colorFilterSettings(const QString &curveName) const
Get method for copying one color filter. Cannot return just a reference or else there is a warning ab...
Model for DlgSettingsCoords and CmdSettingsCoords.
Model for DlgSettingsDigitizeCurve and CmdSettingsDigitizeCurve.
Model for DlgSettingsExportFormat and CmdSettingsExportFormat.
void setDelimiter(ExportDelimiter exportDelimiter)
Set method for delimiter.
Model for DlgSettingsGeneral and CmdSettingsGeneral.
Model for DlgSettingsGridRemoval and CmdSettingsGridRemoval. The settings are unstable until the user...
Model for DlgSettingsPointMatch and CmdSettingsPointMatch.
Model for DlgSettingsSegments and CmdSettingsSegments.
unsigned int coordSystemCount() const
Number of CoordSystem.
Definition Document.cpp:270
void setModelGridRemoval(const DocumentModelGridRemoval &modelGridRemoval)
Set method for DocumentModelGridRemoval.
Definition Document.cpp:877
void setCoordSystemIndex(CoordSystemIndex coordSystemIndex)
Set the index of current active CoordSystem.
Definition Document.cpp:777
void printStream(QString indentation, QTextStream &str) const
Debugging method that supports print method of this class and printStream method of some other class(...
Definition Document.cpp:706
CoordSystemIndex coordSystemIndex() const
Index of current active CoordSystem.
Definition Document.cpp:277
void setModelPointMatch(const DocumentModelPointMatch &modelPointMatch)
Set method for DocumentModelPointMatch.
Definition Document.cpp:884
void setModelCurveStyles(const CurveStyles &modelCurveStyles)
Set method for CurveStyles.
Definition Document.cpp:839
void addCoordSystems(unsigned int numberCoordSystemToAdd)
Add some number (0 or more) of additional coordinate systems.
Definition Document.cpp:138
void setModelColorFilter(const DocumentModelColorFilter &modelColorFilter)
Set method for DocumentModelColorFilter.
Definition Document.cpp:814
void setModelDigitizeCurve(const DocumentModelDigitizeCurve &modelDigitizeCurve)
Set method for DocumentModelDigitizeCurve.
Definition Document.cpp:856
void saveXml(QXmlStreamWriter &writer) const
Save document to xml.
Definition Document.cpp:748
DocumentModelAxesChecker modelAxesChecker() const
Get method for DocumentModelAxesChecker.
Definition Document.cpp:597
DocumentModelColorFilter modelColorFilter() const
Get method for DocumentModelColorFilter.
Definition Document.cpp:604
void setCurvesGraphs(const CurvesGraphs &curvesGraphs)
Let CmdAbstract classes overwrite CurvesGraphs.
Definition Document.cpp:784
CurveStyles modelCurveStyles() const
Get method for CurveStyles.
Definition Document.cpp:618
void setModelCoords(const DocumentModelCoords &modelCoords)
Set method for DocumentModelCoords.
Definition Document.cpp:832
void setModelAxesChecker(const DocumentModelAxesChecker &modelAxesChecker)
Set method for DocumentModelAxesChecker.
Definition Document.cpp:807
void setModelSegments(const DocumentModelSegments &modelSegments)
Set method for DocumentModelSegments.
Definition Document.cpp:891
void setModelGeneral(const DocumentModelGeneral &modelGeneral)
Set method for DocumentModelGeneral.
Definition Document.cpp:870
void setModelExport(const DocumentModelExportFormat &modelExport)
Set method for DocumentModelExportFormat.
Definition Document.cpp:863
DocumentModelGridRemoval modelGridRemoval() const
Get method for DocumentModelGridRemoval.
Definition Document.cpp:646
DocumentModelExportFormat modelExport() const
Get method for DocumentModelExportFormat.
Definition Document.cpp:632
Strategy class for exporting to a file. This strategy is external to the Document class so that class...
QString filterTsv() const
QFileDialog filter for TSV files.
QString filterCsv() const
QFileDialog filter for CSV files.
void exportToFile(const DocumentModelExportFormat &modelExport, const Document &document, const MainWindowModel &modelMainWindow, const Transformation &transformation, QTextStream &str) const
Export Document points according to the settings.
QString fileExtensionTsv() const
File extension for tsv export files.
QString fileExtensionCsv() const
File extension for csv export files.
File that manages a command stack for regression testing of file import/open/export/close.
bool canRedo() const
Returns true if there is at least one command on the stack.
void redo(MainWindow &mainWindow)
Apply the next command. Requires non-empty stack.
Class for showing points and lines for all coordinate systems simultaneously, even though the code no...
Definition Ghosts.h:27
unsigned int coordSystemIndexToBeRestored() const
Coordinate system index that was active before the ghosts.
Definition Ghosts.cpp:73
void createGhosts(QGraphicsScene &scene)
Create ghosts from the path/rect/polygon lists.
Definition Ghosts.cpp:78
void captureGraphicsItems(QGraphicsScene &scene)
Take a snapshot of the graphics items.
Definition Ghosts.cpp:26
void destroyGhosts(QGraphicsScene &scene)
Destory ghosts. Called at end of algorithm.
Definition Ghosts.cpp:119
Add point and line handling to generic QGraphicsScene.
void updateGraphicsLinesToMatchGraphicsPoints(const CurveStyles &modelCurveStyles, const Transformation &transformation)
A mouse move has just occurred so move the selected points, since they were dragged.
void resetOnLoad()
Reset, when loading a document after the first, to same state that first document was at when loaded.
void updateAfterCommand(CmdMediator &cmdMediator)
Update the Points and their Curves after executing a command.
QStringList selectedPointIdentifiers() const
Return a list of identifiers for the currently selected points.
void showCurves(bool show, bool showAll=false, const QString &curveName="")
Show or hide all Curves (if showAll is true) or just the selected Curve (if showAll is false);.
void resetPositionHasChangedFlags()
Reset positionHasChanged flag for all items. Typically this is done as part of mousePressEvent.
void printStream(QString indentation, QTextStream &str)
Debugging method that supports print method of this class and printStream method of some other class(...
void updateCurveStyles(const CurveStyles &modelCurveStyles)
Update curve styles after settings changed.
QGraphicsView class with event handling added. Typically the events are sent to the active digitizing...
Dockable help window.
Definition HelpWindow.h:14
Wrapper around OpenJPEG library, in C, for opening jpeg2000 files.
Definition Jpeg2000.h:27
QStringList supportedImageWildcards() const
List the supported jpeg2000 file extensions, for filtering import files.
Definition Jpeg2000.cpp:305
bool load(const QString &filename, QImage &image) const
Load image from jpeg2000 file.
Definition Jpeg2000.cpp:192
Returns information about files.
bool loadsAsDigFile(const QString &urlString) const
Returns true if specified file name can be loaded as a DIG file.
Load QImage from url. This is trivial for a file, but requires an asynchronous download step for http...
void startLoadImage(const QUrl &url)
Start the asynchronous loading of an image from the specified url.
static void bindToMainWindow(const MainWindow *mainWindow)
Bind to MainWindow so this class can access the command stack.
Model for DlgSettingsMainWindow.
QLocale locale() const
Get method for locale.
ZoomFactorInitial zoomFactorInitial() const
Get method for initial zoom factor.
void setMainTitleBarFormat(MainTitleBarFormat mainTitleBarFormat)
Set method for MainWindow titlebar filename format.
void setZoomControl(ZoomControl zoomControl)
Set method for zoom control.
ZoomControl zoomControl() const
Get method for zoom control.
void setZoomFactorInitial(ZoomFactorInitial zoomFactorInitial)
Set method for initial zoom factor.
MainTitleBarFormat mainTitleBarFormat() const
Get method for MainWindow titlebar filename format.
void setLocale(QLocale::Language language, QLocale::Country country)
Set method for locale given attributes.
void updateSettingsGridRemoval(const DocumentModelGridRemoval &modelGridRemoval)
Update with new grid removal properties.
void showTemporaryMessage(const QString &temporaryMessage)
Show temporary message in status bar.
CmdMediator * cmdMediator()
Accessor for commands to process the Document.
virtual bool eventFilter(QObject *, QEvent *)
Catch secret keypresses.
void updateSettingsAxesChecker(const DocumentModelAxesChecker &modelAxesChecker)
Update with new axes indicator properties.
virtual void showEvent(QShowEvent *)
Processing performed after gui becomes available.
void updateSettingsDigitizeCurve(const DocumentModelDigitizeCurve &modelDigitizeCurve)
Update with new curve digitization styles.
bool isGnuplot() const
Get method for gnuplot flag.
void updateSettingsCurveStyles(const CurveStyles &modelCurveStyles)
Update with new curve styles.
bool transformIsDefined() const
Return true if all three axis points have been defined.
MainWindowModel modelMainWindow() const
Get method for main window model.
void cmdFileOpen(const QString &fileName)
Open file. This is called from a file script command.
void updateAfterCommand()
See GraphicsScene::updateAfterCommand.
void updateSettingsExportFormat(const DocumentModelExportFormat &modelExport)
Update with new export properties.
void updateSettingsSegments(const DocumentModelSegments &modelSegments)
Update with new segments properties.
BackgroundImage selectOriginal(BackgroundImage backgroundImage)
Make original background visible, for DigitizeStateColorPicker.
void updateSettingsCurveAddRemove(const CurvesGraphs &curvesGraphs)
Update with new curves.
void saveErrorReportFileAndExit(const char *comment, const char *file, int line, const char *context) const
Save error report and exit.
void cmdFileExport(const QString &fileName)
Export file. This is called from a file script command.
void updateViewsOfSettings(const QString &activeCurve)
Update curve-specific view of settings. Private version gets active curve name from DigitizeStateCont...
void updateSettingsMainWindow(const MainWindowModel &modelMainWindow)
Update with new main window properties.
void cmdFileClose()
Close file. This is called from a file script command.
void updateDigitizeStateIfSoftwareTriggered(DigitizeState digitizeState)
After software-triggered state transition, this method manually triggers the action as if user had cl...
void updateSettingsGeneral(const DocumentModelGeneral &modelGeneral)
Update with new general properties.
void signalZoom(int)
Send zoom selection, picked from menu or keystroke, to StatusBar.
void updateSettingsPointMatch(const DocumentModelPointMatch &modelPointMatch)
Update with new point match properties.
void cmdFileImport(const QString &fileName)
Import file. This is called from a file script command.
void updateGraphicsLinesToMatchGraphicsPoints()
Update the graphics lines so they follow the graphics points, after a drag, addition,...
MainWindow(const QString &errorReportFile, const QString &fileCmdScriptFile, bool isRegressionTest, bool isGnuplot, QStringList loadStartupFiles, QWidget *parent=0)
Single constructor.
QImage imageFiltered() const
Background image that has been filtered for the current curve. This asserts if a curve-specific image...
QString selectedGraphCurve() const
Curve name that is currently selected in m_cmbCurve.
GraphicsScene & scene()
Scene container for the QImage and QGraphicsItems.
void updateAfterMouseRelease()
Call MainWindow::updateControls (which is private) after the very specific case - a mouse press/relea...
void resizeEvent(QResizeEvent *event)
Intercept resize event so graphics scene can be appropriately resized when in Fill mode.
Transformation transformation() const
Return read-only copy of transformation.
void updateSettingsColorFilter(const DocumentModelColorFilter &modelColorFilter)
Update with new color filter properties.
void updateCoordSystem(CoordSystemIndex coordSystemIndex)
Select a different CoordSystem.
void updateSettingsCoords(const DocumentModelCoords &modelCoords)
Update with new coordinate properties.
GraphicsView & view()
View for the QImage and QGraphicsItems, without const.
Client for interacting with Engauge server.
void uploadErrorReport(const QString &report)
Upload the error report asynchronously.
Details for a specific Point.
Definition PointStyle.h:21
Wrapper around QStatusBar to manage permanent widgets.
Definition StatusBar.h:22
void wakeUp()
Enable all widgets in the status bar. This is called just after a Document becomes active.
void setStatusBarMode(StatusBarMode statusBarMode)
Set the status bar visibility mode.
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.
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...
Context class for transformation state machine.
void triggerStateTransition(TransformationState transformationState, CmdMediator &cmdMediator, const Transformation &transformation, const QString &selectedGraphCurve)
Trigger a state transition to be performed immediately.
void resetOnLoad()
Reset, when loading a document after the first, to same state that first document was at when loaded.
void updateAxesChecker(CmdMediator &cmdMediator, const Transformation &transformation)
Apply the new DocumentModelAxesChecker.
Affine transformation between screen and graph coordinates, based on digitized axis points.
void coordTextForStatusBar(QPointF cursorScreen, QString &coordsScreen, QString &coordsGraph, QString &resolutionGraph)
Return string descriptions of cursor coordinates for status bar.
void resetOnLoad()
Reset, when loading a document after the first, to same state that first document was at when loaded.
bool transformIsDefined() const
Transform is defined when at least three axis points have been digitized.
void update(bool fileIsLoaded, const CmdMediator &cmdMediator, const MainWindowModel &modelMainWindow)
Update transform by iterating through the axis points.
Tutorial using a strategy like a comic strip with decision points deciding which panels appear.
Definition TutorialDlg.h:20
Class that displays a view of the current Curve's point style.
void unsetPointStyle()
Apply no PointStyle.
void setPointStyle(const PointStyle &pointStyle)
Apply the PointStyle of the currently selected curve.
void setEnabled(bool enabled)
Show the style with semi-transparency or full-transparency to indicate if associated Curve is active ...
Class that displays the current Segment Filter in a MainWindow toolbar.
void unsetColorFilterSettings()
Apply no color filter.
void setColorFilterSettings(const ColorFilterSettings &colorFilterSettings, const QPixmap &pixmap)
Apply the color filter of the currently selected curve. The pixmap is included so the background colo...
void setEnabled(bool enabled)
Show the style with semi-transparency or full-transparency to indicate if associated Curve is active ...