1 /*******************************************************************************
2 **
3 ** Photivo
4 **
5 ** Copyright (C) 2008,2009 Jos De Laender <jos.de_laender@telenet.be>
6 ** Copyright (C) 2009-2011 Michael Munzert <mail@mm-log.com>
7 ** Copyright (C) 2013 Alexander Tzyganenko <tz@fast-report.com>
8 **
9 ** This file is part of Photivo.
10 **
11 ** Photivo is free software: you can redistribute it and/or modify
12 ** it under the terms of the GNU General Public License version 3
13 ** as published by the Free Software Foundation.
14 **
15 ** Photivo is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ** GNU General Public License for more details.
19 **
20 ** You should have received a copy of the GNU General Public License
21 ** along with Photivo. If not, see <http://www.gnu.org/licenses/>.
22 **
23 *******************************************************************************/
24
25 #include "ptDefines.h"
26 #include "ptConfirmRequest.h"
27 #include "ptConstants.h"
28 #include "ptError.h"
29 #include "ptGuiOptions.h"
30 #include "ptMainWindow.h"
31 #include "ptMessageBox.h"
32 #include "ptSettings.h"
33 #include "ptTheme.h"
34 #include "ptViewWindow.h"
35 #include "ptWhiteBalances.h"
36
37 #include "filters/ptFilterDM.h"
38 #include "filters/ptFilterBase.h"
39 #include "ptToolBox.h"
40
41 #ifdef Q_OS_WIN
42 #include "ptEcWin7.h"
43 #endif
44
45 #include <QDesktopWidget>
46 #include <QFileDialog>
47
48 #include <iomanip>
49 #include <iostream>
50 #include <cassert>
51
52 using namespace std;
53
54 extern ptTheme* Theme;
55 extern ptViewWindow* ViewWindow;
56 extern QString ImageFileToOpen;
57 extern QString PtsFileToOpen;
58 extern short ImageCleanUp;
59
60 void CB_MenuFileOpen(const short HaveFile);
61 void CB_OpenSettingsFile(QString SettingsFileName);
62 void CB_OpenFileButton();
63 void CB_ZoomStep(int direction);
64 void ReadSidecar(const QString& Sidecar);
65
66 // undo-redo & clipboard support
67 void ptMakeUndo();
68 void ptMakeRedo();
69 void ptClearUndoRedo();
70 void ptMakeFullUndo();
71 void ptResetSettingsToDefault();
72 void ptCopySettingsToClipboard();
73 void ptPasteSettingsFromClipboard();
74
75
76 ////////////////////////////////////////////////////////////////////////////////
77 //
78 // Here follow a bunch of macro's to avoid repetitive code for lots of
79 // the Gui elements.
80 //
81 ////////////////////////////////////////////////////////////////////////////////
82
83 // Connect a menu action.
84
85 // Must be bool for the checkable menu items !
86 #define Macro_ConnectSomeMenu(Some) \
87 connect( action ## Some,SIGNAL(triggered(bool)), \
88 this,SLOT(On ## Some ## Triggered(bool)));
89
90 // Connect a button.
91
92 #define Macro_ConnectSomeButton(Some) \
93 connect(Some ## Button,SIGNAL(clicked()), \
94 this,SLOT(On ## Some ## ButtonClicked()));
95
96 // Callback into main for a menu item activated.
97
98 #define Macro_OnSomeMenuActivated(Some) \
99 void CB_Menu ## Some(const short Enabled); \
100 void ptMainWindow::On ## Some ## Triggered(const bool Enabled) { \
101 ::CB_Menu ## Some(Enabled); \
102 }
103
104 // Leftover from removing the menu
105 void CB_MenuFileExit(const short);
106
107 // Prototype
108 void Update(short Phase,
109 short SubPhase = -1,
110 short WithIdentify = 1,
111 short ProcessorMode = ptProcessorMode_Preview);
112
113 void Update(const QString GuiName);
114
115 //==============================================================================
116
ptMainWindow(const QString Title)117 ptMainWindow::ptMainWindow(const QString Title)
118 : QMainWindow(NULL)
119 {
120 FUIState = uisNone;
121
122 // Setup from the Gui builder.
123 setupUi(this);
124 setWindowTitle(Title);
125
126 // Initialize Win 7 taskbar features
127 #ifdef Q_OS_WIN
128 ptEcWin7::CreateInstance(this);
129 #endif
130
131 // Move the fullscreen button in the zoom bar a bit to the left
132 // to make space for the Mac window resize handle
133 #ifdef Q_OS_MAC
134 MacSpacer->setFixedWidth(16);
135 #endif
136
137 MainSplitter->setStretchFactor(1,1);
138 ViewSplitter->setStretchFactor(0,1);
139
140 // Some corrections that often go wrong in the manual
141 // layout using the designer.
142
143 QList <QVBoxLayout *> VBoxes = MainTabBook->findChildren <QVBoxLayout *> ();
144 for (short i=0; i<VBoxes.size(); i++) {
145 VBoxes[i]->setMargin(2);
146 VBoxes[i]->setContentsMargins(2,2,2,2);
147 }
148
149 // Initial value. We remember locally for the case that a
150 // a new photograph is from another camera. This is then detected
151 // for other whitebalances.
152 m_CameraMake = Settings->GetString("CameraMake");
153 m_CameraModel = Settings->GetString("CameraModel");
154
155 // Go and construct all the input,choice .. gui elements.
156 const QStringList Keys = Settings->GetKeys();
157 for (int i=0; i<Keys.size(); i++) {
158 const QString Key = Keys[i];
159 //printf("(%s,%d) '%s'\n",__FILE__,__LINE__,Key.toLocal8Bit().data());
160 switch (Settings->GetGuiType(Key)) {
161
162 case ptGT_InputSlider :
163 case ptGT_Input :
164 //printf("(%s,%d) Creating Input for '%s'\n",
165 // __FILE__,__LINE__,Key.toLocal8Bit().data());
166 {
167 QString ParentName = Key + "Widget";
168 QString ObjectName = Key + "Input";
169 ptInput* Input =
170 new ptInput(this,
171 ObjectName,
172 ParentName,
173 Settings->GetGuiType(Key) == ptGT_InputSlider,
174 0,
175 Settings->GetHasDefaultValue(Key),
176 Settings->GetDefaultValue(Key),
177 Settings->GetMinimumValue(Key),
178 Settings->GetMaximumValue(Key),
179 Settings->GetStep(Key),
180 Settings->GetNrDecimals(Key),
181 Settings->GetLabel(Key),
182 Settings->GetToolTip(Key),
183 ptTimeout_Input);
184 connect(Input,SIGNAL(valueChanged(QVariant)),
185 this,SLOT(OnInputChanged(QVariant)));
186 //m_GuiInputs[ObjectName] = Input;
187 Settings->SetGuiInput(Key,Input);
188 }
189 break;
190 case ptGT_InputSliderHue :
191 //printf("(%s,%d) Creating Input for '%s'\n",
192 // __FILE__,__LINE__,Key.toLocal8Bit().data());
193 {
194 QString ParentName = Key + "Widget";
195 QString ObjectName = Key + "Input";
196 ptInput* Input =
197 new ptInput(this,
198 ObjectName,
199 ParentName,
200 1,
201 1,
202 Settings->GetHasDefaultValue(Key),
203 Settings->GetDefaultValue(Key),
204 Settings->GetMinimumValue(Key),
205 Settings->GetMaximumValue(Key),
206 Settings->GetStep(Key),
207 Settings->GetNrDecimals(Key),
208 Settings->GetLabel(Key),
209 Settings->GetToolTip(Key),
210 ptTimeout_Input);
211 connect(Input,SIGNAL(valueChanged(QVariant)),
212 this,SLOT(OnInputChanged(QVariant)));
213 //m_GuiInputs[ObjectName] = Input;
214 Settings->SetGuiInput(Key,Input);
215 }
216 break;
217 case ptGT_Choice :
218 //printf("(%s,%d) Creating Choice for '%s'\n",
219 // __FILE__,__LINE__,Key.toLocal8Bit().data());
220 {
221 QString ParentName = Key + "Widget";
222 QString ObjectName = Key + "Choice";
223 ptChoice* Choice =
224 new ptChoice(this,
225 ObjectName,
226 ParentName,
227 Settings->GetHasDefaultValue(Key),
228 Settings->GetDefaultValue(Key),
229 Settings->GetInitialOptions(Key),
230 Settings->GetToolTip(Key),
231 ptTimeout_Input);
232 connect(Choice,SIGNAL(valueChanged(QVariant)),
233 this,SLOT(OnInputChanged(QVariant)));
234 //m_GuiChoices[ObjectName] = Choice;
235 Settings->SetGuiChoice(Key,Choice);
236 }
237 break;
238
239 case ptGT_Check :
240 //printf("(%s,%d) Creating Check for '%s'\n",
241 // __FILE__,__LINE__,Key.toLocal8Bit().data());
242 {
243 QString ParentName = Key + "Widget";
244 QString ObjectName = Key + "Check";
245 ptCheck* Check =
246 new ptCheck(this,
247 ObjectName,
248 ParentName,
249 Settings->GetDefaultValue(Key),
250 Settings->GetLabel(Key),
251 Settings->GetToolTip(Key));
252 connect(Check,SIGNAL(valueChanged(QVariant)),
253 this,SLOT(OnInputChanged(QVariant)));
254 //m_GuiChecks[ObjectName] = Check;
255 Settings->SetGuiCheck(Key,Check);
256 }
257 break;
258
259 default :
260 //printf("(%s,%d) No widget for '%s'\n",
261 // __FILE__,__LINE__,Key.toLocal8Bit().data());
262 continue;
263 };
264 // To sync the state of the now created gui element we have
265 // to set the value. As the setting now has the gui element
266 // attached, it will be updated.
267 Settings->SetValue(Key,Settings->GetValue(Key));
268 }
269
270 //
271 // Menu structure related.
272 //
273
274 // menu removed ;-)
275
276 // Leftover after menu was removed
277
278 m_GroupBox = NULL;
279 m_GroupBoxesOrdered = NULL;
280 m_TabLayouts = NULL;
281 m_MovedTools = new QList<QWidget*>;
282
283 // NOTE: Following function does the UI replacing and ptGroupBox creation.
284 // It also initializes new-style filters.
285 OnToolBoxesEnabledTriggered(0);
286
287 // Inserting new-style filters postponed to here because a fully functional m_TabLayouts
288 // is needed.
289 for (ptFilterBase *hFilter: *GFilterDM) {
290 m_TabLayouts->at(hFilter->parentTabIdx())->insertWidget(hFilter->idxInParentTab(),
291 hFilter->gui());
292 }
293
294 //
295 // Run pipe related
296 //
297
298 Macro_ConnectSomeButton(PreviewMode);
299 PreviewModeButton->setChecked(Settings->GetInt("PreviewMode"));
300
301 Macro_ConnectSomeButton(Run);
302 RunButton->setEnabled(Settings->GetInt("RunMode"));
303
304 Macro_ConnectSomeButton(TabProcessing);
305 Macro_ConnectSomeButton(TabSettings);
306 Macro_ConnectSomeButton(TabInfo);
307
308 //
309 // Zoom related
310 //
311
312 BottomContainer->setVisible(Settings->GetInt("ShowBottomContainer"));
313
314 Macro_ConnectSomeButton(ZoomFit);
315 Macro_ConnectSomeButton(ZoomIn);
316 Macro_ConnectSomeButton(ZoomOut);
317 Macro_ConnectSomeButton(ZoomFull);
318 Macro_ConnectSomeButton(Batch);
319 Macro_ConnectSomeButton(FileMgr);
320 Macro_ConnectSomeButton(FullScreen);
321 FullScreenButton->setChecked(0);
322 Macro_ConnectSomeButton(LoadStyle);
323 Macro_ConnectSomeButton(PreviousImage);
324 Macro_ConnectSomeButton(NextImage);
325
326
327 //
328 // Connect Export button (not only for Gimp like the name suggests)
329 //
330 Macro_ConnectSomeButton(ToGimp);
331
332 //
333 // Settings related
334 //
335
336 Macro_ConnectSomeButton(BackgroundColor);
337 QPixmap BgPix(80, 14);
338 QColor BgColor;
339 BgColor.setRed(Settings->GetInt("BackgroundRed"));
340 BgColor.setGreen(Settings->GetInt("BackgroundGreen"));
341 BgColor.setBlue(Settings->GetInt("BackgroundBlue"));
342 BgPix.fill(BgColor);
343 BackgroundColorButton->setIcon(BgPix);
344
345 Macro_ConnectSomeButton(Reset);
346
347 //
348 // TAB : Generic
349 //
350
351 Macro_ConnectSomeButton(CameraColorProfile);
352
353 Macro_ConnectSomeButton(PreviewColorProfile);
354
355 Macro_ConnectSomeButton(OutputColorProfile);
356
357 Macro_ConnectSomeButton(GimpExecCommand);
358
359 Macro_ConnectSomeButton(StartupSettings);
360
361 //
362 // TAB : Camera
363 //
364
365 Macro_ConnectSomeButton(OpenFile);
366 Macro_ConnectSomeButton(OpenSettingsFile);
367 Macro_ConnectSomeButton(OpenPresetFile);
368 Macro_ConnectSomeButton(SpotWB);
369
370 //
371 // TAB : Geometry
372 //
373
374 // TODO: BJ Unhide when lensfun implementation has grown far enough
375 widget_158->setVisible(false); //Camera
376 widget_159->setVisible(false); //Lens
377
378 Macro_ConnectSomeButton(RotateLeft);
379 Macro_ConnectSomeButton(RotateRight);
380 Macro_ConnectSomeButton(RotateAngle);
381 Macro_ConnectSomeButton(MakeCrop);
382 Macro_ConnectSomeButton(ConfirmCrop);
383 Macro_ConnectSomeButton(CancelCrop);
384 Macro_ConnectSomeButton(CropOrientation);
385 Macro_ConnectSomeButton(CropCenterHor);
386 Macro_ConnectSomeButton(CropCenterVert);
387
388 //
389 // TAB : Output
390 //
391
392 connect(TagsEditWidget, SIGNAL(textChanged()), this, SLOT(OnTagsEditTextChanged()));
393 connect(edtOutputSuffix, SIGNAL(editingFinished()), this, SLOT(Form_2_Settings()));
394 connect(edtImageTitle, SIGNAL(editingFinished()), this, SLOT(Form_2_Settings()));
395 connect(edtCopyright, SIGNAL(editingFinished()), this, SLOT(Form_2_Settings()));
396
397
398 Macro_ConnectSomeButton(OutputColorProfileReset);
399
400 Macro_ConnectSomeButton(WritePipe);
401
402 Settings->SetEnabled("OutputGamma",Settings->GetInt("OutputGammaCompensation"));
403 Settings->SetEnabled("OutputLinearity",Settings->GetInt("OutputGammaCompensation"));
404
405 if (Settings->GetInt("SaveFormat")==ptSaveFormat_JPEG)
406 Settings->SetEnabled("SaveSampling",1);
407 else
408 Settings->SetEnabled("SaveSampling",0);
409
410 if (Settings->GetInt("SaveFormat")==ptSaveFormat_JPEG ||
411 Settings->GetInt("SaveFormat")==ptSaveFormat_PNG||
412 Settings->GetInt("SaveFormat")==ptSaveFormat_PNG16)
413 Settings->SetEnabled("SaveQuality",1);
414 else
415 Settings->SetEnabled("SaveQuality",0);
416
417 // hide some stuff instead of removing from the code
418 findChild<ptGroupBox *>(QString("TabToolBoxControl"))->setVisible(0);
419 findChild<ptGroupBox *>(QString("TabMemoryTest"))->setVisible(0);
420 findChild<ptGroupBox *>(QString("TabRememberSettings"))->setVisible(0);
421
422 UpdateToolBoxes();
423
424 // Set help pages
425 dynamic_cast<ptGroupBox*>(m_GroupBox->value("TabWhiteBalance"))->
426 SetHelpUri("http://photivo.org/photivo/manual/tabs/camera#white_balance");
427
428 dynamic_cast<ptGroupBox*>(m_GroupBox->value("TabLensfunLensParameters"))->
429 SetHelpUri("http://photivo.org/photivo/manual/tabs/geometry#lens_parameters");
430 dynamic_cast<ptGroupBox*>(m_GroupBox->value("TabLensfunCA"))->
431 SetHelpUri("http://photivo.org/photivo/manual/tabs/geometry#chromatic_aberration");
432 dynamic_cast<ptGroupBox*>(m_GroupBox->value("TabLensfunVignette"))->
433 SetHelpUri("http://photivo.org/photivo/manual/tabs/geometry#vignetting");
434 dynamic_cast<ptGroupBox*>(m_GroupBox->value("TabLensfunDistortion"))->
435 SetHelpUri("http://photivo.org/photivo/manual/tabs/geometry#lens_distortion");
436 dynamic_cast<ptGroupBox*>(m_GroupBox->value("TabLensfunGeometry"))->
437 SetHelpUri("http://photivo.org/photivo/manual/tabs/geometry#geometry_conversion");
438 dynamic_cast<ptGroupBox*>(m_GroupBox->value("TabDefish"))->
439 SetHelpUri("http://photivo.org/photivo/manual/tabs/geometry#defish");
440 dynamic_cast<ptGroupBox*>(m_GroupBox->value("TabRotation"))->
441 SetHelpUri("http://photivo.org/photivo/manual/tabs/geometry#rotation_and_perspective");
442 dynamic_cast<ptGroupBox*>(m_GroupBox->value("TabCrop"))->
443 SetHelpUri("http://photivo.org/photivo/manual/tabs/geometry#crop");
444 dynamic_cast<ptGroupBox*>(m_GroupBox->value("TabLiquidRescale"))->
445 SetHelpUri("http://photivo.org/photivo/manual/tabs/geometry#seam_carving");
446 dynamic_cast<ptGroupBox*>(m_GroupBox->value("TabResize"))->
447 SetHelpUri("http://photivo.org/photivo/manual/tabs/geometry#resize");
448 dynamic_cast<ptGroupBox*>(m_GroupBox->value("TabFlip"))->
449 SetHelpUri("http://photivo.org/photivo/manual/tabs/geometry#flip");
450 dynamic_cast<ptGroupBox*>(m_GroupBox->value("TabBlock"))->
451 SetHelpUri("http://photivo.org/photivo/manual/tabs/geometry#block");
452
453 m_ActiveTabs.append(LocalTab);
454 m_ActiveTabs.append(GeometryTab);
455 m_ActiveTabs.append(RGBTab);
456 m_ActiveTabs.append(LabCCTab);
457 m_ActiveTabs.append(LabSNTab);
458 m_ActiveTabs.append(LabEyeCandyTab);
459 m_ActiveTabs.append(EyeCandyTab);
460 m_ActiveTabs.append(OutTab);
461
462 m_StatusIcon = QIcon(QString::fromUtf8(":/dark/ui-graphics/indicator-active-tab.png"));
463
464 // Profiles
465 QFileInfo PathInfo(Settings->GetString("CameraColorProfile"));
466 QString ShortFileName = PathInfo.fileName();
467 CameraColorProfileText->setText(ShortFileName);
468
469 PathInfo.setFile(Settings->GetString("PreviewColorProfile"));
470 ShortFileName = PathInfo.fileName();
471 PreviewColorProfileText->setText(ShortFileName);
472
473 PathInfo.setFile(Settings->GetString("OutputColorProfile"));
474 ShortFileName = PathInfo.fileName();
475 OutputColorProfileText->setText(ShortFileName);
476
477 PathInfo.setFile(Settings->GetString("GimpExecCommand"));
478 ShortFileName = PathInfo.fileName();
479 GimpExecCommandText->setText(ShortFileName);
480
481 // Photivo version string on info tab.
482 // Character replacements are hacks to avoid problems with make and stringify
483 // and certain special characters.
484 QString Temp(TOSTRING(APPVERSION));
485 AppVersionLabel->setText(Temp);
486 AppVersion2Label->setText(Temp);
487
488 Tabbar = ProcessingTabBook->findChild<QTabBar*>();
489 Tabbar->installEventFilter(this);
490 WritePipeButton->installEventFilter(this);
491 ToGimpButton->installEventFilter(this);
492 ResetButton->installEventFilter(this);
493 LogoLabel->installEventFilter(this);
494
495 m_ContextMenuOnTab = -1;
496
497 // context menu for save button
498 m_AtnSavePipe = new QAction(tr("Save current pipe"), this);
499 connect(m_AtnSavePipe, SIGNAL(triggered()), this, SLOT(SaveMenuPipe()));
500 m_AtnSaveFull = new QAction(tr("Save full size"), this);
501 connect(m_AtnSaveFull, SIGNAL(triggered()), this, SLOT(SaveMenuFull()));
502 m_AtnSaveSettings = new QAction(tr("Save settings file"), this);
503 connect(m_AtnSaveSettings, SIGNAL(triggered()), this, SLOT(SaveMenuSettings()));
504 m_AtnSaveJobfile = new QAction(tr("Save job file"), this);
505 connect(m_AtnSaveJobfile, SIGNAL(triggered()), this, SLOT(SaveMenuJobfile()));
506 m_AtnSendToBatch = new QAction(tr("Send to batch"), this);
507 connect(m_AtnSendToBatch, SIGNAL(triggered()), this, SLOT(SaveMenuBatch()));
508
509 // context menu for gimp button
510 m_AtnGimpSavePipe = new QAction(tr("Export current pipe"), this);
511 connect(m_AtnGimpSavePipe, SIGNAL(triggered()), this, SLOT(GimpSaveMenuPipe()));
512 m_AtnGimpSaveFull = new QAction(tr("Export full size"), this);
513 connect(m_AtnGimpSaveFull, SIGNAL(triggered()), this, SLOT(GimpSaveMenuFull()));
514
515 // context menu for reset button
516 m_AtnMenuFullReset = new QAction(tr("Neutral reset"), this);
517 connect(m_AtnMenuFullReset, SIGNAL(triggered()), this, SLOT(MenuFullReset()));
518 m_AtnMenuUserReset = new QAction(tr("User reset"), this);
519 connect(m_AtnMenuUserReset, SIGNAL(triggered()), this, SLOT(MenuUserReset()));
520 m_AtnMenuOpenPreset = new QAction(tr("Open preset"), this);
521 connect(m_AtnMenuOpenPreset, SIGNAL(triggered()), this, SLOT(MenuOpenPreset()));
522 m_AtnMenuOpenSettings = new QAction(tr("Open settings"), this);
523 connect(m_AtnMenuOpenSettings, SIGNAL(triggered()), this, SLOT(MenuOpenSettings()));
524
525 // context menu to show tools
526 m_AtnShowTools = new QAction(tr("&Show hidden tools"), this);
527 connect(m_AtnShowTools, SIGNAL(triggered()), this, SLOT(ShowToolsOnTab()));
528 m_AtnShowTools->setIcon(QIcon(*Theme->ptIconCheckGreen));
529 m_AtnShowTools->setIconVisibleInMenu(true);
530
531 // Search bar
532 Macro_ConnectSomeButton(SearchReset);
533 Macro_ConnectSomeButton(SearchActiveTools);
534 Macro_ConnectSomeButton(SearchAllTools);
535 Macro_ConnectSomeButton(SearchFavouriteTools);
536 connect(SearchInputWidget, SIGNAL(textEdited(QString)), this, SLOT(StartSearchTimer(QString)));
537 SearchWidget->setVisible(Settings->GetInt("SearchBarEnable"));
538 #if (QT_VERSION >= 0x40700)
539 SearchInputWidget->setPlaceholderText(tr("Search"));
540 #endif
541 m_SearchInputTimer = new QTimer(this);
542 m_SearchInputTimer->setSingleShot(1);
543 connect(m_SearchInputTimer, SIGNAL(timeout()), this, SLOT(Search()));
544
545 // Set the toolpane to show the pipe controls ...
546 MainTabBook->blockSignals(1);
547 MainTabBook->setCurrentWidget(TabProcessing);
548 MainTabBook->blockSignals(0);
549
550 // ... and open the first pipe controls tab
551 ProcessingTabBook->blockSignals(1);
552 ProcessingTabBook->setCurrentIndex(0);
553 ProcessingTabBook->blockSignals(0);
554
555 setAcceptDrops(true); // Drag and drop
556
557 // Timer to delay on resize operations.
558 // (avoiding excessive calculations and loops in the ZoomFit approach.)
559 m_ResizeTimer = new QTimer(this);
560 m_ResizeTimer->setSingleShot(1);
561 connect(m_ResizeTimer,
562 SIGNAL(timeout()),
563 this,
564 SLOT(ResizeTimerExpired()));
565 // This qualifies for an ugly hack :)
566 // Need an event at t=0 at toplevel.
567 m_Event0Timer = new QTimer(this);
568 m_Event0Timer->setSingleShot(1);
569 m_Event0Timer->start(0);
570 connect(m_Event0Timer,
571 SIGNAL(timeout()),
572 this,
573 SLOT(Event0TimerExpired()));
574
575 FileMgrThumbMaxRowColWidget->setEnabled(Settings->GetInt("FileMgrUseThumbMaxRowCol"));
576
577 UpdateCropToolUI();
578 UpdateLfunDistUI();
579 UpdateLfunCAUI();
580 UpdateLfunVignetteUI();
581 UpdateLiquidRescaleUI();
582 InitVisibleTools();
583 Settings->SetValue("PipeSize", Settings->GetValue("StartupPipeSize"));
584 if (Settings->GetInt("StartupUIMode") == ptStartupUIMode_Favourite)
585 ShowFavouriteTools();
586 if (Settings->GetInt("StartupUIMode") == ptStartupUIMode_AllTools)
587 ShowAllTools();
588
589 // Show the file manager if no image loaded at startup, the image editor otherwise.
590 // Do this last in the constructor because it triggers thumbnail reading.
591 #ifndef PT_WITHOUT_FILEMGR
592 if (ImageFileToOpen == "" &&
593 Settings->GetInt("FileMgrStartupOpen") &&
594 !Settings->GetInt("PreventFileMgrStartup"))
595 {
596 SwitchUIState(uisFileMgr);
597 } else {
598 SwitchUIState(uisProcessing);
599 }
600 #else
601 SwitchUIState(uisProcessing);
602 findChild<ptGroupBox *>(QString("TabFileMgrSettings"))->setVisible(0);
603 #endif
604
605 AutosaveSettingsWidget->setDisabled(Settings->GetInt("SaveConfirmation"));
606 }
607
608 //==============================================================================
609
610 void CB_Event0();
Event0TimerExpired()611 void ptMainWindow::Event0TimerExpired() {
612 ::CB_Event0();
613 }
614
615 //==============================================================================
616
617 // Setup the UI language combobox. Only done once after constructing MainWindow.
618 // The languages combobox is a regular QComboBox because its dynamic content (depends on
619 // available translation files) doesn't fit the logic of ptChoice (static, pre-defined lists).
PopulateTranslationsCombobox(const QStringList UiLanguages,const int LangIdx)620 void ptMainWindow::PopulateTranslationsCombobox(const QStringList UiLanguages, const int LangIdx) {
621 TranslationChoice->setFixedHeight(24);
622 TranslationChoice->addItem(tr("English (Default)"));
623 TranslationChoice->addItems(UiLanguages);
624 TranslationChoice->setCurrentIndex(LangIdx==-1 ? 0 : LangIdx+1);
625 connect(TranslationChoice, SIGNAL(currentIndexChanged(int)), this, SLOT(OnTranslationChoiceChanged(int)));
626 }
627
628 //==============================================================================
629
OnTranslationChoiceChanged(int idx)630 void ptMainWindow::OnTranslationChoiceChanged(int idx) {
631 TranslationLabel->setText(tr("Restart Photivo to change the language."));
632 if (idx == 0) { // no translation
633 Settings->SetValue("TranslationMode", 0);
634 Settings->SetValue("UiLanguage", "");
635 } else {
636 Settings->SetValue("TranslationMode", 1);
637 Settings->SetValue("UiLanguage", TranslationChoice->itemText(idx));
638 }
639 }
640
641
642 ////////////////////////////////////////////////////////////////////////////////
643 //
644 // Event filter
645 //
646 ////////////////////////////////////////////////////////////////////////////////
647
eventFilter(QObject * obj,QEvent * event)648 bool ptMainWindow::eventFilter(QObject *obj, QEvent *event)
649 {
650 if (event->type() == QEvent::ContextMenu) {
651 if (obj == Tabbar) {
652 // compute the tab number
653 QContextMenuEvent *mouseEvent = static_cast<QContextMenuEvent *>(event);
654 QPoint position = mouseEvent->pos();
655 int c = Tabbar->count();
656 int clickedItem = -1;
657
658 for (int i=0; i<c; i++) {
659 if ( Tabbar->tabRect(i).contains( position ) ) {
660 clickedItem = i;
661 break;
662 }
663 }
664 // tools on this tab hidden?
665 short HaveHiddenTools = 0;
666 QStringList TempList = Settings->GetStringList("HiddenTools");
667 foreach (ptTempFilterBase* GroupBox, *m_GroupBox) {
668 if (TempList.contains(GroupBox->objectName())) {
669 short Tab = GroupBox->parentTabIdx();
670 if (Tab == clickedItem) HaveHiddenTools = 1;
671 }
672 }
673 if (clickedItem !=0 && HaveHiddenTools == 1) { // no hidden tools on camera tab
674 m_ContextMenuOnTab = clickedItem;
675 QMenu Menu(NULL);
676 Menu.setStyle(Theme->style());
677 Menu.setPalette(Theme->menuPalette());
678 Menu.addAction(m_AtnShowTools);
679 Menu.exec(static_cast<QContextMenuEvent *>(event)->globalPos());
680 }
681 } else if (obj == WritePipeButton) {
682 QMenu Menu(NULL);
683 Menu.setStyle(Theme->style());
684 Menu.setPalette(Theme->menuPalette());
685 Menu.addAction(m_AtnSavePipe);
686 Menu.addAction(m_AtnSaveFull);
687 Menu.addAction(m_AtnSaveSettings);
688 Menu.addAction(m_AtnSaveJobfile);
689 Menu.addAction(m_AtnSendToBatch);
690 Menu.exec(static_cast<QContextMenuEvent *>(event)->globalPos());
691 } else if (obj == ToGimpButton) {
692 QMenu Menu(NULL);
693 Menu.setStyle(Theme->style());
694 Menu.setPalette(Theme->menuPalette());
695 Menu.addAction(m_AtnGimpSavePipe);
696 Menu.addAction(m_AtnGimpSaveFull);
697 Menu.exec(static_cast<QContextMenuEvent *>(event)->globalPos());
698 } else if (obj == ResetButton) {
699 QMenu Menu(NULL);
700 Menu.setStyle(Theme->style());
701 Menu.setPalette(Theme->menuPalette());
702 Menu.addAction(m_AtnMenuUserReset);
703 Menu.addAction(m_AtnMenuFullReset);
704 Menu.addSeparator();
705 Menu.addAction(m_AtnMenuOpenPreset);
706 Menu.addAction(m_AtnMenuOpenSettings);
707 Menu.exec(static_cast<QContextMenuEvent *>(event)->globalPos());
708 }
709 return QObject::eventFilter(obj, event);
710 } else if (obj == LogoLabel &&
711 event->type() == QEvent::MouseButtonPress &&
712 static_cast <QMouseEvent*>(event)->button() == Qt::LeftButton) {
713 ::CB_OpenFileButton();
714 return 0;
715 } else {
716 // pass the event on to the parent class
717 return QObject::eventFilter(obj, event);
718 }
719 }
720
721 ////////////////////////////////////////////////////////////////////////////////
722 //
723 // Slots for context menu on save button
724 //
725 ////////////////////////////////////////////////////////////////////////////////
726
727 extern void SaveOutput(const short mode);
728
SaveMenuPipe()729 void ptMainWindow::SaveMenuPipe() {
730 SaveOutput(ptOutputMode_Pipe);
731 }
SaveMenuFull()732 void ptMainWindow::SaveMenuFull() {
733 SaveOutput(ptOutputMode_Full);
734 }
SaveMenuSettings()735 void ptMainWindow::SaveMenuSettings() {
736 SaveOutput(ptOutputMode_Settingsfile);
737 }
SaveMenuJobfile()738 void ptMainWindow::SaveMenuJobfile() {
739 SaveOutput(ptOutputMode_Jobfile);
740 }
SaveMenuBatch()741 void ptMainWindow::SaveMenuBatch() {
742 SaveOutput(ptOutputMode_Batch);
743 }
744
745 ////////////////////////////////////////////////////////////////////////////////
746 //
747 // Slots for context menu on gimp button
748 //
749 ////////////////////////////////////////////////////////////////////////////////
750
751 extern void Export(const short mode);
752
GimpSaveMenuPipe()753 void ptMainWindow::GimpSaveMenuPipe() {
754 Export(ptExportMode_GimpPipe);
755 }
GimpSaveMenuFull()756 void ptMainWindow::GimpSaveMenuFull() {
757 Export(ptExportMode_GimpFull);
758 }
759
760 ////////////////////////////////////////////////////////////////////////////////
761 //
762 // Slots for context menu on reset button
763 //
764 ////////////////////////////////////////////////////////////////////////////////
765
766 extern void ResetButtonHandler(const short mode);
767
MenuFullReset()768 void ptMainWindow::MenuFullReset() {
769 ResetButtonHandler(ptResetMode_Full);
770 }
771
MenuUserReset()772 void ptMainWindow::MenuUserReset() {
773 ResetButtonHandler(ptResetMode_User);
774 }
775
MenuOpenPreset()776 void ptMainWindow::MenuOpenPreset() {
777 ResetButtonHandler(ptResetMode_OpenPreset);
778 }
779
MenuOpenSettings()780 void ptMainWindow::MenuOpenSettings() {
781 ResetButtonHandler(ptResetMode_OpenSettings);
782 }
783
784 ////////////////////////////////////////////////////////////////////////////////
785 //
786 // Slots for context menu on tabs
787 //
788 ////////////////////////////////////////////////////////////////////////////////
789
ShowToolsOnTab()790 void ptMainWindow::ShowToolsOnTab() {
791 // show hidden tools on tab m_ContextMenuOnTab
792 QString ActiveTool= "";
793 QString TempString = "";
794 QStringList TempList = Settings->GetStringList("HiddenTools");
795 TempList.removeDuplicates();
796
797 foreach (ptTempFilterBase* GroupBox, *m_GroupBox) {
798 TempString = GroupBox->objectName();
799
800 if (TempList.contains(TempString)) {
801 short Tab = GroupBox->parentTabIdx();
802
803 if (m_ContextMenuOnTab==Tab) {
804 GroupBox->guiWidget()->show();
805 TempList.removeOne(TempString);
806 Settings->SetValue("HiddenTools", TempList);
807
808 if (GroupBox->isActive()) {
809 ActiveTool = TempString;
810 }
811 }
812 }
813 }
814 Settings->SetValue("HiddenTools", TempList);
815 // run processor if needed
816 if (ActiveTool != "") Update(ActiveTool);
817 }
818
819
820 ////////////////////////////////////////////////////////////////////////////////
821 //
822 // Added slot for messages to the single instance
823 //
824 ////////////////////////////////////////////////////////////////////////////////
825
OtherInstanceMessage(const QString & msg)826 void ptMainWindow::OtherInstanceMessage(const QString &msg) {
827 // Settings file loaded via cli
828 if (msg.startsWith("::pts::")) {
829 PtsFileToOpen = msg;
830 PtsFileToOpen.remove(0,7);
831
832 if (ptConfirmRequest::loadConfig(lcmSettingsFile, PtsFileToOpen)) {
833 CB_OpenSettingsFile(PtsFileToOpen);
834 }
835
836 // Image file loaded via cli
837 } else if (msg.startsWith("::img::")) {
838 ImageFileToOpen = msg;
839 ImageFileToOpen.remove(0,7);
840 CB_MenuFileOpen(1);
841
842 // image incoming from Gimp
843 } else if (msg.startsWith("::tmp::")) {
844 ImageFileToOpen = msg;
845 ImageFileToOpen.remove(0,7);
846 ImageCleanUp++;
847 CB_MenuFileOpen(1);
848 } else if (msg.startsWith("::sidecar::")) {
849 QString Sidecar = msg;
850 Sidecar.remove(0,11);
851 ReadSidecar(Sidecar);
852 Settings->SetValue("Sidecar", Sidecar);
853 }
854
855 }
856
857 //==============================================================================
858
859 ////////////////////////////////////////////////////////////////////////////////
860 //
861 // GetCurrentTab
862 //
863 // Determine the current tab selected.
864 //
865 ////////////////////////////////////////////////////////////////////////////////
866
GetCurrentTab()867 short ptMainWindow::GetCurrentTab() {
868 // I opt for matching onto widget name, rather than on
869 // index, as I feel that this is more robust for change.
870 if (ProcessingTabBook->currentWidget() == CameraTab) return ptCameraTab;
871 else if (ProcessingTabBook->currentWidget() == LocalTab) return ptLocalTab;
872 else if (ProcessingTabBook->currentWidget() == GeometryTab) return ptGeometryTab;
873 else if (ProcessingTabBook->currentWidget() == RGBTab) return ptRGBTab;
874 else if (ProcessingTabBook->currentWidget() == LabCCTab) return ptLabCCTab;
875 else if (ProcessingTabBook->currentWidget() == LabSNTab) return ptLabSNTab;
876 else if (ProcessingTabBook->currentWidget() == LabEyeCandyTab) return ptLabEyeCandyTab;
877 else if (ProcessingTabBook->currentWidget() == EyeCandyTab) return ptEyeCandyTab;
878 else if (ProcessingTabBook->currentWidget() == OutTab) return ptOutTab;
879 else {
880 ptLogError(ptError_Argument,"Unforeseen tab.");
881 assert(0);
882 return 0;
883 }
884 }
885
886 ////////////////////////////////////////////////////////////////////////////////
887 //
888 // All kind of Gui events.
889 // Translated back to a CB_ function into ptMain
890 //
891 ////////////////////////////////////////////////////////////////////////////////
892
893 //==============================================================================
894 // Show/hide file manager window
895
OpenBatchWindow()896 void ptMainWindow::OpenBatchWindow() {
897 SwitchUIState(uisBatch);
898 }
899
CloseBatchWindow()900 void ptMainWindow::CloseBatchWindow() {
901 SwitchUIState(uisProcessing);
902 }
903
OpenFileMgrWindow()904 void ptMainWindow::OpenFileMgrWindow() {
905 SwitchUIState(uisFileMgr);
906 }
907
CloseFileMgrWindow()908 void ptMainWindow::CloseFileMgrWindow() {
909 SwitchUIState(uisProcessing);
910 }
911
912 //==============================================================================
913 // Tabbook switching
914
915 void CB_Tabs(const short Index);
on_ProcessingTabBook_currentChanged(const int Index)916 void ptMainWindow::on_ProcessingTabBook_currentChanged(const int Index) {
917 ::CB_Tabs(Index);
918 }
919
920 //==============================================================================
921
922 struct sToolBoxStructure {
923 QToolBox* ToolBox;
924 QWidget* Parent;
925 QVBoxLayout* ParentLayout;
926 // The standard layout in toolbox pages.
927 QList <QWidget *> Pages;
928 QList <QVBoxLayout *> PageLayouts;
929 // The alternative layout in groupboxes.
930 QList <ptGroupBox *> GroupBoxes;
931 QList <QVBoxLayout *> GroupBoxLayouts;
932 // The widgets we foresaw moving.
933 QList <QWidget *> Widgets;
934 };
935
936 QList <sToolBoxStructure*> ToolBoxStructureList;
937
AnalyzeToolBoxStructure()938 void ptMainWindow::AnalyzeToolBoxStructure() {
939 // QMap for all processing group boxes (without settings and info!)
940 // QMap Name -> ptGroupBox*
941 if (m_GroupBox) delete m_GroupBox;
942 m_GroupBox = new QMap<QString, ptTempFilterBase*>;
943 if (m_GroupBoxesOrdered) delete m_GroupBoxesOrdered;
944 m_GroupBoxesOrdered = new QList<QString>;
945 if (m_TabLayouts) delete m_TabLayouts;
946 m_TabLayouts = new QList<QVBoxLayout*>;
947
948 // Each processing tab has one QToolBox containing a list of QWidgets as direct children.
949 // Each of those is one filter and will become one groupbox.
950 // The settings page and info page are represented by QToolBox "SettingsToolBox" and
951 // "InfoToolBox". They are excluded from the m_GroupBox and m_GrouBoxesOrdered lists. I.e.
952 // those lists only contain the filters on the proccessing page.
953 QList <QToolBox *> ToolBoxes;
954 short NumberOfTabs = ProcessingTabBook->count();
955 for (short i=0; i<NumberOfTabs; i++) {
956 ToolBoxes.append(ProcessingTabBook->widget(i)->findChildren <QToolBox *> ());
957 }
958 ToolBoxes.append(SettingsToolBox);
959 ToolBoxes.append(InfoToolBox);
960
961 // iterate over the QToolBoxes
962 for (short itTab=0; itTab<ToolBoxes.size(); itTab++) {
963 sToolBoxStructure* ToolBoxStructure = new sToolBoxStructure;
964 ToolBoxStructureList.append(ToolBoxStructure);
965 ToolBoxStructure->ToolBox = ToolBoxes[itTab];
966 ToolBoxStructure->Parent =
967 qobject_cast <QWidget*>(ToolBoxes[itTab]->parent());
968 ToolBoxStructure->ParentLayout =
969 qobject_cast <QVBoxLayout*>(ToolBoxStructure->Parent->layout());
970 assert (ToolBoxStructure->ParentLayout);
971 if (ToolBoxStructure->ToolBox != SettingsToolBox &&
972 ToolBoxStructure->ToolBox != InfoToolBox) {
973 m_TabLayouts->append(ToolBoxStructure->ParentLayout);
974 }
975
976 // iterate over the the QToolBox child widgets (i.e. the individual filters)
977 for (short itIdx=0; itIdx<ToolBoxes[itTab]->count(); itIdx++) {
978 // handle dummy entries for new-style filters
979 auto hNewFilter = GFilterDM->GetFilterFromName(ToolBoxes[itTab]->itemText(itIdx), false);
980 if (hNewFilter) {
981 hNewFilter->setPos(itTab, itIdx);
982 m_GroupBoxesOrdered->append(hNewFilter->uniqueName());
983 m_GroupBox->insert(hNewFilter->uniqueName(), hNewFilter);
984 continue;
985 }
986
987 // create groupboxes etc. for old-style filters
988 QWidget* Page = ToolBoxes[itTab]->widget(itIdx);
989 QVBoxLayout* PageLayout = qobject_cast <QVBoxLayout*>(Page->layout());
990 ToolBoxStructure->Pages.append(Page);
991 ToolBoxStructure->PageLayouts.append(PageLayout);
992 // Alternative groupboxes. The layout of which still needs to be created.
993 ptGroupBox* GroupBox =
994 new ptGroupBox(ToolBoxStructure->ToolBox->itemText(itIdx),
995 this,
996 ToolBoxStructure->ToolBox->widget(itIdx)->objectName(),
997 itTab<NumberOfTabs?ProcessingTabBook->widget(itTab)->objectName():"",
998 itTab,
999 itIdx);
1000
1001 if (ToolBoxStructure->ToolBox != SettingsToolBox &&
1002 ToolBoxStructure->ToolBox != InfoToolBox) {
1003 m_GroupBox->insert(ToolBoxStructure->ToolBox->widget(itIdx)->objectName(),
1004 GroupBox);
1005 m_GroupBoxesOrdered->append(ToolBoxStructure->ToolBox->widget(itIdx)->objectName());
1006 }
1007
1008 QVBoxLayout* GroupBoxLayout = new QVBoxLayout(GroupBox->m_Widget);
1009 GroupBoxLayout->setSpacing(0);
1010 GroupBoxLayout->setMargin(0);
1011 ToolBoxStructure->GroupBoxes.append(GroupBox);
1012 ToolBoxStructure->GroupBoxLayouts.append(GroupBoxLayout);
1013 // The list of childwidgets.
1014 QList <QWidget *> DirectChildrenOfPage = findChildren <QWidget *> ();
1015 // findChildren is always recursive. Remove lots.
1016 for (short k=0; k<DirectChildrenOfPage.size();) {
1017 if (DirectChildrenOfPage[k]->parent() != Page) {
1018 DirectChildrenOfPage.removeAt(k);
1019 } else {
1020 k++;
1021 }
1022 }
1023 GInfo->Assert(DirectChildrenOfPage.size() == 1,
1024 "Failed analyzing filter named " + ToolBoxes[itTab]->itemText(itIdx) +
1025 ". If you see a FUID as the name you probably forgot to create the "
1026 "corresponding new-style filter in ptMain::CreateAllFilters().", AT);
1027 ToolBoxStructure->Widgets.append(DirectChildrenOfPage[0]);
1028 }
1029 }
1030 }
1031
1032 //==============================================================================
1033
OnToolBoxesEnabledTriggered(const bool Enabled)1034 void ptMainWindow::OnToolBoxesEnabledTriggered(const bool Enabled) {
1035 if (ToolBoxStructureList.size() == 0) {
1036 AnalyzeToolBoxStructure();
1037 }
1038
1039 // Empty all involved layouts.
1040 for (short Idx=0; Idx<ToolBoxStructureList.size(); Idx++) {
1041 sToolBoxStructure* ToolBoxStructure = ToolBoxStructureList[Idx];
1042 // 1. Parent.
1043 while (ToolBoxStructure->ParentLayout->count()) {
1044 ToolBoxStructure->ParentLayout->
1045 removeItem(ToolBoxStructure->ParentLayout->itemAt(0));
1046 }
1047 for (short j=0; j<ToolBoxStructure->Widgets.size(); j++) {
1048 // 2. Groupboxes.
1049 while (ToolBoxStructure->GroupBoxLayouts[j]->count()) {
1050 ToolBoxStructure->GroupBoxLayouts[j]->
1051 removeItem(ToolBoxStructure->GroupBoxLayouts[j]->itemAt(0));
1052 }
1053 // 3. Pages.
1054 while (ToolBoxStructure->PageLayouts[j]->count()) {
1055 ToolBoxStructure->PageLayouts[j]->
1056 removeItem(ToolBoxStructure->PageLayouts[j]->itemAt(0));
1057 }
1058 }
1059 }
1060
1061 // Orphan widgets (TODO : maybe not really needed ..)
1062 for (short Idx=0; Idx<ToolBoxStructureList.size(); Idx++) {
1063 sToolBoxStructure* ToolBoxStructure = ToolBoxStructureList[Idx];
1064 for (short j=0; j<ToolBoxStructure->Widgets.size(); j++) {
1065 ToolBoxStructure->Widgets[j]->setParent(NULL);
1066 ToolBoxStructure->GroupBoxes[j]->setParent(NULL);
1067 }
1068 ToolBoxStructure->ToolBox->setParent(NULL);
1069 }
1070
1071 // Now start relayouting.
1072
1073 // Layout for groupbox mode.
1074 if (!Enabled) {
1075 for (short Idx=0; Idx<ToolBoxStructureList.size(); Idx++) {
1076 sToolBoxStructure* ToolBoxStructure = ToolBoxStructureList[Idx];
1077 for (short j=0; j<ToolBoxStructure->Widgets.size(); j++) {
1078 ToolBoxStructure->Widgets[j]->
1079 setParent(ToolBoxStructure->GroupBoxes[j]);
1080 ToolBoxStructure->GroupBoxLayouts[j]->
1081 addWidget(ToolBoxStructure->Widgets[j]);
1082 ToolBoxStructure->Widgets[j]->layout()->setSpacing(4);
1083 ToolBoxStructure->GroupBoxes[j]->setParent(ToolBoxStructure->Parent);
1084 ToolBoxStructure->ParentLayout->
1085 addWidget(ToolBoxStructure->GroupBoxes[j]);
1086 }
1087 ToolBoxStructure->ParentLayout->addStretch();
1088 ToolBoxStructure->ParentLayout->setSpacing(0);
1089 ToolBoxStructure->ParentLayout->setContentsMargins(0,0,0,0);
1090 ToolBoxStructure->ParentLayout->setMargin(0);
1091 ToolBoxStructure->Parent->show();
1092 }
1093 }
1094
1095 // Layout for toolbox mode.
1096 if (Enabled) {
1097 GInfo->Raise("Toolbox mode is ancient and dysfunctional!", AT);
1098 }
1099 }
1100
1101
1102 //
1103 // Gimp
1104 //
1105
OnToGimpButtonClicked()1106 void ptMainWindow::OnToGimpButtonClicked() {
1107 #ifdef DLRAW_GIMP_PLUGIN
1108 ::CB_MenuFileExit(1);
1109 #endif
1110 GimpSaveMenuPipe();
1111 }
1112
1113 //
1114 // PreviewMode
1115 //
1116
1117 void CB_PreviewModeButton(const QVariant State);
OnPreviewModeButtonClicked()1118 void ptMainWindow::OnPreviewModeButtonClicked() {
1119 if (PreviewModeButton->isChecked())
1120 ::CB_PreviewModeButton(1);
1121 else
1122 ::CB_PreviewModeButton(0);
1123 }
1124
1125 //
1126 // Run
1127 //
1128
1129 void CB_RunButton();
OnRunButtonClicked()1130 void ptMainWindow::OnRunButtonClicked() {
1131 ::CB_RunButton();
1132 }
1133
1134 void CB_ResetButton();
OnResetButtonClicked()1135 void ptMainWindow::OnResetButtonClicked() {
1136 ::CB_ResetButton();
1137 }
1138
1139 //
1140 // Zoom
1141 //
1142
1143 void CB_ZoomFitButton();
OnZoomFitButtonClicked()1144 void ptMainWindow::OnZoomFitButtonClicked() {
1145 ::CB_ZoomFitButton();
1146 }
1147
1148 void CB_ZoomFullButton();
OnZoomFullButtonClicked()1149 void ptMainWindow::OnZoomFullButtonClicked() {
1150 ::CB_ZoomFullButton();
1151 }
1152
OnZoomInButtonClicked()1153 void ptMainWindow::OnZoomInButtonClicked() {
1154 ViewWindow->ZoomStep(1);
1155 }
1156
OnZoomOutButtonClicked()1157 void ptMainWindow::OnZoomOutButtonClicked() {
1158 ViewWindow->ZoomStep(-1);
1159 }
1160
1161
1162 void CB_InputChanged(const QString ObjectName, const QVariant Value);
OnInputChanged(const QVariant Value)1163 void ptMainWindow::OnInputChanged(const QVariant Value) {
1164 QObject* Sender = sender();
1165 printf("(%s,%d) Sender : '%s'\n",
1166 __FILE__,__LINE__,Sender->objectName().toLocal8Bit().data());
1167 CB_InputChanged(Sender->objectName(),Value);
1168
1169 }
1170
1171 void CB_PreviousImageButton();
OnPreviousImageButtonClicked()1172 void ptMainWindow::OnPreviousImageButtonClicked() {
1173 ::CB_PreviousImageButton();
1174 }
1175
1176 void CB_NextImageButton();
OnNextImageButtonClicked()1177 void ptMainWindow::OnNextImageButtonClicked() {
1178 ::CB_NextImageButton();
1179 }
1180
1181 void CB_BatchButton();
OnBatchButtonClicked()1182 void ptMainWindow::OnBatchButtonClicked() {
1183 ::CB_BatchButton();
1184 }
1185
1186 void CB_FileMgrButton();
OnFileMgrButtonClicked()1187 void ptMainWindow::OnFileMgrButtonClicked() {
1188 ::CB_FileMgrButton();
1189 }
1190
1191 void CB_FullScreenButton(const int State);
OnFullScreenButtonClicked()1192 void ptMainWindow::OnFullScreenButtonClicked() {
1193 if (FullScreenButton->isChecked())
1194 ::CB_FullScreenButton(1);
1195 else
1196 ::CB_FullScreenButton(0);
1197 }
1198
1199 void CB_LoadStyleButton();
OnLoadStyleButtonClicked()1200 void ptMainWindow::OnLoadStyleButtonClicked() {
1201 ::CB_LoadStyleButton();
1202 }
1203
OnTabProcessingButtonClicked()1204 void ptMainWindow::OnTabProcessingButtonClicked() {
1205 // clean up first!
1206 if (m_MovedTools->size()>0) CleanUpMovedTools();
1207 SearchInputWidget->setText("");
1208 ViewWindow->setFocus();
1209
1210 // apply changes at VisibleTools box
1211 if (MainTabBook->currentWidget() == TabSetting)
1212 ApplyVisibleTools();
1213
1214 MainTabBook->setCurrentWidget(TabProcessing);
1215 }
1216
OnTabSettingsButtonClicked()1217 void ptMainWindow::OnTabSettingsButtonClicked() {
1218 // clean up first!
1219 if (m_MovedTools->size()>0) CleanUpMovedTools();
1220 SearchInputWidget->setText("");
1221 ViewWindow->setFocus();
1222
1223 if (MainTabBook->currentWidget() == TabSetting) {
1224 // apply changes at VisibleTools box
1225 ApplyVisibleTools();
1226 MainTabBook->setCurrentWidget(TabProcessing);
1227 }
1228 else {
1229 // update VisibleTools box
1230 UpdateVisibleTools();
1231 MainTabBook->setCurrentWidget(TabSetting);
1232 }
1233 }
1234
OnTabInfoButtonClicked()1235 void ptMainWindow::OnTabInfoButtonClicked() {
1236 // clean up first!
1237 if (m_MovedTools->size()>0) CleanUpMovedTools();
1238 SearchInputWidget->setText("");
1239 ViewWindow->setFocus();
1240
1241 // apply changes at VisibleTools box
1242 if (MainTabBook->currentWidget() == TabSetting)
1243 ApplyVisibleTools();
1244
1245 if (MainTabBook->currentWidget() == TabInfo)
1246 MainTabBook->setCurrentWidget(TabProcessing);
1247 else {
1248 UpdateSettings();
1249 MainTabBook->setCurrentWidget(TabInfo);
1250 }
1251 }
1252
1253 //
1254 // Settings
1255 //
1256
1257 void CB_BackgroundColorButton();
OnBackgroundColorButtonClicked()1258 void ptMainWindow::OnBackgroundColorButtonClicked() {
1259 ::CB_BackgroundColorButton();
1260 }
1261
1262 //
1263 // Tab Generic
1264 //
1265
1266 void CB_CameraColorProfileButton();
OnCameraColorProfileButtonClicked()1267 void ptMainWindow::OnCameraColorProfileButtonClicked() {
1268 ::CB_CameraColorProfileButton();
1269 }
1270
1271 void CB_PreviewColorProfileButton();
OnPreviewColorProfileButtonClicked()1272 void ptMainWindow::OnPreviewColorProfileButtonClicked() {
1273 ::CB_PreviewColorProfileButton();
1274 }
1275
1276 void CB_OutputColorProfileButton();
OnOutputColorProfileButtonClicked()1277 void ptMainWindow::OnOutputColorProfileButtonClicked() {
1278 ::CB_OutputColorProfileButton();
1279 }
1280
1281 void CB_GimpExecCommandButton();
OnGimpExecCommandButtonClicked()1282 void ptMainWindow::OnGimpExecCommandButtonClicked() {
1283 ::CB_GimpExecCommandButton();
1284 }
1285
1286 void CB_StartupSettingsButton();
OnStartupSettingsButtonClicked()1287 void ptMainWindow::OnStartupSettingsButtonClicked() {
1288 ::CB_StartupSettingsButton();
1289 }
1290
1291
1292 //
1293 // Tab : Camera
1294 //
1295
OnOpenFileButtonClicked()1296 void ptMainWindow::OnOpenFileButtonClicked() {
1297 ::CB_OpenFileButton();
1298 }
1299 void CB_OpenSettingsFileButton();
OnOpenSettingsFileButtonClicked()1300 void ptMainWindow::OnOpenSettingsFileButtonClicked() {
1301 ::CB_OpenSettingsFileButton();
1302 }
1303 void CB_OpenPresetFileButton();
OnOpenPresetFileButtonClicked()1304 void ptMainWindow::OnOpenPresetFileButtonClicked() {
1305 ::CB_OpenPresetFileButton();
1306 }
1307
1308 void CB_SpotWBButton();
OnSpotWBButtonClicked()1309 void ptMainWindow::OnSpotWBButtonClicked() {
1310 ::CB_SpotWBButton();
1311 }
1312
1313 //
1314 // Tab : Geometry
1315 //
1316
1317
1318 void CB_RotateLeftButton();
OnRotateLeftButtonClicked()1319 void ptMainWindow::OnRotateLeftButtonClicked() {
1320 ::CB_RotateLeftButton();
1321 }
1322
1323 void CB_RotateRightButton();
OnRotateRightButtonClicked()1324 void ptMainWindow::OnRotateRightButtonClicked() {
1325 ::CB_RotateRightButton();
1326 }
1327
1328 void CB_RotateAngleButton();
OnRotateAngleButtonClicked()1329 void ptMainWindow::OnRotateAngleButtonClicked() {
1330 ::CB_RotateAngleButton();
1331 }
1332
1333 void CB_MakeCropButton();
OnMakeCropButtonClicked()1334 void ptMainWindow::OnMakeCropButtonClicked() {
1335 ::CB_MakeCropButton();
1336 }
1337
1338 void CB_ConfirmCropButton();
OnConfirmCropButtonClicked()1339 void ptMainWindow::OnConfirmCropButtonClicked() {
1340 ::CB_ConfirmCropButton();
1341 }
1342
1343 void CB_CancelCropButton();
OnCancelCropButtonClicked()1344 void ptMainWindow::OnCancelCropButtonClicked() {
1345 ::CB_CancelCropButton();
1346 }
1347
1348 void CB_CropOrientationButton();
OnCropOrientationButtonClicked()1349 void ptMainWindow::OnCropOrientationButtonClicked() {
1350 ::CB_CropOrientationButton();
1351 }
1352
1353 void CB_CropCenterHorButton();
OnCropCenterHorButtonClicked()1354 void ptMainWindow::OnCropCenterHorButtonClicked() {
1355 ::CB_CropCenterHorButton();
1356 }
1357
1358 void CB_CropCenterVertButton();
OnCropCenterVertButtonClicked()1359 void ptMainWindow::OnCropCenterVertButtonClicked() {
1360 ::CB_CropCenterVertButton();
1361 }
1362
1363 // Tab : Output
1364
1365 void CB_OutputColorProfileResetButton();
OnOutputColorProfileResetButtonClicked()1366 void ptMainWindow::OnOutputColorProfileResetButtonClicked() {
1367 ::CB_OutputColorProfileResetButton();
1368 }
1369
1370 void CB_WritePipeButton();
OnWritePipeButtonClicked()1371 void ptMainWindow::OnWritePipeButtonClicked() {
1372 ::CB_WritePipeButton();
1373 }
1374
1375 void PrepareTags(const QString TagsInput);
OnTagsEditTextChanged()1376 void ptMainWindow::OnTagsEditTextChanged() {
1377 PrepareTags(TagsEditWidget->toPlainText());
1378 }
1379
1380 // Intercept close event and translate to a FileExit.
closeEvent(QCloseEvent * Event)1381 void ptMainWindow::closeEvent(QCloseEvent *Event) {
1382 Event->ignore();
1383 ::CB_MenuFileExit(1);
1384 }
1385
1386 // Fit the image again after a resize event.
1387
resizeEvent(QResizeEvent *)1388 void ptMainWindow::resizeEvent(QResizeEvent*) {
1389 // Avoiding excessive calculations and ZoomFit loops.
1390 m_ResizeTimer->start(500); // 500 ms.
1391 }
1392
ResizeTimerExpired()1393 void ptMainWindow::ResizeTimerExpired() {
1394 // 250 would be the size for the progress label then.
1395 if (Settings->GetInt("ZoomMode") == ptZoomMode_Fit) {
1396 ::CB_ZoomFitButton();
1397 }
1398 }
1399
1400 ////////////////////////////////////////////////////////////////////////
1401 //
1402 // dragEnterEvent
1403 //
1404 ////////////////////////////////////////////////////////////////////////
1405
dragEnterEvent(QDragEnterEvent * Event)1406 void ptMainWindow::dragEnterEvent(QDragEnterEvent* Event) {
1407 if (ViewWindow->interaction() != iaNone) {
1408 return;
1409 }
1410
1411 // accept just text/uri-list mime format
1412 if (Event->mimeData()->hasFormat("text/uri-list")) {
1413 Event->acceptProposedAction();
1414 }
1415 }
1416
1417
1418 ////////////////////////////////////////////////////////////////////////
1419 //
1420 // dropEvent
1421 //
1422 ////////////////////////////////////////////////////////////////////////
1423
dropEvent(QDropEvent * Event)1424 void ptMainWindow::dropEvent(QDropEvent* Event) {
1425 if (ViewWindow->interaction() != iaNone) {
1426 return;
1427 }
1428
1429 QList<QUrl> UrlList;
1430 QString DropName;
1431 QFileInfo DropInfo;
1432
1433 if (Event->mimeData()->hasUrls())
1434 {
1435 UrlList = Event->mimeData()->urls(); // returns list of QUrls
1436
1437 // if just text was dropped, urlList is empty (size == 0)
1438 if ( UrlList.size() > 0) // if at least one QUrl is present in list
1439 {
1440 DropName = UrlList[0].toLocalFile(); // convert first QUrl to local path
1441 DropInfo.setFile( DropName ); // information about file
1442 if ( DropInfo.isFile() ) { // if is file
1443 if (DropInfo.completeSuffix()!="pts" && DropInfo.completeSuffix()!="ptj" &&
1444 DropInfo.completeSuffix()!="dls" && DropInfo.completeSuffix()!="dlj")
1445 {
1446 if (Settings->GetInt("FileMgrIsOpen"))
1447 CloseFileMgrWindow();
1448 ImageFileToOpen = DropName;
1449 CB_MenuFileOpen(1);
1450
1451 } else {
1452 if (!Settings->GetInt("FileMgrIsOpen")) {
1453 if (ptConfirmRequest::loadConfig(lcmSettingsFile, DropName)) {
1454 CB_OpenSettingsFile(DropName);
1455 }
1456 }
1457 }
1458 }
1459 }
1460 }
1461 Event->acceptProposedAction();
1462 }
1463
1464 void CB_FullScreenButton(const int State);
1465 void UpdateSettings();
1466 void CB_RunModeCheck(const QVariant Check);
1467 void CB_OpenPresetFileButton();
1468 void CB_InputChanged(const QString,const QVariant);
1469 void CB_ZoomFitButton();
1470 void CB_WritePipeButton();
1471 void CB_SpecialPreviewChoice(const QVariant Choice);
1472 void CB_MenuFileExit(const short);
1473 void ViewWindowShowStatus(short State);
1474 void CB_SearchBarEnableCheck(const QVariant State);
1475
1476 // Catch keyboard shortcuts
keyPressEvent(QKeyEvent * Event)1477 void ptMainWindow::keyPressEvent(QKeyEvent *Event) {
1478 if (Event->key()==Qt::Key_Escape) {// back to used view
1479 if (Settings->GetInt("SpecialPreview") != ptSpecialPreview_RGB) {
1480 CB_SpecialPreviewChoice(ptSpecialPreview_RGB);
1481 return;
1482 } else if (SearchInputWidget->hasFocus()) {
1483 OnTabProcessingButtonClicked();
1484 return;
1485 } else if (Settings->GetInt("ShowToolContainer") == 0) {
1486 Settings->SetValue("ShowToolContainer", 1);
1487 UpdateSettings();
1488 return;
1489 } else if (Settings->GetInt("FullscreenActive") == 1) {
1490 ::CB_FullScreenButton(0);
1491 return;
1492 } else {
1493 if (Settings->GetInt("EscToExit") == 1) {
1494 ::CB_MenuFileExit(1);
1495 }
1496 return;
1497 }
1498 }
1499
1500 if (SearchInputWidget->hasFocus() &&
1501 (Event->key()==Qt::Key_Return ||
1502 Event->key()==Qt::Key_Enter))
1503 {
1504 ViewWindow->setFocus();
1505 return;
1506 }
1507
1508 if (Settings->GetInt("BlockTools") == 0 || ViewWindow->interaction() == iaCrop) {
1509 if (Event->key()==Qt::Key_F11) { // toggle full screen
1510 ::CB_FullScreenButton(!isFullScreen());
1511 } else if (Event->key()==Qt::Key_1 && Event->modifiers()==Qt::NoModifier) {
1512 CB_ZoomStep(1);
1513 } else if (Event->key()==Qt::Key_2 && Event->modifiers()==Qt::NoModifier) {
1514 CB_InputChanged("ZoomInput",100);
1515 } else if (Event->key()==Qt::Key_3 && Event->modifiers()==Qt::NoModifier) {
1516 CB_ZoomStep(-1);
1517 } else if (Event->key()==Qt::Key_4 && Event->modifiers()==Qt::NoModifier) {
1518 CB_ZoomFitButton();
1519 } else if (Event->key()==Qt::Key_Space) {
1520 Settings->SetValue("ShowToolContainer",1-Settings->GetInt("ShowToolContainer"));
1521 UpdateSettings();
1522 if (Settings->GetInt("ZoomMode") == ptZoomMode_Fit) {
1523 ViewWindow->ZoomToFit(0);
1524 }
1525 }
1526 }
1527
1528 // most shortcuts should only work when we are not in special state like cropping
1529 if (Settings->GetInt("BlockTools")==0) {
1530 if (Event->key()==Qt::Key_F1) {
1531 QDesktopServices::openUrl(QString("http://photivo.org/photivo/manual"));
1532 } else if (Event->key()==Qt::Key_P && Event->modifiers()==Qt::NoModifier) {
1533 OnTabProcessingButtonClicked();
1534 } else if (Event->key()==Qt::Key_S && Event->modifiers()==Qt::NoModifier) {
1535 OnTabSettingsButtonClicked();
1536 } else if (Event->key()==Qt::Key_I && Event->modifiers()==Qt::NoModifier) {
1537 OnTabInfoButtonClicked();
1538 } else if (Event->key()==Qt::Key_M && Event->modifiers()==Qt::NoModifier) {
1539 ::CB_RunModeCheck(1-Settings->GetInt("RunMode"));
1540 } else if (Event->key()==Qt::Key_F5) {
1541 OnRunButtonClicked();
1542 } else if (Event->key()==Qt::Key_F3) {
1543 CB_SearchBarEnableCheck(1);
1544 if (!SearchInputWidget->hasFocus()) {
1545 SearchInputWidget->setText("");
1546 SearchInputWidget->setFocus();
1547 }
1548 } else if (Event->key() == Qt::Key_M && Event->modifiers() == Qt::ControlModifier) {
1549 SwitchUIState(uisFileMgr);
1550 } else if (Event->key() == Qt::Key_B && Event->modifiers() == Qt::ControlModifier) {
1551 SwitchUIState(uisBatch);
1552 } else if (Event->key()==Qt::Key_P && Event->modifiers()==Qt::ControlModifier) {
1553 CB_OpenPresetFileButton();
1554 } else if (Event->key()==Qt::Key_Q && Event->modifiers()==Qt::ControlModifier) {
1555 CB_MenuFileExit(1);
1556 } else if (Event->key()==Qt::Key_O && Event->modifiers()==Qt::ControlModifier) {
1557 CB_MenuFileOpen(0);
1558 } else if (Event->key()==Qt::Key_S && Event->modifiers()==Qt::ControlModifier) {
1559 CB_WritePipeButton();
1560 } else if (Event->key()==Qt::Key_G && Event->modifiers()==Qt::ControlModifier) {
1561 Update(ptProcessorPhase_ToGimp);
1562 } else if (Event->key()==Qt::Key_R && Event->modifiers()==Qt::ControlModifier) {
1563 resize(QSize(1200,900));
1564 QRect DesktopRect = (QApplication::desktop())->screenGeometry(this);
1565 move(QPoint(MAX((DesktopRect.width()-1200),0)/2,MAX((DesktopRect.height()-900)/2-20,0)));
1566 } else if (Event->key()==Qt::Key_1 && Event->modifiers()==Qt::AltModifier) {
1567 ProcessingTabBook->setCurrentIndex(0);
1568 } else if (Event->key()==Qt::Key_2 && Event->modifiers()==Qt::AltModifier) {
1569 ProcessingTabBook->setCurrentIndex(1);
1570 } else if (Event->key()==Qt::Key_3 && Event->modifiers()==Qt::AltModifier) {
1571 ProcessingTabBook->setCurrentIndex(2);
1572 } else if (Event->key()==Qt::Key_4 && Event->modifiers()==Qt::AltModifier) {
1573 ProcessingTabBook->setCurrentIndex(3);
1574 } else if (Event->key()==Qt::Key_5 && Event->modifiers()==Qt::AltModifier) {
1575 ProcessingTabBook->setCurrentIndex(4);
1576 } else if (Event->key()==Qt::Key_6 && Event->modifiers()==Qt::AltModifier) {
1577 ProcessingTabBook->setCurrentIndex(5);
1578 } else if (Event->key()==Qt::Key_7 && Event->modifiers()==Qt::AltModifier) {
1579 ProcessingTabBook->setCurrentIndex(6);
1580 } else if (Event->key()==Qt::Key_8 && Event->modifiers()==Qt::AltModifier) {
1581 ProcessingTabBook->setCurrentIndex(7);
1582 } else if (Event->key()==Qt::Key_9 && Event->modifiers()==Qt::AltModifier) {
1583 ProcessingTabBook->setCurrentIndex(8);
1584 } else if (Event->key()==Qt::Key_Period && Event->modifiers()==Qt::NoModifier) {
1585 ProcessingTabBook->setCurrentIndex(MIN(ProcessingTabBook->currentIndex()+1,ProcessingTabBook->count()));
1586 } else if (Event->key()==Qt::Key_Comma && Event->modifiers()==Qt::NoModifier) {
1587 ProcessingTabBook->setCurrentIndex(MAX(ProcessingTabBook->currentIndex()-1,0));
1588 } else if (Event->key()==Qt::Key_T && Event->modifiers()==Qt::NoModifier) {
1589 CB_PreviewModeButton(1-Settings->GetInt("PreviewTabMode"));
1590 } else if (Event->key()==Qt::Key_0 && Event->modifiers()==Qt::NoModifier) {
1591 if (Settings->GetInt("SpecialPreview")!=ptSpecialPreview_RGB)
1592 CB_SpecialPreviewChoice(ptSpecialPreview_RGB);
1593 else ViewWindowShowStatus(ptStatus_Done);
1594 } else if (Event->key()==Qt::Key_9 && Event->modifiers()==Qt::NoModifier) {
1595 if (Settings->GetInt("SpecialPreview")!=ptSpecialPreview_Structure)
1596 CB_SpecialPreviewChoice(ptSpecialPreview_Structure);
1597 else ViewWindowShowStatus(ptStatus_Done);
1598 } else if (Event->key()==Qt::Key_8 && Event->modifiers()==Qt::NoModifier) {
1599 if (Settings->GetInt("SpecialPreview")!=ptSpecialPreview_L)
1600 CB_SpecialPreviewChoice(ptSpecialPreview_L);
1601 else ViewWindowShowStatus(ptStatus_Done);
1602 } else if (Event->key()==Qt::Key_7 && Event->modifiers()==Qt::NoModifier) {
1603 if (Settings->GetInt("SpecialPreview")!=ptSpecialPreview_A)
1604 CB_SpecialPreviewChoice(ptSpecialPreview_A);
1605 else ViewWindowShowStatus(ptStatus_Done);
1606 } else if (Event->key()==Qt::Key_6 && Event->modifiers()==Qt::NoModifier) {
1607 if (Settings->GetInt("SpecialPreview")!=ptSpecialPreview_B)
1608 CB_SpecialPreviewChoice(ptSpecialPreview_B);
1609 else ViewWindowShowStatus(ptStatus_Done);
1610 } else if (Event->key()==Qt::Key_5 && Event->modifiers()==Qt::NoModifier) {
1611 if (Settings->GetInt("SpecialPreview")!=ptSpecialPreview_Gradient)
1612 CB_SpecialPreviewChoice(ptSpecialPreview_Gradient);
1613 else ViewWindowShowStatus(ptStatus_Done);
1614 } else if (Event->key()==Qt::Key_C && Event->modifiers()==Qt::NoModifier) {
1615 Settings->SetValue("ExposureIndicator",1-Settings->GetInt("ExposureIndicator"));
1616 Update(ptProcessorPhase_Preview);
1617 // hidden tools, needs GUI implementation
1618 } else if (Event->key()==Qt::Key_H && Event->modifiers()==Qt::NoModifier) {
1619 QString Tools = "";
1620 QString Tab = "";
1621 foreach (ptTempFilterBase* GroupBox, *m_GroupBox) {
1622 if (Settings->ToolIsHidden(GroupBox->objectName())) {
1623 Tab = ProcessingTabBook->tabText(GroupBox->parentTabIdx());
1624 Tools += Tab + ": " + GroupBox->caption() + "\n";
1625 }
1626 }
1627 if (Tools == "") Tools = tr("No tools hidden!");
1628 ptMessageBox::information(this,tr("Hidden tools"),Tools);
1629 /*findChild<QWidget *>(QString("TabGenCorrections"))->
1630 setVisible(1-findChild<QWidget *>(QString("TabGenCorrections"))->isVisible()); */
1631 } else if (Event->key()==Qt::Key_U && Event->modifiers()==Qt::NoModifier) {
1632 // show hidden tools on current tab
1633 m_ContextMenuOnTab = ProcessingTabBook->currentIndex();
1634 ShowToolsOnTab();
1635 } else if (Event->key()==Qt::Key_A && Event->modifiers()==Qt::NoModifier) {
1636 ShowActiveTools();
1637 } else if (Event->key()==Qt::Key_B && Event->modifiers()==Qt::NoModifier) {
1638 QString Tools = "";
1639 QString Tab = "";
1640 foreach (ptTempFilterBase* GroupBox, *m_GroupBox) {
1641 if (GroupBox->isBlocked()) {
1642 Tab = ProcessingTabBook->tabText(GroupBox->parentTabIdx());
1643 Tools += Tab + ": " + GroupBox->caption() + "\n";
1644 }
1645 }
1646 if (Tools == "") Tools = tr("No tools blocked!");
1647 ptMessageBox::information(this,tr("Blocked tools"),Tools);
1648 } else if (Event->key()==Qt::Key_R && Event->modifiers()==(Qt::ControlModifier | Qt::ShiftModifier)) {
1649 // Ctrl+Shift+R resets to default settings
1650 ptResetSettingsToDefault();
1651 } else if (Event->key()==Qt::Key_U && Event->modifiers()==(Qt::ControlModifier | Qt::ShiftModifier)) {
1652 // Ctrl+Shift+U resets to the last saved user settings
1653 ptMakeFullUndo();
1654 } else if (Event->key()==Qt::Key_Z && Event->modifiers()==Qt::ControlModifier) {
1655 // Ctrl+Z undo
1656 ptMakeUndo();
1657 } else if (Event->key()==Qt::Key_Y && Event->modifiers()==Qt::ControlModifier) {
1658 // Ctrl+Y redo
1659 ptMakeRedo();
1660 } else if (Event->key()==Qt::Key_Z && Event->modifiers()==(Qt::ControlModifier | Qt::ShiftModifier)) {
1661 // Ctrl+Shift+Z redo
1662 ptMakeRedo();
1663 } else if (Event->key()==Qt::Key_C && Event->modifiers()==(Qt::ControlModifier | Qt::ShiftModifier)) {
1664 // Ctrl+Shift+C copy settings
1665 ptCopySettingsToClipboard();
1666 } else if (Event->key()==Qt::Key_V && Event->modifiers()==(Qt::ControlModifier | Qt::ShiftModifier)) {
1667 // Ctrl+Shift+V paste settings
1668 ptPasteSettingsFromClipboard();
1669 }
1670 }
1671 }
1672
wheelEvent(QWheelEvent * Event)1673 void ptMainWindow::wheelEvent(QWheelEvent * Event) {
1674 if (Event->delta() < 0 && ((QMouseEvent*)Event)->modifiers()==Qt::AltModifier) {
1675 ProcessingTabBook->setCurrentIndex(MIN(ProcessingTabBook->currentIndex()+1,ProcessingTabBook->count()));
1676 } else if (Event->delta() > 0 && ((QMouseEvent*)Event)->modifiers()==Qt::AltModifier) {
1677 ProcessingTabBook->setCurrentIndex(MAX(ProcessingTabBook->currentIndex()-1,0));
1678 }
1679 }
1680
1681 ////////////////////////////////////////////////////////////////////////////////
1682 //
1683 // Search and moved tools
1684 //
1685 ////////////////////////////////////////////////////////////////////////////////
1686
OnSearchResetButtonClicked()1687 void ptMainWindow::OnSearchResetButtonClicked() {
1688 OnTabProcessingButtonClicked();
1689 }
1690
1691 //==============================================================================
1692
OnSearchActiveToolsButtonClicked()1693 void ptMainWindow::OnSearchActiveToolsButtonClicked() {
1694 ShowActiveTools();
1695 }
1696
1697 //==============================================================================
1698
OnSearchAllToolsButtonClicked()1699 void ptMainWindow::OnSearchAllToolsButtonClicked() {
1700 ShowAllTools();
1701 }
1702
1703 //==============================================================================
1704
OnSearchFavouriteToolsButtonClicked()1705 void ptMainWindow::OnSearchFavouriteToolsButtonClicked() {
1706 ShowFavouriteTools();
1707 }
1708
1709 //==============================================================================
1710
StartSearchTimer(QString)1711 void ptMainWindow::StartSearchTimer(QString) {
1712 m_SearchInputTimer->start(50);
1713 }
1714
1715 //==============================================================================
1716
Search()1717 void ptMainWindow::Search() {
1718 const QString hSearchString = SearchInputWidget->text();
1719
1720 if (hSearchString == "") {
1721 OnTabProcessingButtonClicked();
1722 return;
1723 }
1724
1725 // apply changes at VisibleTools box
1726 if (MainTabBook->currentWidget() == TabSetting)
1727 ApplyVisibleTools();
1728
1729 // clean up first!
1730 if (m_MovedTools->size()>0)
1731 CleanUpMovedTools();
1732
1733 // iterate through toolboxes and remember those whose caption matches the search text
1734 for (QString hBoxName: *m_GroupBoxesOrdered) {
1735 ptTempFilterBase *hBox = m_GroupBox->value(hBoxName);
1736
1737 // remember matching toolboxes
1738 if (hBox->caption().contains(hSearchString, Qt::CaseInsensitive)) {
1739 m_MovedTools->append(hBox->guiWidget());
1740 }
1741 }
1742
1743 if (m_MovedTools->size() > 0)
1744 ShowMovedTools(tr("Search results:"));
1745 }
1746
1747 //==============================================================================
1748
ShowActiveTools()1749 void ptMainWindow::ShowActiveTools() {
1750 // apply changes at VisibleTools box
1751 if (MainTabBook->currentWidget() == TabSetting)
1752 ApplyVisibleTools();
1753
1754 // clean up first!
1755 if (m_MovedTools->size()>0) CleanUpMovedTools();
1756 SearchInputWidget->setText("");
1757
1758 for (QString hBoxName: *m_GroupBoxesOrdered) {
1759 ptTempFilterBase *hBox = m_GroupBox->value(hBoxName);
1760
1761 if (hBox->isActive())
1762 m_MovedTools->append(hBox->guiWidget());
1763 }
1764
1765 if (m_MovedTools->size() == 0) {
1766 ShowMovedTools(tr("No tools active!"));
1767 } else {
1768 ShowMovedTools(tr("Active tools:"));
1769 }
1770 }
1771
1772 //==============================================================================
1773
ShowAllTools()1774 void ptMainWindow::ShowAllTools() {
1775 // apply changes at VisibleTools box
1776 if (MainTabBook->currentWidget() == TabSetting)
1777 ApplyVisibleTools();
1778
1779 // clean up first!
1780 if (m_MovedTools->size()>0) CleanUpMovedTools();
1781 SearchInputWidget->setText("");
1782
1783 auto hHiddenTools = Settings->GetStringList("HiddenTools");
1784 for (QString hBoxName: *m_GroupBoxesOrdered) {
1785 if (!hHiddenTools.contains(hBoxName)) {
1786 m_MovedTools->append(m_GroupBox->value(hBoxName)->guiWidget());
1787 }
1788 }
1789
1790 if (m_MovedTools->size() == 0) {
1791 ShowMovedTools(tr("No tools visible!"));
1792 } else {
1793 ShowMovedTools(tr("All visible tools:"));
1794 }
1795 }
1796
1797 //==============================================================================
1798
ShowFavouriteTools()1799 void ptMainWindow::ShowFavouriteTools() {
1800 // apply changes at VisibleTools box
1801 if (MainTabBook->currentWidget() == TabSetting)
1802 ApplyVisibleTools();
1803
1804 // clean up first!
1805 if (m_MovedTools->size()>0) CleanUpMovedTools();
1806 SearchInputWidget->setText("");
1807
1808 auto hFavTools = Settings->GetStringList("FavouriteTools");
1809 for (QString hBoxName: *m_GroupBoxesOrdered) {
1810 if (hFavTools.contains(hBoxName)) {
1811 m_MovedTools->append(m_GroupBox->value(hBoxName)->guiWidget());
1812 }
1813 }
1814
1815 if (m_MovedTools->size() == 0) {
1816 ptMessageBox::information(this,tr("Favourite tools"),tr("No favourite tools!"));
1817 return;
1818 }
1819
1820 ShowMovedTools(tr("Favourite tools:"));
1821 }
1822
1823 //==============================================================================
1824
ShowMovedTools(const QString ATitle)1825 void ptMainWindow::ShowMovedTools(const QString ATitle) {
1826 ToolContainerLabel->setText(ATitle);
1827 MainTabBook->setCurrentWidget(TabMovedTools);
1828
1829 // clear previous contents from the moved tools page
1830 while (ToolContainer->layout()->count()!=0) {
1831 ToolContainer->layout()->takeAt(0);
1832 }
1833
1834 // add new tools from moved tools list
1835 for (short i=0; i<m_MovedTools->size(); i++) {
1836 ToolContainer->layout()->addWidget(m_MovedTools->at(i));
1837 }
1838
1839 static_cast<QVBoxLayout*>(ToolContainer->layout())->addStretch();
1840 static_cast<QVBoxLayout*>(ToolContainer->layout())->setSpacing(0);
1841 static_cast<QVBoxLayout*>(ToolContainer->layout())->setContentsMargins(0,0,0,0);
1842 }
1843
1844 //==============================================================================
1845
CleanUpMovedTools()1846 void ptMainWindow::CleanUpMovedTools() {
1847 for (QWidget *hToolBox: *m_MovedTools) {
1848 int hTabIdx = -1;
1849 int hIdxInTab = -1;
1850 if (QString(hToolBox->metaObject()->className()) == "ptToolBox") {
1851 auto hFilt = GFilterDM->GetFilterFromName(hToolBox->objectName());
1852 hTabIdx = hFilt->parentTabIdx();
1853 hIdxInTab = hFilt->idxInParentTab();
1854 } else if (QString(hToolBox->metaObject()->className()) == "ptGroupBox") {
1855 hTabIdx = ((ptGroupBox*)hToolBox)->GetTabNumber();
1856 hIdxInTab = ((ptGroupBox*)hToolBox)->GetIndexInTab();
1857 }
1858
1859 m_TabLayouts->at(hTabIdx)->insertWidget(hIdxInTab, hToolBox);
1860 }
1861
1862 m_MovedTools->clear();
1863 }
1864
1865 ////////////////////////////////////////////////////////////////////////////////
1866 //
1867 // UpdateToolBoxes
1868 //
1869 ////////////////////////////////////////////////////////////////////////////////
1870
UpdateToolBoxes()1871 void ptMainWindow::UpdateToolBoxes() {
1872 foreach (ptTempFilterBase* GroupBox, *m_GroupBox) {
1873 auto hGroupBox = qobject_cast<ptGroupBox*>(GroupBox);
1874 if (!hGroupBox) continue;
1875
1876 if (Settings->ToolIsHidden(hGroupBox->objectName())) {
1877 hGroupBox->hide();
1878 } else {
1879 hGroupBox->show();
1880 }
1881 hGroupBox->Update();
1882 }
1883
1884 // disable Raw tools when we have a bitmap
1885 QList<ptGroupBox *> m_RawTools;
1886 m_RawTools << static_cast<ptGroupBox*>(m_GroupBox->value("TabCameraColorSpace"))
1887 << static_cast<ptGroupBox*>(m_GroupBox->value("TabGenCorrections"))
1888 << static_cast<ptGroupBox*>(m_GroupBox->value("TabWhiteBalance"))
1889 << static_cast<ptGroupBox*>(m_GroupBox->value("TabDemosaicing"))
1890 << static_cast<ptGroupBox*>(m_GroupBox->value("TabHighlightRecovery"));
1891 bool hTemp = Settings->useRAWHandling();
1892 for (int i = 0; i < m_RawTools.size(); i++) {
1893 m_RawTools.at(i)->SetEnabled(hTemp);
1894 }
1895
1896 // disable tools when we are in detail view
1897 QList<ptGroupBox *> m_DetailViewTools;
1898 m_DetailViewTools << static_cast<ptGroupBox*>(m_GroupBox->value("TabLensfunCA"))
1899 << static_cast<ptGroupBox*>(m_GroupBox->value("TabLensfunVignette"))
1900 << static_cast<ptGroupBox*>(m_GroupBox->value("TabLensfunDistortion"))
1901 << static_cast<ptGroupBox*>(m_GroupBox->value("TabLensfunGeometry"))
1902 << static_cast<ptGroupBox*>(m_GroupBox->value("TabDefish"))
1903 << static_cast<ptGroupBox*>(m_GroupBox->value("TabCrop"))
1904 << static_cast<ptGroupBox*>(m_GroupBox->value("TabLiquidRescale"))
1905 << static_cast<ptGroupBox*>(m_GroupBox->value("TabResize"))
1906 << static_cast<ptGroupBox*>(m_GroupBox->value("TabWebResize"));
1907
1908 hTemp = !(Settings->GetInt("DetailViewActive") == 1);
1909 for (int i = 0; i < m_DetailViewTools.size(); i++) {
1910 m_DetailViewTools.at(i)->SetEnabled(hTemp);
1911 }
1912 }
1913
1914 ////////////////////////////////////////////////////////////////////////////////
1915 //
1916 // UpdateSettings()
1917 //
1918 // Adapt the Gui elements according to GuiSettings
1919 // (for those gui elements that should be updated after a programmatic
1920 // recalculation)
1921 //
1922 ////////////////////////////////////////////////////////////////////////////////
1923
1924 // #define SHOW_BT
1925 #ifdef SHOW_BT
1926 extern "C" {
1927 #include <execinfo.h>
1928 }
1929 #endif
1930
UpdateSettings()1931 void ptMainWindow::UpdateSettings() {
1932
1933 #ifdef SHOW_BT
1934
1935 {
1936 void *array[10];
1937 size_t size;
1938 char **strings;
1939 size_t i;
1940 size = backtrace(array,10);
1941 strings = backtrace_symbols (array, size);
1942 printf ("Obtained %zd stack frames.\n", size);
1943 for (i = 0; i < size; i++)
1944 printf ("%s\n", strings[i]);
1945 free (strings);
1946 }
1947 #endif
1948
1949 // State of Groupboxes
1950 foreach (ptTempFilterBase* GroupBox, *m_GroupBox) {
1951 auto hGroupBox = qobject_cast<ptGroupBox*>(GroupBox);
1952 if (hGroupBox)
1953 hGroupBox->SetActive(Settings->ToolIsActive(hGroupBox->objectName()));
1954 }
1955
1956 // Status LED on tabs
1957 if(Settings->GetInt("TabStatusIndicator")) {
1958 ProcessingTabBook->setIconSize(QSize(Settings->GetInt("TabStatusIndicator"),
1959 Settings->GetInt("TabStatusIndicator")));
1960 QList <ptGroupBox *> Temp;
1961 for (int j=0; j<m_ActiveTabs.size();j++) {
1962 bool hIsActiveTab = GFilterDM->isActiveCacheGroup(j+1); // +1 because Camera tab is not
1963 if (!hIsActiveTab) { // in m_ActiveTabs
1964 Temp = m_ActiveTabs.at(j)->findChildren <ptGroupBox *> ();
1965 for (int i=0; i<Temp.size();i++) {
1966 if(Settings->ToolIsActive(Temp.at(i)->objectName())) {
1967 hIsActiveTab = true;
1968 break;
1969 }
1970 }
1971 }
1972
1973 if (hIsActiveTab)
1974 ProcessingTabBook->setTabIcon(ProcessingTabBook->indexOf(m_ActiveTabs.at(j)),m_StatusIcon);
1975 else
1976 ProcessingTabBook->setTabIcon(ProcessingTabBook->indexOf(m_ActiveTabs.at(j)),QIcon());
1977 }
1978 } else {
1979 for (int j=0; j<m_ActiveTabs.size();j++)
1980 ProcessingTabBook->setTabIcon(ProcessingTabBook->indexOf(m_ActiveTabs.at(j)),QIcon());
1981 }
1982
1983
1984 // New Camera Color Space or profile ?
1985 int TmpCameraColor = Settings->GetInt("CameraColor");
1986 if (TmpCameraColor == ptCameraColor_Adobe_Profile) {
1987 Settings->SetEnabled("CameraColorProfileIntent",1);
1988 Settings->SetEnabled("CameraColorGamma",0);
1989 CameraColorProfileText->setEnabled(1);
1990 } else if (TmpCameraColor == ptCameraColor_Profile) {
1991 Settings->SetEnabled("CameraColorProfileIntent",1);
1992 Settings->SetEnabled("CameraColorGamma",1);
1993 CameraColorProfileText->setEnabled(1);
1994 } else if (TmpCameraColor == ptCameraColor_Flat) {
1995 Settings->SetEnabled("CameraColorProfileIntent",1);
1996 Settings->SetEnabled("CameraColorGamma",1);
1997 CameraColorProfileText->setEnabled(1);
1998 } else {
1999 Settings->SetEnabled("CameraColorProfileIntent",0);
2000 Settings->SetEnabled("CameraColorGamma",0);
2001 CameraColorProfileText->setEnabled(0);
2002 }
2003
2004 Settings->SetEnabled("CaRed",Settings->GetInt("CaCorrect")==ptCACorrect_Manual);
2005 Settings->SetEnabled("CaBlue",Settings->GetInt("CaCorrect")==ptCACorrect_Manual);
2006
2007 QFileInfo PathInfo(Settings->GetString("CameraColorProfile"));
2008 QString ShortFileName = PathInfo.baseName();
2009 CameraColorProfileText->setText(ShortFileName);
2010 // End CameraColorChoice.
2011
2012
2013 // Preview Color Profile.
2014 PathInfo.setFile(Settings->GetString("PreviewColorProfile"));
2015 ShortFileName = PathInfo.baseName();
2016 PreviewColorProfileText->setText(ShortFileName);
2017
2018 bool Temp = Settings->GetInt("CMQuality") != ptCMQuality_FastSRGB;
2019 Settings->SetEnabled("PreviewColorProfileIntent", Temp);
2020 PreviewProfileWidget->setEnabled(Temp);
2021 // End Preview Color Profile.
2022
2023 // Preview Color Profile.
2024 PathInfo.setFile(Settings->GetString("OutputColorProfile"));
2025 ShortFileName = PathInfo.baseName();
2026 OutputColorProfileText->setText(ShortFileName);
2027 // End Preview Color Profile.
2028
2029 // GimpExecCommand
2030 PathInfo.setFile(Settings->GetString("GimpExecCommand"));
2031 ShortFileName = PathInfo.fileName();
2032 GimpExecCommandText->setText(ShortFileName);
2033 // GimpExecCommand
2034
2035 // StartupSettings
2036 PathInfo.setFile(Settings->GetString("StartupSettingsFile"));
2037 ShortFileName = PathInfo.baseName();
2038 StartupSettingsText->setText(ShortFileName);
2039 // StartupSettings
2040
2041 // New BlackPoint ?
2042 Settings->SetEnabled("BlackPoint",Settings->GetInt("ManualBlackPoint"));
2043 // End BlackPoint
2044
2045 // New WhitePoint ?
2046 Settings->SetEnabled("WhitePoint",Settings->GetInt("ManualWhitePoint"));
2047 // End WhitePoint
2048
2049 // New BadPixels ?
2050 if (Settings->GetInt("HaveBadPixels") == 2) {
2051 // Small routine that lets Shortfilename point to the basename.
2052 QFileInfo PathInfo(Settings->GetString("BadPixelsFileName"));
2053 QString ShortFileName = PathInfo.baseName();
2054 Settings->AddOrReplaceOption("BadPixels",ShortFileName,QVariant(2));
2055 }
2056 Settings->SetValue("BadPixels",Settings->GetInt("HaveBadPixels"));
2057 // End BadPixels.
2058
2059 // New DarkFrame ?
2060 if (Settings->GetInt("HaveDarkFrame") == 2) {
2061 // Small routine that lets Shortfilename point to the basename.
2062 QFileInfo PathInfo(Settings->GetString("DarkFrameFileName"));
2063 QString ShortFileName = PathInfo.baseName();
2064 Settings->AddOrReplaceOption("DarkFrame",ShortFileName,QVariant(2));
2065 }
2066 Settings->SetValue("DarkFrame",Settings->GetInt("HaveDarkFrame"));
2067 // End DarkFrame.
2068
2069 // New White balances,due to photo from other camera ?
2070 // Also the CameraMake model for lensfun is adapted.
2071 if (m_CameraMake != Settings->GetString("CameraMake")
2072 ||
2073 m_CameraModel != Settings->GetString("CameraModel") ) {
2074
2075 m_CameraMake = Settings->GetString("CameraMake");
2076 m_CameraModel = Settings->GetString("CameraModel");
2077 // New white balances !
2078 // First clear the whole WhiteBalanceChoice
2079 Settings->ClearOptions("WhiteBalance", 1);
2080
2081 // Add the camera dependent custom ones.
2082 // First calculate which index our camera has int ptWhiteBalances.
2083 short WBIdx = 4; // To jump over the first 4 standard ones.
2084 while ( !ptWhiteBalances[WBIdx].m_Make.isEmpty()
2085 &&
2086 ( ptWhiteBalances[WBIdx].m_Make != m_CameraMake
2087 ||
2088 ptWhiteBalances[WBIdx].m_Model != m_CameraModel
2089 )
2090 ) {
2091 WBIdx++;
2092 }
2093 // And then add the custom whitebalances.
2094 while (ptWhiteBalances[WBIdx].m_Make == m_CameraMake
2095 &&
2096 ptWhiteBalances[WBIdx].m_Model == m_CameraModel){
2097 Settings->AddOrReplaceOption("WhiteBalance",
2098 ptWhiteBalances[WBIdx].m_Name,
2099 QVariant(WBIdx));
2100 WBIdx++;
2101 }
2102 }
2103
2104 // Setting for interpolation passes only on DCB needed
2105
2106 if (Settings->GetInt("Interpolation")==ptInterpolation_DCB ||
2107 Settings->GetInt("Interpolation")==ptInterpolation_DCBSoft ||
2108 Settings->GetInt("Interpolation")==ptInterpolation_DCBSharp)
2109 Settings->SetEnabled("InterpolationPasses",1);
2110 else
2111 Settings->SetEnabled("InterpolationPasses",0);
2112
2113 // Preview Mode
2114 PreviewModeButton->setChecked(Settings->GetInt("PreviewMode"));
2115
2116 // Run mode
2117 RunButton->setEnabled(Settings->GetInt("RunMode"));
2118
2119 // PizeSize Widget
2120 PipeSizeWidget->setEnabled(1-
2121 (Settings->GetInt("AutomaticPipeSize") &&
2122 Settings->ToolIsActive("TabResize")));
2123
2124 // Show containers
2125 BottomContainer->setVisible(Settings->GetInt("ShowBottomContainer"));
2126 ControlFrame->setVisible(Settings->GetInt("ShowToolContainer"));
2127
2128 // Geometry
2129 ResizeHeightWidget->setVisible(Settings->GetInt("ResizeDimension") == ptResizeDimension_WidthHeight);
2130
2131 // sRGB gamma compensation
2132 Settings->SetEnabled("OutputGamma",Settings->GetInt("OutputGammaCompensation"));
2133 Settings->SetEnabled("OutputLinearity",Settings->GetInt("OutputGammaCompensation"));
2134
2135 // Save options
2136 if (Settings->GetInt("SaveFormat")==ptSaveFormat_JPEG)
2137 Settings->SetEnabled("SaveSampling",1);
2138 else
2139 Settings->SetEnabled("SaveSampling",0);
2140
2141 if (Settings->GetInt("SaveFormat")==ptSaveFormat_JPEG ||
2142 Settings->GetInt("SaveFormat")==ptSaveFormat_PNG ||
2143 Settings->GetInt("SaveFormat")==ptSaveFormat_PNG16)
2144 Settings->SetEnabled("SaveQuality",1);
2145 else
2146 Settings->SetEnabled("SaveQuality",0);
2147
2148 // Statusbar : photo
2149 QStringList InputFileNameList = Settings->GetStringList("InputFileNameList");
2150 if (InputFileNameList.count() > 0) {
2151 PathInfo.setFile(InputFileNameList[0]);
2152 ShortFileName = PathInfo.fileName();
2153
2154 QString Tmp = "";
2155 QString Report = "";
2156 Report += Tmp.setNum(Settings->GetInt("ImageW"));
2157 Report += " x ";
2158 Report += Tmp.setNum(Settings->GetInt("ImageH"));
2159 Report += " ";
2160 SizeFullLabel->setText(Report);
2161
2162 int TmpScaled = Settings->GetInt("Scaled");
2163
2164 Report = "";
2165 Report += Tmp.setNum(Settings->GetInt("PipeImageW") << TmpScaled);
2166 Report += " x ";
2167 Report += Tmp.setNum(Settings->GetInt("PipeImageH") << TmpScaled);
2168 Report += " ";
2169 SizeFullCropLabel->setText(Report);
2170
2171 Report = "";
2172 Report += Tmp.setNum(Settings->GetInt("PipeImageW"));
2173 Report += " x ";
2174 Report += Tmp.setNum(Settings->GetInt("PipeImageH"));
2175 Report += " ";
2176 SizeCurrentLabel->setText(Report);
2177
2178 } else {
2179 // Startup.
2180
2181 }
2182 }
2183
2184 //==============================================================================
2185 // Display strings from settings
Settings_2_Form()2186 void ptMainWindow::Settings_2_Form() {
2187 if (Settings->GetInt("JobMode") == 1) return;
2188
2189 // Metadata
2190 edtOutputSuffix->setText(Settings->GetString("OutputFileNameSuffix"));
2191 edtImageTitle->setText(Settings->GetString("ImageTitle"));
2192 edtCopyright->setText( Settings->GetString("Copyright"));
2193 }
2194
2195 //==============================================================================
2196 // Read settings from Form
Form_2_Settings()2197 void ptMainWindow::Form_2_Settings() {
2198 if (Settings->GetInt("JobMode") == 1) return;
2199
2200 //Metadata
2201 Settings->SetValue("OutputFileNameSuffix", edtOutputSuffix->text().trimmed());
2202 Settings->SetValue("ImageTitle", edtImageTitle->text().trimmed());
2203 Settings->SetValue("Copyright", edtCopyright->text().trimmed());
2204 }
2205
2206 ////////////////////////////////////////////////////////////////////////////////
2207
UpdateFilenameInfo(const QStringList FileNameList)2208 void ptMainWindow::UpdateFilenameInfo(const QStringList FileNameList) {
2209 QFileInfo fn(FileNameList[0]);
2210 if (FileNameList.length() > 0 ) {
2211 FileNameLabel->setText(fn.fileName());
2212 #ifdef Q_OS_WIN
2213 FilePathLabel->setText(fn.canonicalPath().replace(QString("/"), QString("\\")));
2214 #else
2215 FilePathLabel->setText(fn.canonicalPath());
2216 #endif
2217 } else {
2218 FileNameLabel->setText("");
2219 FilePathLabel->setText("");
2220 }
2221 }
2222
2223
2224 ////////////////////////////////////////////////////////////////////////////////
2225 //
2226 // UpdateExifInfo()
2227 // Update the exif info gui element.
2228 // TODO Optimize : slow.
2229 //
2230 ////////////////////////////////////////////////////////////////////////////////
2231
UpdateExifInfo(Exiv2::ExifData ExifData)2232 void ptMainWindow::UpdateExifInfo(Exiv2::ExifData ExifData) {
2233
2234 // Exif info for the info window (the previous infowindow)
2235
2236 Exiv2::ExifData::iterator Pos;
2237 QString TheInfo;
2238 QString TempString = "";
2239
2240 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Image.Make"));
2241 if (Pos != ExifData.end() ) {
2242 std::stringstream str;
2243 str << *Pos;
2244 TheInfo.append(QString(str.str().c_str()));
2245 }
2246 while (TheInfo.endsWith(" ")) TheInfo.chop(1);
2247 TempString = TheInfo +": ";
2248 TheInfo="";
2249
2250 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Image.Model"));
2251 if (Pos != ExifData.end() ) {
2252 std::stringstream str;
2253 str << *Pos;
2254 TheInfo.append(QString(str.str().c_str()));
2255 }
2256 TempString = TempString + TheInfo;
2257 InfoCameraLabel->setText(TempString);
2258 TheInfo="";
2259
2260 // Idea from UFRaw
2261 if (ExifData.findKey(Exiv2::ExifKey("Exif.Image.LensInfo")) != ExifData.end() ) {
2262 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Image.LensInfo"));
2263 std::stringstream str;
2264 str << *Pos;
2265 TheInfo.append(QString(str.str().c_str()));
2266 } else if (ExifData.findKey(Exiv2::ExifKey("Exif.Nikon3.LensData")) != ExifData.end() ) {
2267 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Nikon3.LensData"));
2268 std::stringstream str;
2269 str << *Pos;
2270 TheInfo.append(QString(str.str().c_str()));
2271 } else if (ExifData.findKey(Exiv2::ExifKey("Exif.Nikon3.Lens")) != ExifData.end() ) {
2272 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Nikon3.Lens"));
2273 std::stringstream str;
2274 str << *Pos;
2275 TheInfo.append(QString(str.str().c_str()));
2276 #if EXIV2_TEST_VERSION(0,17,91) /* Exiv2 0.18-pre1 */
2277 } else if (ExifData.findKey(Exiv2::ExifKey("Exif.CanonCs.LensType")) != ExifData.end() ) {
2278 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.CanonCs.LensType"));
2279 std::stringstream str;
2280 str << *Pos;
2281 TheInfo.append(QString(str.str().c_str()));
2282 #endif
2283 } else if (ExifData.findKey(Exiv2::ExifKey("Exif.Canon.0x0095")) != ExifData.end() ) {
2284 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Canon.0x0095"));
2285 std::stringstream str;
2286 str << *Pos;
2287 TheInfo.append(QString(str.str().c_str()));
2288 } else if (ExifData.findKey(Exiv2::ExifKey("Exif.Minolta.LensID")) != ExifData.end() ) {
2289 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Minolta.LensID"));
2290 std::stringstream str;
2291 str << *Pos;
2292 TheInfo.append(QString(str.str().c_str()));
2293 #if EXIV2_TEST_VERSION(0,16,0)
2294 } else if (ExifData.findKey(Exiv2::ExifKey("Exif.Pentax.LensType")) != ExifData.end() ) {
2295 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Pentax.LensType"));
2296 std::stringstream str;
2297 str << *Pos;
2298 TheInfo.append(QString(str.str().c_str()));
2299 #endif
2300 } else if (ExifData.findKey(Exiv2::ExifKey("Exif.OlympusEq.LensType")) != ExifData.end() ) {
2301 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.OlympusEq.LensType"));
2302 std::stringstream str;
2303 str << *Pos;
2304 TheInfo.append(QString(str.str().c_str()));
2305 } else if (ExifData.findKey(Exiv2::ExifKey("Exif.Panasonic.LensType")) != ExifData.end() ) {
2306 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Panasonic.LensType"));
2307 std::stringstream str;
2308 str << *Pos;
2309 TheInfo.append(QString(str.str().c_str()));
2310 }
2311 InfoLensLabel->setText(TheInfo);
2312 TheInfo="";
2313
2314 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Photo.DateTimeOriginal"));
2315 if (Pos != ExifData.end() ) {
2316 std::stringstream str;
2317 str << *Pos;
2318 TheInfo.append(QString(str.str().c_str()));
2319 }
2320 InfoTimeLabel->setText(TheInfo);
2321 TheInfo="";
2322
2323 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Photo.ExposureTime"));
2324 if (Pos != ExifData.end() ) {
2325 std::stringstream str;
2326 str << *Pos;
2327 TheInfo.append(QString(str.str().c_str()));
2328 } else {
2329 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Photo.ShutterSpeedValue"));
2330 if (Pos != ExifData.end() ) {
2331 std::stringstream str;
2332 str << *Pos;
2333 TheInfo.append(QString(str.str().c_str()));
2334 }
2335 }
2336 TempString = TheInfo + tr(" at ");
2337 TheInfo="";
2338
2339 Settings->SetValue("ApertureFromExif", 0.0);
2340 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Photo.FNumber"));
2341 if (Pos != ExifData.end() ) {
2342 std::stringstream str;
2343 str << *Pos;
2344 Settings->SetValue("ApertureFromExif", QString(str.str().c_str()).remove("F", Qt::CaseInsensitive).toDouble());
2345 TheInfo.append(QString(str.str().c_str()));
2346 } else {
2347 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Photo.ApertureValue"));
2348 if (Pos != ExifData.end() ) {
2349 std::stringstream str;
2350 str << *Pos;
2351 Settings->SetValue("ApertureFromExif", QString(str.str().c_str()).remove("F", Qt::CaseInsensitive).toDouble());
2352 TheInfo.append(QString(str.str().c_str()));
2353 }
2354 }
2355 TempString = TempString + TheInfo + tr(" with ISO ");
2356 TheInfo="";
2357
2358 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Photo.ISOSpeedRatings"));
2359 if (Pos != ExifData.end() ) {
2360 std::stringstream str;
2361 str << *Pos;
2362 TheInfo.append(QString(str.str().c_str()));
2363 }
2364 if (TheInfo == "" || TheInfo == " ") TheInfo = "NN";
2365 TempString = TempString + TheInfo;
2366 InfoExposureLabel->setText(TempString);
2367 TheInfo="";
2368
2369 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Photo.FocalLength"));
2370 if (Pos != ExifData.end() ) {
2371 std::stringstream str;
2372 str << *Pos;
2373 TheInfo.append(QString(str.str().c_str()));
2374 }
2375 if (TheInfo != "" && TheInfo != " ") {
2376 // save focal length (need 35mm equiv.)
2377 QString FL = TheInfo;
2378 while(FL.endsWith("m") || FL.endsWith(" ")) FL.chop(1);
2379 if (FL.toFloat() >= 4.0f && FL.toFloat() <= 6000.0f)
2380 Settings->SetValue("FocalLengthIn35mmFilm",FL.toFloat());
2381 else
2382 Settings->SetValue("FocalLengthIn35mmFilm",50.0);
2383 } else {
2384 Settings->SetValue("FocalLengthIn35mmFilm",50.0);
2385 }
2386 TempString = TheInfo;
2387 TheInfo="";
2388
2389 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Photo.FocalLengthIn35mmFilm"));
2390 if (Pos != ExifData.end() ) {
2391 std::stringstream str;
2392 str << *Pos;
2393 TheInfo.append(QString(str.str().c_str()));
2394 }
2395 if (TheInfo != "" && TheInfo != " " && TheInfo != TempString ) {
2396 TempString = TempString + tr(" (35mm equiv.: ") + TheInfo + ")";
2397 // save focal length (crop camera!)
2398 QString FL = TheInfo;
2399 while(FL.endsWith("m") || FL.endsWith(" ")) FL.chop(1);
2400 if (FL.toFloat() >= 4.0f && FL.toFloat() <= 6000.0f)
2401 Settings->SetValue("FocalLengthIn35mmFilm",FL.toFloat());
2402 else
2403 Settings->SetValue("FocalLengthIn35mmFilm",50.0);
2404 }
2405 InfoFocalLengthLabel->setText(TempString);
2406 TheInfo="";
2407
2408 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Photo.Flash"));
2409 if (Pos != ExifData.end() ) {
2410 std::stringstream str;
2411 str << *Pos;
2412 TheInfo.append(QString::fromLocal8Bit(str.str().c_str()));
2413 }
2414 InfoFlashLabel->setText(TheInfo);
2415 TheInfo="";
2416
2417 Pos = ExifData.findKey(Exiv2::ExifKey("Exif.Photo.WhiteBalance"));
2418 if (Pos != ExifData.end() ) {
2419 std::stringstream str;
2420 str << *Pos;
2421 TheInfo.append(QString::fromLocal8Bit(str.str().c_str()));
2422 }
2423 InfoWhitebalanceLabel->setText(TheInfo);
2424 TheInfo="";
2425
2426 // dcraw Data
2427 TheInfo = Settings->GetString("CameraMake") + ": " + Settings->GetString("CameraModel");
2428 InfoDcrawLabel->setText(TheInfo);
2429 }
2430
2431 //==============================================================================
2432
2433
2434 ////////////////////////////////////////////////////////////////////////////////
2435 //
2436 // UpdateCropToolUI
2437 //
2438 ////////////////////////////////////////////////////////////////////////////////
2439
UpdateCropToolUI()2440 void ptMainWindow::UpdateCropToolUI() {
2441 bool OnOff = false;
2442 if (ViewWindow != NULL) { // when called from MainWindow constructor, ViewWindow doesn't yet exist
2443 if (ViewWindow->interaction() == iaCrop) {
2444 OnOff = true;
2445 }
2446 }
2447 CropWidget->setEnabled(!OnOff);
2448 MakeCropButton->setVisible(!OnOff);
2449 ConfirmCropButton->setVisible(OnOff);
2450 CancelCropButton->setVisible(OnOff);
2451 CropCenterHorButton->setVisible(OnOff);
2452 CropCenterVertButton->setVisible(OnOff);
2453
2454 if (Settings->GetInt("FixedAspectRatio") != 0) {
2455 AspectRatioWLabel->setEnabled(true);
2456 AspectRatioHLabel->setEnabled(true);
2457 AspectRatioWWidget->setEnabled(true);
2458 AspectRatioHWidget->setEnabled(true);
2459 } else {
2460 AspectRatioWLabel->setEnabled(false);
2461 AspectRatioHLabel->setEnabled(false);
2462 AspectRatioWWidget->setEnabled(false);
2463 AspectRatioHWidget->setEnabled(false);
2464 }
2465 }
2466
2467
2468 ////////////////////////////////////////////////////////////////////////////////
2469 //
2470 // InitVisibleTools
2471 //
2472 ////////////////////////////////////////////////////////////////////////////////
2473
InitVisibleTools()2474 void ptMainWindow::InitVisibleTools() {
2475 m_VisibleToolsModel = new ptVisibleToolsModel;
2476
2477 // fill items corresponding to tabs
2478 for (int i=0; i < ProcessingTabBook->count(); i++) {
2479 QStandardItem *topItem = new QStandardItem(ProcessingTabBook->tabText(i));
2480 topItem->setFlags(Qt::NoItemFlags);
2481 m_VisibleToolsModel->appendRow(topItem);
2482 }
2483
2484 QStringList hiddenTools = Settings->GetStringList("HiddenTools");
2485 QStringList favouriteTools = Settings->GetStringList("FavouriteTools");
2486
2487 foreach (QString hBoxName, *m_GroupBoxesOrdered) {
2488 auto hFilt = m_GroupBox->value(hBoxName);
2489 auto item = new QStandardItem(hFilt->caption());
2490
2491 // set tool state and corresponding icon will be set automatically
2492 if (hiddenTools.contains(hBoxName))
2493 item->setData(tsHidden, Qt::UserRole+1);
2494 else
2495 if (favouriteTools.contains(hBoxName))
2496 item->setData(tsFavourite, Qt::UserRole+1);
2497 else
2498 item->setData(tsNormal, Qt::UserRole+1);
2499
2500 // check if tool can be hidden and set corresponding flag
2501 if (hFilt->canHide())
2502 item->setData(0, Qt::UserRole+2);
2503 else
2504 item->setData(1, Qt::UserRole+2);
2505
2506 m_VisibleToolsModel->item(hFilt->parentTabIdx())->appendRow(item);
2507 }
2508
2509 // connect model with Visible Tools View
2510 VisibleToolsView->setModel(m_VisibleToolsModel);
2511 VisibleToolsView->setEditTriggers(QAbstractItemView::CurrentChanged |
2512 QAbstractItemView::DoubleClicked);
2513 VisibleToolsView->setItemDelegate(new ptVisibleToolsItemDelegate);
2514 }
2515
2516 //==============================================================================
2517
SwitchUIState(const ptUIState AState)2518 void ptMainWindow::SwitchUIState(const ptUIState AState)
2519 {
2520 if (FUIState == AState) return;
2521
2522 FUIState = AState;
2523
2524 switch (AState) {
2525 case uisProcessing:
2526 // Processing
2527 MainStack->setCurrentWidget(ProcessingPage);
2528 Settings->SetValue("FileMgrIsOpen", 0);
2529 Settings->SetValue("BatchIsOpen", 0);
2530 break;
2531 case uisFileMgr:
2532 // Filemanager
2533 #ifndef PT_WITHOUT_FILEMGR
2534 MainStack->setCurrentWidget(FileManagerPage);
2535 Settings->SetValue("FileMgrIsOpen", 1);
2536 #endif
2537 break;
2538 case uisBatch:
2539 MainStack->setCurrentWidget(BatchPage);
2540 Settings->SetValue("BatchIsOpen", 1);
2541 break;
2542 default:
2543 GInfo->Raise("Unknown UI state", AT);
2544 }
2545 }
2546
2547 ////////////////////////////////////////////////////////////////////////////////
2548 //
2549 // ApplyVisibleTools
2550 //
2551 ////////////////////////////////////////////////////////////////////////////////
2552
ApplyVisibleTools()2553 void ptMainWindow::ApplyVisibleTools() {
2554 QString FirstActive;
2555
2556 foreach (QString hBoxName, *m_GroupBoxesOrdered) {
2557 auto hFilt = m_GroupBox->value(hBoxName);
2558 auto hToolBox = hFilt->guiWidget();
2559
2560 // find all items with necessary name (in different tabs)
2561 QList<QStandardItem *> itemList =
2562 m_VisibleToolsModel->findItems(hFilt->caption(), Qt::MatchExactly | Qt::MatchRecursive);
2563
2564 // find item corresponding to proper tab (maybe their is a simplier way)
2565 QStandardItem *item = NULL;
2566 foreach (QStandardItem *it, itemList) {
2567 QString tabName = ProcessingTabBook->tabText(hFilt->parentTabIdx());
2568 if (m_VisibleToolsModel->indexFromItem(it).parent() ==
2569 m_VisibleToolsModel->indexFromItem(
2570 m_VisibleToolsModel->findItems(tabName, Qt::MatchExactly).first()) )
2571 {
2572 item = it;
2573 break;
2574 }
2575 }
2576
2577 // hide/show tools according to state
2578 if (item->data(Qt::UserRole+1).toInt() == tsHidden) {
2579 QStringList hiddenTools = Settings->GetStringList("HiddenTools");
2580 // hide tool if it was visible
2581 if (!hiddenTools.contains(hBoxName)) {
2582 hiddenTools.append(hBoxName);
2583 hToolBox->hide();
2584 // find first active tool, which changes it's state
2585 if (hFilt->isActive() && FirstActive.size() == 0)
2586 FirstActive = hBoxName;
2587 Settings->SetValue("HiddenTools", hiddenTools);
2588 }
2589
2590 QStringList favouriteTools = Settings->GetStringList("FavouriteTools");
2591 if (favouriteTools.contains(hBoxName)) {
2592 favouriteTools.removeAll(hBoxName);
2593 Settings->SetValue("FavouriteTools", favouriteTools);
2594 }
2595 }
2596
2597 if (item->data(Qt::UserRole+1).toInt() == tsFavourite) {
2598 QStringList favouriteTools = Settings->GetStringList("FavouriteTools");
2599 if (!favouriteTools.contains(hBoxName)) {
2600 favouriteTools.append(hBoxName);
2601 Settings->SetValue("FavouriteTools", favouriteTools);
2602 }
2603
2604 QStringList hiddenTools = Settings->GetStringList("HiddenTools");
2605 // show tool if it was hidden
2606 if (hiddenTools.contains(hBoxName)) {
2607 hiddenTools.removeAll(hBoxName);
2608 hToolBox->show();
2609 Settings->SetValue("HiddenTools", hiddenTools);
2610 // find first active tool, which changes it's state
2611 if (hFilt->isActive() && FirstActive.size() == 0)
2612 FirstActive = hBoxName;
2613 }
2614 }
2615
2616 if (item->data(Qt::UserRole+1).toInt() == tsNormal) {
2617 QStringList hiddenTools = Settings->GetStringList("HiddenTools");
2618 // show tool if it was hidden
2619 if (hiddenTools.contains(hBoxName)) {
2620 hiddenTools.removeAll(hBoxName);
2621 hToolBox->show();
2622 Settings->SetValue("HiddenTools", hiddenTools);
2623 // find first active tool, which changes it's state
2624 if (hFilt->isActive() && FirstActive.size() == 0)
2625 FirstActive = hBoxName;
2626 }
2627
2628 QStringList favouriteTools = Settings->GetStringList("FavouriteTools");
2629 if (favouriteTools.contains(hBoxName)) {
2630 favouriteTools.removeAll(hBoxName);
2631 Settings->SetValue("FavouriteTools", favouriteTools);
2632 }
2633 }
2634 }
2635
2636 // Image need to be updated, if active tools have changed their state
2637 if (FirstActive.size() != 0)
2638 Update(FirstActive);
2639 }
2640
2641
2642 ////////////////////////////////////////////////////////////////////////////////
2643 //
2644 // UpdateVisibleTools
2645 //
2646 ////////////////////////////////////////////////////////////////////////////////
2647
UpdateVisibleTools()2648 void ptMainWindow::UpdateVisibleTools() {
2649 QStringList hiddenTools = Settings->GetStringList("HiddenTools");
2650 QStringList favouriteTools = Settings->GetStringList("FavouriteTools");
2651
2652 foreach (QString itGroupBox, *m_GroupBoxesOrdered) {
2653 auto hFilt = m_GroupBox->value(itGroupBox);
2654
2655 // find all TreeItems with necessary name (in different tabs)
2656 QList<QStandardItem *> itemList =
2657 m_VisibleToolsModel->findItems(hFilt->caption(), Qt::MatchExactly | Qt::MatchRecursive);
2658
2659 // find item corresponding to proper tab (maybe there is a simpler way)
2660 QStandardItem *item = NULL;
2661 foreach (QStandardItem *it, itemList) {
2662 QString tabName = ProcessingTabBook->tabText(hFilt->parentTabIdx());
2663 if (m_VisibleToolsModel->indexFromItem(it).parent() ==
2664 m_VisibleToolsModel->indexFromItem(
2665 m_VisibleToolsModel->findItems(tabName, Qt::MatchExactly).first() ))
2666 {
2667 item = it;
2668 break;
2669 }
2670 }
2671
2672 // set tool state and corresponding icon will be set automatically
2673 if (hiddenTools.contains(itGroupBox)) {
2674 m_VisibleToolsModel->setData(m_VisibleToolsModel->indexFromItem(item),
2675 tsHidden, Qt::UserRole+1);
2676 } else {
2677 if (favouriteTools.contains(itGroupBox)) {
2678 m_VisibleToolsModel->setData(m_VisibleToolsModel->indexFromItem(item),
2679 tsFavourite, Qt::UserRole+1);
2680 } else {
2681 m_VisibleToolsModel->setData(m_VisibleToolsModel->indexFromItem(item),
2682 tsNormal, Qt::UserRole+1);
2683 }
2684 }
2685
2686 // check if tool can be hidden and set corresponding flag
2687 if (Settings->ToolAlwaysVisible(itGroupBox))
2688 m_VisibleToolsModel->setData(m_VisibleToolsModel->indexFromItem(item), 1, Qt::UserRole+2);
2689 else
2690 m_VisibleToolsModel->setData(m_VisibleToolsModel->indexFromItem(item), 0, Qt::UserRole+2);
2691 }
2692 }
2693
2694
2695 ////////////////////////////////////////////////////////////////////////////////
2696 //
2697 // LoadUISettings
2698 //
2699 ////////////////////////////////////////////////////////////////////////////////
2700
LoadUISettings(const QString & fileName)2701 void ptMainWindow::LoadUISettings(const QString &fileName) {
2702 QSettings UISettings(fileName, QSettings::IniFormat);
2703 UISettings.sync();
2704
2705 if (UISettings.status() != QSettings::NoError) {
2706 ptMessageBox::critical(0, "Error", "Error reading UI file\n" + fileName);
2707 return;
2708 }
2709 if (UISettings.value("Magic") != "photivoUIFile") {
2710 ptMessageBox::warning(0, "Error", fileName + "\nis not an UI file.");
2711 return;
2712 }
2713
2714 Settings->SetValue("FavouriteTools", UISettings.value("FavouriteTools").toStringList());
2715
2716 QStringList hOldHidden = Settings->GetStringList("HiddenTools");
2717 QStringList hNewHidden = UISettings.value("HiddenTools").toStringList();
2718 QStringList Temp = hNewHidden;
2719
2720 // find difference between previous and current hidden tools list
2721 hOldHidden.removeDuplicates();
2722 hNewHidden.removeDuplicates();
2723 foreach (QString str, hOldHidden) {
2724 if (hNewHidden.contains(str)) {
2725 hOldHidden.removeOne(str);
2726 hNewHidden.removeOne(str);
2727 }
2728 }
2729
2730 // create a list of active tools which change their state
2731 QStringList hActiveTools;
2732 for (QString str: hNewHidden) {
2733 auto hFilt = m_GroupBox->value(str);
2734 hFilt->guiWidget()->hide();
2735 if (hFilt->isActive())
2736 hActiveTools.append(str);
2737 }
2738
2739 Settings->SetValue("HiddenTools", Temp);
2740 for (QString str: hOldHidden) {
2741 auto hFilt = m_GroupBox->value(str);
2742 hFilt->guiWidget()->show();
2743 if (hFilt->isActive())
2744 hActiveTools.append(str);
2745 }
2746
2747 // Image need to be updated, if active tools have changed their state
2748 foreach (QString str, *m_GroupBoxesOrdered) {
2749 if (hActiveTools.contains(str)) {
2750 Update(str);
2751 break;
2752 }
2753 }
2754 }
2755
2756
2757 ////////////////////////////////////////////////////////////////////////////////
2758 //
2759 // SaveUISettings
2760 //
2761 ////////////////////////////////////////////////////////////////////////////////
2762
SaveUISettings(const QString & fileName) const2763 void ptMainWindow::SaveUISettings(const QString &fileName) const {
2764 QSettings UISettings(fileName, QSettings::IniFormat);
2765 UISettings.clear();
2766
2767 UISettings.setValue("Magic", "photivoUIFile");
2768 UISettings.setValue("HiddenTools", Settings->GetStringList("HiddenTools"));
2769 UISettings.setValue("FavouriteTools", Settings->GetStringList("FavouriteTools"));
2770
2771 UISettings.sync();
2772 if (UISettings.status() != QSettings::NoError)
2773 ptMessageBox::critical(0, "Error", "Error writing UI file\n" + fileName);
2774 }
2775
2776
2777 ////////////////////////////////////////////////////////////////////////////////
2778 //
2779 // OnVisibleToolsDiscardButtonClicked
2780 //
2781 ////////////////////////////////////////////////////////////////////////////////
2782
OnVisibleToolsDiscardButtonClicked()2783 void ptMainWindow::OnVisibleToolsDiscardButtonClicked() {
2784 // update VisibleTools box
2785 UpdateVisibleTools();
2786 }
2787
2788
2789 ////////////////////////////////////////////////////////////////////////////////
2790 //
2791 // OnVisibleToolsLoadButtonClicked
2792 //
2793 ////////////////////////////////////////////////////////////////////////////////
2794
OnVisibleToolsLoadButtonClicked()2795 void ptMainWindow::OnVisibleToolsLoadButtonClicked() {
2796 QString UIFilePattern = tr("Photivo UI file (*.ptu);;All files (*.*)");
2797 QString UIFileName = QFileDialog::getOpenFileName(this,
2798 tr("Open UI"),
2799 Settings->GetString("UIDirectory"),
2800 UIFilePattern);
2801 if (UIFileName.size() == 0) return;
2802
2803 LoadUISettings(UIFileName);
2804
2805 // update VisibleTools box
2806 UpdateVisibleTools();
2807 }
2808
2809
2810 ////////////////////////////////////////////////////////////////////////////////
2811 //
2812 // OnVisibleToolsSaveButtonClicked
2813 //
2814 ////////////////////////////////////////////////////////////////////////////////
2815
OnVisibleToolsSaveButtonClicked()2816 void ptMainWindow::OnVisibleToolsSaveButtonClicked() {
2817 // apply changes at VisibleTools box
2818 ApplyVisibleTools();
2819
2820 QString UIFilePattern = tr("Photivo UI file (*.ptu);;All files (*.*)");
2821 QString UIFileName = QFileDialog::getSaveFileName(this,
2822 tr("Save UI"),
2823 Settings->GetString("UIDirectory"),
2824 UIFilePattern);
2825 if (UIFileName.size() == 0) return;
2826
2827 QFileInfo PathInfo(UIFileName);
2828 if (PathInfo.suffix().size() == 0)
2829 UIFileName += ".ptu";
2830
2831 SaveUISettings(UIFileName);
2832 }
2833
2834
2835 ////////////////////////////////////////////////////////////////////////////////
2836 //
2837 // Update lensfun UI elements
2838 //
2839 ////////////////////////////////////////////////////////////////////////////////
2840
UpdateLfunDistUI()2841 void ptMainWindow::UpdateLfunDistUI() {
2842 short DistModel = Settings->GetInt("LfunDistModel");
2843 LfunDistPoly3Container->setVisible(DistModel == ptLfunDistModel_Poly3);
2844 LfunDistPoly5Container->setVisible(DistModel == ptLfunDistModel_Poly5);
2845 #if LF_VERSION < (3 << 16)
2846 LfunDistFov1Container->setVisible(DistModel == ptLfunDistModel_Fov1);
2847 #endif
2848 LfunDistPTLensContainer->setVisible(DistModel == ptLfunDistModel_PTLens);
2849 }
2850
UpdateLfunCAUI()2851 void ptMainWindow::UpdateLfunCAUI() {
2852 short CAModel = Settings->GetInt("LfunCAModel");
2853 LfunCALinearContainer->setVisible(CAModel == ptLfunCAModel_Linear);
2854 LfunCAPoly3Container->setVisible(CAModel == ptLfunCAModel_Poly3);
2855 }
2856
UpdateLfunVignetteUI()2857 void ptMainWindow::UpdateLfunVignetteUI() {
2858 short VignetteModel = Settings->GetInt("LfunVignetteModel");
2859 LfunVignettePoly6Container->setVisible(VignetteModel == ptLfunVignetteModel_Poly6);
2860 }
2861
2862 ////////////////////////////////////////////////////////////////////////////////
2863 //
2864 // Update liquid rescale UI elements
2865 //
2866 ////////////////////////////////////////////////////////////////////////////////
2867
UpdateLiquidRescaleUI()2868 void ptMainWindow::UpdateLiquidRescaleUI() {
2869 short Scaling = Settings->GetInt("LqrScaling");
2870 LqrHorScaleWidget->setVisible(Scaling == ptLqr_ScaleRelative);
2871 LqrVertScaleWidget->setVisible(Scaling == ptLqr_ScaleRelative);
2872 LqrWHContainter->setVisible(Scaling == ptLqr_ScaleAbsolute);
2873 }
2874
2875
2876 ////////////////////////////////////////////////////////////////////////////////
2877 //
2878 // Destructor
2879 //
2880 ////////////////////////////////////////////////////////////////////////////////
2881
~ptMainWindow()2882 ptMainWindow::~ptMainWindow() {
2883 while (ToolBoxStructureList.size()) {
2884 ToolBoxStructureList.removeAt(0);
2885 }
2886 }
2887
2888 //==============================================================================
2889
2890 #ifdef Q_OS_WIN
winEvent(MSG * message,long * result)2891 bool ptMainWindow::winEvent(MSG *message, long *result) {
2892 return ptEcWin7::GetInstance()->winEvent(message, result);
2893 }
2894
2895 #endif
2896