1 // -*- c-basic-offset: 4 -*-
2
3 /** @file BatchFrame.cpp
4 *
5 * @brief Batch processor for Hugin with GUI
6 *
7 * @author Marko Kuder <marko.kuder@gmail.com>
8 *
9 * $Id: BatchFrame.cpp 3322 2008-08-18 1:10:07Z mkuder $
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
15 *
16 * This software is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public
22 * License along with this software. If not, see
23 * <http://www.gnu.org/licenses/>.
24 *
25 */
26
27 #include "BatchFrame.h"
28 #include <wx/stdpaths.h>
29 #include "PTBatcherGUI.h"
30 #include "FindPanoDialog.h"
31 #include "FailedProjectsDialog.h"
32 #ifdef __WXMSW__
33 #include <powrprof.h>
34 #ifdef _MSC_VER
35 #pragma comment(lib, "PowrProf.lib")
36 #endif
37 #if wxCHECK_VERSION(3,1,0)
38 #include <wx/taskbarbutton.h>
39 #endif
40 #endif
41
42 /* file drag and drop handler method */
OnDropFiles(wxCoord x,wxCoord y,const wxArrayString & filenames)43 bool BatchDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
44 {
45 BatchFrame* MyBatchFrame = wxGetApp().GetFrame();
46 if (!MyBatchFrame)
47 {
48 return false;
49 }
50 if(filenames.GetCount()==0)
51 {
52 return false;
53 }
54 for(unsigned int i=0; i< filenames.GetCount(); i++)
55 {
56 wxFileName file(filenames[i]);
57 if(file.HasExt())
58 {
59 if (file.GetExt().CmpNoCase(wxT("pto")) == 0 ||
60 file.GetExt().CmpNoCase(wxT("ptp")) == 0 ||
61 file.GetExt().CmpNoCase(wxT("pts")) == 0 )
62 {
63 if(file.FileExists())
64 {
65 MyBatchFrame->AddToList(filenames[i]);
66 }
67 };
68 }
69 else
70 {
71 if(file.DirExists())
72 {
73 MyBatchFrame->AddDirToList(filenames[i]);
74 }
75 };
76 };
77 return true;
78 };
79
80 enum
81 {
82 EVT_TIMER_UPDATE_LISTBOX
83 };
84
BEGIN_EVENT_TABLE(BatchFrame,wxFrame)85 BEGIN_EVENT_TABLE(BatchFrame, wxFrame)
86 EVT_TOOL(XRCID("tool_clear"),BatchFrame::OnButtonClear)
87 EVT_TOOL(XRCID("tool_open"),BatchFrame::OnButtonOpenBatch)
88 EVT_TOOL(XRCID("tool_save"),BatchFrame::OnButtonSaveBatch)
89 EVT_TOOL(XRCID("tool_start"),BatchFrame::OnButtonRunBatch)
90 EVT_TOOL(XRCID("tool_skip"),BatchFrame::OnButtonSkip)
91 EVT_TOOL(XRCID("tool_pause"),BatchFrame::OnButtonPause)
92 EVT_TOOL(XRCID("tool_cancel"),BatchFrame::OnButtonCancel)
93 EVT_TOOL(XRCID("tool_add"),BatchFrame::OnButtonAddToStitchingQueue)
94 EVT_TOOL(XRCID("tool_remove"),BatchFrame::OnButtonRemoveFromList)
95 EVT_TOOL(XRCID("tool_adddir"),BatchFrame::OnButtonAddDir)
96 EVT_MENU(XRCID("menu_add"),BatchFrame::OnButtonAddToStitchingQueue)
97 EVT_MENU(XRCID("menu_add_assistant"),BatchFrame::OnButtonAddToAssistantQueue)
98 EVT_MENU(XRCID("menu_remove"),BatchFrame::OnButtonRemoveFromList)
99 EVT_MENU(XRCID("menu_adddir"),BatchFrame::OnButtonAddDir)
100 EVT_MENU(XRCID("menu_searchpano"), BatchFrame::OnButtonSearchPano)
101 EVT_MENU(XRCID("menu_open"),BatchFrame::OnButtonOpenBatch)
102 EVT_MENU(XRCID("menu_save"),BatchFrame::OnButtonSaveBatch)
103 EVT_MENU(XRCID("menu_clear"),BatchFrame::OnButtonClear)
104 EVT_MENU(XRCID("menu_tray"), BatchFrame::OnMinimizeTrayMenu)
105 EVT_MENU(XRCID("menu_exit"),BatchFrame::OnUserExit)
106 EVT_MENU(XRCID("menu_help"),BatchFrame::OnButtonHelp)
107 EVT_BUTTON(XRCID("button_addcommand"),BatchFrame::OnButtonAddCommand)
108 EVT_BUTTON(XRCID("button_remove"),BatchFrame::OnButtonRemoveComplete)
109 EVT_BUTTON(XRCID("button_prefix"),BatchFrame::OnButtonChangePrefix)
110 EVT_BUTTON(XRCID("button_reset"),BatchFrame::OnButtonReset)
111 EVT_BUTTON(XRCID("button_resetall"),BatchFrame::OnButtonResetAll)
112 EVT_BUTTON(XRCID("button_edit"),BatchFrame::OnButtonOpenWithHugin)
113 EVT_BUTTON(XRCID("button_move_up"),BatchFrame::OnButtonMoveUp)
114 EVT_BUTTON(XRCID("button_move_down"),BatchFrame::OnButtonMoveDown)
115 EVT_CHECKBOX(XRCID("cb_overwrite"), BatchFrame::OnCheckOverwrite)
116 EVT_CHOICE(XRCID("choice_end"), BatchFrame::OnChoiceEnd)
117 EVT_CHECKBOX(XRCID("cb_verbose"), BatchFrame::OnCheckVerbose)
118 EVT_CHECKBOX(XRCID("cb_autoremove"), BatchFrame::OnCheckAutoRemove)
119 EVT_CHECKBOX(XRCID("cb_autostitch"), BatchFrame::OnCheckAutoStitch)
120 EVT_CHECKBOX(XRCID("cb_savelog"), BatchFrame::OnCheckSaveLog)
121 EVT_END_PROCESS(-1, BatchFrame::OnProcessTerminate)
122 EVT_CLOSE(BatchFrame::OnClose)
123 EVT_TIMER(EVT_TIMER_UPDATE_LISTBOX, BatchFrame::OnUpdateListBox)
124 EVT_COMMAND(wxID_ANY, EVT_BATCH_FAILED, BatchFrame::OnBatchFailed)
125 EVT_COMMAND(wxID_ANY, EVT_INFORMATION, BatchFrame::OnBatchInformation)
126 EVT_COMMAND(wxID_ANY, EVT_UPDATE_PARENT, BatchFrame::OnRefillListBox)
127 EVT_COMMAND(wxID_ANY, EVT_QUEUE_PROGRESS, BatchFrame::OnProgress)
128 EVT_ICONIZE(BatchFrame::OnMinimize)
129 END_EVENT_TABLE()
130
131 BatchFrame::BatchFrame(wxLocale* locale, wxString xrc)
132 {
133 this->SetLocaleAndXRC(locale,xrc);
134 m_cancelled = false;
135
136 //load xrc resources
137 wxXmlResource::Get()->LoadFrame(this, (wxWindow* )NULL, wxT("batch_frame"));
138 // load our menu bar
139 #ifdef __WXMAC__
140 wxApp::s_macExitMenuItemId = XRCID("menu_exit");
141 wxApp::s_macHelpMenuTitleName = _("&Help");
142 #endif
143 SetMenuBar(wxXmlResource::Get()->LoadMenuBar(this, wxT("batch_menu")));
144
145 // create tool bar
146 SetToolBar(wxXmlResource::Get()->LoadToolBar(this, wxT("batch_toolbar")));
147
148 int widths[2] = { -1, 150 };
149 CreateStatusBar(2);
150 SetStatusWidths(2, widths);
151 SetStatusText(_("Not doing much..."));
152
153 // set the minimize icon
154 #ifdef __WXMSW__
155 m_iconNormal = wxIcon(m_xrcPrefix + wxT("data/ptbatcher.ico"), wxBITMAP_TYPE_ICO);
156 m_iconRunning = wxIcon(m_xrcPrefix + wxT("data/ptbatcher_running.ico"), wxBITMAP_TYPE_ICO);
157 m_iconPaused = wxIcon(m_xrcPrefix + wxT("data/ptbatcher_pause.ico"), wxBITMAP_TYPE_ICO);
158 #else
159 m_iconNormal = wxIcon(m_xrcPrefix + wxT("data/ptbatcher.png"), wxBITMAP_TYPE_PNG);
160 m_iconRunning = wxIcon(m_xrcPrefix + wxT("data/ptbatcher_running.png"), wxBITMAP_TYPE_PNG);
161 m_iconPaused = wxIcon(m_xrcPrefix + wxT("data/ptbatcher_pause.png"), wxBITMAP_TYPE_PNG);
162 #endif
163 SetIcon(m_iconNormal);
164
165 m_batch = new Batch(this);
166 if(wxGetKeyState(WXK_COMMAND))
167 {
168 #ifdef __WXMAC__
169 wxString text(_("You have pressed the Command key."));
170 #else
171 wxString text(_("You have pressed the Control key."));
172 #endif
173 text.Append(wxT("\n"));
174 text.Append(_("Should the loading of the batch queue be skipped?"));
175 if(wxMessageBox(text,
176 #ifdef __WXMSW__
177 wxT("PTBatcherGUI"),
178 #else
179 wxEmptyString,
180 #endif
181 wxYES_NO | wxICON_EXCLAMATION, NULL)==wxNO)
182 {
183 m_batch->LoadTemp();
184 }
185 else
186 {
187 // save empty batch queue
188 m_batch->SaveTemp();
189 };
190 }
191 else
192 {
193 m_batch->LoadTemp();
194 };
195 projListBox = XRCCTRL(*this,"project_listbox",ProjectListBox);
196 // fill at end list box, check which options are available
197 m_endChoice = XRCCTRL(*this, "choice_end", wxChoice);
198 m_endChoice->Clear();
199 m_endChoice->Append(_("Do nothing"), (void*)Batch::DO_NOTHING);
200 m_endChoice->Append(_("Close PTBatcherGUI"), (void*)Batch::CLOSE_PTBATCHERGUI);
201 #if !defined __WXMAC__ && !defined __WXOSX_COCOA__
202 // there is no wxShutdown for wxMac
203 m_endChoice->Append(_("Shutdown computer"), (void*)Batch::SHUTDOWN);
204 #endif
205 #ifdef __WXMSW__
206 SYSTEM_POWER_CAPABILITIES pwrCap;
207 if (GetPwrCapabilities(&pwrCap))
208 {
209 if (pwrCap.SystemS3)
210 {
211 m_endChoice->Append(_("Suspend computer"), (void*)Batch::SUSPEND);
212 };
213 if (pwrCap.SystemS4 && pwrCap.HiberFilePresent)
214 {
215 m_endChoice->Append(_("Hibernate computer"), (void*)Batch::HIBERNATE);
216 };
217 };
218 #endif
219
220 //TO-DO: include a batch or project progress gauge?
221 projListBox->Fill(m_batch);
222 SetDropTarget(new BatchDropTarget());
223
224 m_tray = NULL;
225 if (wxTaskBarIcon::IsAvailable())
226 {
227 // minimize to tray is by default disabled
228 // activate only if task bar icon is available
229 GetMenuBar()->Enable(XRCID("menu_tray"), true);
230 bool minTray;
231 // tray icon is disabled by default
232 wxConfigBase::Get()->Read(wxT("/BatchFrame/minimizeTray"), &minTray, false);
233 GetMenuBar()->Check(XRCID("menu_tray"), minTray);
234 UpdateTrayIcon(minTray);
235 }
236
237 UpdateTaskBarProgressBar();
238
239 #ifndef __WXMSW__
240 // check settings of help window and fix when needed
241 FixHelpSettings();
242 #endif
243 m_updateProjectsTimer = new wxTimer(this, EVT_TIMER_UPDATE_LISTBOX);
244 // start timer for check for updates in project files
245 m_updateProjectsTimer->StartOnce(5000);
246 }
247
OnCreateStatusBar(int number,long style,wxWindowID id,const wxString & name)248 wxStatusBar* BatchFrame::OnCreateStatusBar(int number, long style, wxWindowID id, const wxString& name)
249 {
250 m_progStatusBar = new ProgressStatusBar(this, id, style, name);
251 m_progStatusBar->SetFieldsCount(number);
252 return m_progStatusBar;
253 }
254
IsRunning()255 bool BatchFrame::IsRunning()
256 {
257 return m_batch->IsRunning();
258 };
259
IsPaused()260 bool BatchFrame::IsPaused()
261 {
262 return m_batch->IsPaused();
263 };
264
OnUpdateListBox(wxTimerEvent & event)265 void BatchFrame::OnUpdateListBox(wxTimerEvent& event)
266 {
267 wxFileName tempFile;
268 bool change = false;
269 for(int i = 0; i< m_batch->GetProjectCount(); i++)
270 {
271 if(m_batch->GetProject(i)->id >= 0 && m_batch->GetStatus(i)!=Project::FINISHED)
272 {
273 tempFile.Assign(m_batch->GetProject(i)->path);
274 if(tempFile.FileExists())
275 {
276 wxDateTime modify;
277 modify=tempFile.GetModificationTime();
278 if(m_batch->GetProject(i)->skip)
279 {
280 change = true;
281 m_batch->GetProject(i)->skip = false;
282 m_batch->SetStatus(i,Project::WAITING);
283 projListBox->ReloadProject(projListBox->GetIndex(m_batch->GetProject(i)->id),m_batch->GetProject(i));
284 }
285 else if(!modify.IsEqualTo(m_batch->GetProject(i)->modDate))
286 {
287 change = true;
288 m_batch->GetProject(i)->modDate = modify;
289 m_batch->GetProject(i)->ResetOptions();
290 if(m_batch->GetProject(i)->target==Project::STITCHING)
291 {
292 m_batch->SetStatus(i,Project::WAITING);
293 };
294 projListBox->ReloadProject(projListBox->GetIndex(m_batch->GetProject(i)->id),m_batch->GetProject(i));
295 }
296 }
297 else
298 {
299 if(m_batch->GetStatus(i) != Project::MISSING)
300 {
301 change = true;
302 m_batch->GetProject(i)->skip = true;
303 m_batch->SetStatus(i,Project::MISSING);
304 projListBox->SetMissing(projListBox->GetIndex(m_batch->GetProject(i)->id));
305 }
306 }
307 }
308 if(projListBox->UpdateStatus(i,m_batch->GetProject(i)))
309 {
310 change = true;
311 }
312 }
313 if(change)
314 {
315 m_batch->SaveTemp();
316 };
317 // start timer again
318 m_updateProjectsTimer->StartOnce(2000);
319 };
320
OnUserExit(wxCommandEvent & event)321 void BatchFrame::OnUserExit(wxCommandEvent& event)
322 {
323 Close(true);
324 };
325
OnButtonAddCommand(wxCommandEvent & event)326 void BatchFrame::OnButtonAddCommand(wxCommandEvent& event)
327 {
328 wxTextEntryDialog dlg(this,_("Please enter the command-line application to execute:"),_("Enter application"));
329 wxTheApp->SetEvtHandlerEnabled(false);
330 if(dlg.ShowModal() == wxID_OK)
331 {
332 wxString line = dlg.GetValue();
333 m_batch->AddAppToBatch(line);
334 //SetStatusText(_T("Added application"));
335 projListBox->AppendProject(m_batch->GetProject(m_batch->GetProjectCount()-1));
336 m_batch->SaveTemp();
337 }
338 wxTheApp->SetEvtHandlerEnabled(true);
339 }
340
OnButtonAddDir(wxCommandEvent & event)341 void BatchFrame::OnButtonAddDir(wxCommandEvent& event)
342 {
343 wxString defaultdir = wxConfigBase::Get()->Read(wxT("/BatchFrame/actualPath"),wxT(""));
344 wxDirDialog dlg(this,
345 _("Specify a directory to search for projects in"),
346 defaultdir, wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
347 dlg.SetPath(wxConfigBase::Get()->Read(wxT("/BatchFrame/actualPath"),wxT("")));
348 if (dlg.ShowModal() == wxID_OK)
349 {
350 wxConfig::Get()->Write(wxT("/BatchFrame/actualPath"), dlg.GetPath()); // remember for later
351 AddDirToList(dlg.GetPath());
352 };
353 }
354
OnButtonSearchPano(wxCommandEvent & e)355 void BatchFrame::OnButtonSearchPano(wxCommandEvent& e)
356 {
357 FindPanoDialog findpano_dlg(this,m_xrcPrefix);
358 findpano_dlg.ShowModal();
359 };
360
OnButtonAddToStitchingQueue(wxCommandEvent & event)361 void BatchFrame::OnButtonAddToStitchingQueue(wxCommandEvent& event)
362 {
363 wxString defaultdir = wxConfigBase::Get()->Read(wxT("/BatchFrame/actualPath"),wxT(""));
364 wxFileDialog dlg(0,
365 _("Specify project source file(s)"),
366 defaultdir, wxT(""),
367 _("Project files (*.pto)|*.pto|All files (*)|*"),
368 wxFD_OPEN | wxFD_MULTIPLE, wxDefaultPosition);
369 dlg.SetDirectory(defaultdir);
370
371 if (dlg.ShowModal() == wxID_OK)
372 {
373 wxArrayString paths;
374 dlg.GetPaths(paths);
375 #ifdef __WXGTK__
376 //workaround a bug in GTK, see https://bugzilla.redhat.com/show_bug.cgi?id=849692 and http://trac.wxwidgets.org/ticket/14525
377 wxConfig::Get()->Write(wxT("/BatchFrame/actualPath"), wxPathOnly(paths[0])); // remember for later
378 #else
379 wxConfig::Get()->Write(wxT("/BatchFrame/actualPath"), dlg.GetDirectory()); // remember for later
380 #endif
381 for(unsigned int i=0; i<paths.GetCount(); i++)
382 {
383 AddToList(paths.Item(i));
384 }
385 m_batch->SaveTemp();
386 };
387 }
388
OnButtonAddToAssistantQueue(wxCommandEvent & event)389 void BatchFrame::OnButtonAddToAssistantQueue(wxCommandEvent& event)
390 {
391 wxString defaultdir = wxConfigBase::Get()->Read(wxT("/BatchFrame/actualPath"),wxT(""));
392 wxFileDialog dlg(0,
393 _("Specify project source file(s)"),
394 defaultdir, wxT(""),
395 _("Project files (*.pto)|*.pto|All files (*)|*"),
396 wxFD_OPEN | wxFD_MULTIPLE, wxDefaultPosition);
397 dlg.SetDirectory(defaultdir);
398
399 if (dlg.ShowModal() == wxID_OK)
400 {
401 wxArrayString paths;
402 dlg.GetPaths(paths);
403 #ifdef __WXGTK__
404 //workaround a bug in GTK, see https://bugzilla.redhat.com/show_bug.cgi?id=849692 and http://trac.wxwidgets.org/ticket/14525
405 wxConfig::Get()->Write(wxT("/BatchFrame/actualPath"), wxPathOnly(paths[0])); // remember for later
406 #else
407 wxConfig::Get()->Write(wxT("/BatchFrame/actualPath"), dlg.GetDirectory()); // remember for later
408 #endif
409
410 for(unsigned int i=0; i<paths.GetCount(); i++)
411 {
412 AddToList(paths.Item(i),Project::DETECTING);
413 }
414 m_batch->SaveTemp();
415 };
416 }
417
AddDirToList(wxString aDir)418 void BatchFrame::AddDirToList(wxString aDir)
419 {
420 //we traverse all subdirectories of chosen path
421 DirTraverser traverser;
422 wxDir dir(aDir);
423 dir.Traverse(traverser);
424 wxArrayString projects = traverser.GetProjectFiles();
425 for(unsigned int i=0; i<projects.GetCount(); i++)
426 {
427 m_batch->AddProjectToBatch(projects.Item(i));
428 Project* proj=m_batch->GetProject(m_batch->GetProjectCount()-1);
429 if(!proj->isAligned)
430 {
431 proj->target=Project::DETECTING;
432 };
433 projListBox->AppendProject(proj);
434 };
435 m_batch->SaveTemp();
436 SetStatusText(wxString::Format(_("Added projects from dir %s"), aDir.c_str()));
437 };
438
AddToList(wxString aFile,Project::Target target)439 void BatchFrame::AddToList(wxString aFile,Project::Target target)
440 {
441 m_batch->AddProjectToBatch(aFile,wxT(""),target);
442 wxString s;
443 switch(target)
444 {
445 case Project::STITCHING:
446 s=wxString::Format(_("Add project %s to stitching queue."),aFile.c_str());
447 break;
448 case Project::DETECTING:
449 s=wxString::Format(_("Add project %s to assistant queue."),aFile.c_str());
450 break;
451 };
452 SetStatusInformation(s);
453 projListBox->AppendProject(m_batch->GetProject(m_batch->GetProjectCount()-1));
454 m_batch->SaveTemp();
455 }
456
457
OnButtonCancel(wxCommandEvent & event)458 void BatchFrame::OnButtonCancel(wxCommandEvent& event)
459 {
460 GetToolBar()->ToggleTool(XRCID("tool_pause"),false);
461 m_cancelled = true;
462 m_batch->CancelBatch();
463 SetStatusInformation(_("Batch stopped"));
464 if (m_tray)
465 {
466 m_tray->SetIcon(m_iconNormal, _("Hugin's Batch processor"));
467 };
468 }
469
OnButtonChangePrefix(wxCommandEvent & event)470 void BatchFrame::OnButtonChangePrefix(wxCommandEvent& event)
471 {
472 const HuginBase::UIntSet selected(projListBox->GetSelectedProjects());
473 if(selected.size()== 1)
474 {
475 Project* project = m_batch->GetProject(*selected.begin());
476 if (project->target == Project::STITCHING)
477 {
478 wxFileName prefix(project->prefix);
479 wxFileDialog dlg(0, wxString::Format(_("Specify output prefix for project %s"), project->path),
480 prefix.GetPath(),
481 prefix.GetFullName(), wxT(""),
482 wxFD_SAVE, wxDefaultPosition);
483 if (dlg.ShowModal() == wxID_OK)
484 {
485 while(containsInvalidCharacters(dlg.GetPath()))
486 {
487 wxArrayString list;
488 list.Add(dlg.GetPath());
489 ShowFilenameWarning(this, list);
490 if(dlg.ShowModal()!=wxID_OK)
491 {
492 return;
493 }
494 };
495 wxFileName prefix(dlg.GetPath());
496 while (!prefix.IsDirWritable())
497 {
498 wxMessageBox(wxString::Format(_("You have no permissions to write in folder \"%s\".\nPlease select another folder for the final output."), prefix.GetPath().c_str()),
499 #ifdef __WXMSW__
500 wxT("PTBatcherGUI"),
501 #else
502 wxT(""),
503 #endif
504 wxOK | wxICON_INFORMATION);
505 if (dlg.ShowModal() != wxID_OK)
506 {
507 return;
508 };
509 prefix = dlg.GetPath();
510 };
511
512 wxString outname(dlg.GetPath());
513 ChangePrefix(*selected.begin(), outname);
514 //SetStatusText(_T("Changed prefix for "+projListBox->GetSelectedProject()));
515 m_batch->SaveTemp();
516 }
517 }
518 else
519 {
520 SetStatusText(_("The prefix of an assistant target cannot be changed."));
521 wxBell();
522 };
523 }
524 else
525 {
526 if (selected.empty())
527 {
528 SetStatusText(_("Please select a project"));
529 }
530 else
531 {
532 wxBell();
533 SetStatusText(_("Please select only one project"));
534 };
535 };
536 }
537
ChangePrefix(int index,wxString newPrefix)538 void BatchFrame::ChangePrefix(int index,wxString newPrefix)
539 {
540 int i;
541 if(index!=-1)
542 {
543 i=index;
544 }
545 else
546 {
547 i=m_batch->GetProjectCount()-1;
548 }
549 m_batch->ChangePrefix(i,newPrefix);
550 projListBox->ChangePrefix(i,newPrefix);
551 }
552
OnButtonClear(wxCommandEvent & event)553 void BatchFrame::OnButtonClear(wxCommandEvent& event)
554 {
555 int returnCode = m_batch->ClearBatch();
556 if(returnCode == 0)
557 {
558 projListBox->DeleteAllItems();
559 }
560 else if(returnCode == 2)
561 {
562 m_cancelled = true;
563 projListBox->DeleteAllItems();
564 if(GetToolBar()->GetToolState(XRCID("tool_pause")))
565 {
566 GetToolBar()->ToggleTool(XRCID("tool_pause"),false);
567 }
568 }
569 m_batch->SaveTemp();
570 }
571
OnButtonHelp(wxCommandEvent & event)572 void BatchFrame::OnButtonHelp(wxCommandEvent& event)
573 {
574 DEBUG_TRACE("");
575 #if defined __wxMSW__ && !(wxCHECK_VERSION(3,1,1))
576 // wxWidgets 3.x has a bug, that prevents DisplaySection to work on Win8/10 64 bit
577 // see: http://trac.wxwidgets.org/ticket/14888
578 // so using DisplayContents() and our own implementation of HuginCHMHelpController
579 GetHelpController().DisplayHelpPage(wxT("Hugin_Batch_Processor.html"));
580 #else
581 GetHelpController().DisplaySection(wxT("Hugin_Batch_Processor.html"));
582 #endif
583 }
584
OnButtonMoveDown(wxCommandEvent & event)585 void BatchFrame::OnButtonMoveDown(wxCommandEvent& event)
586 {
587 const HuginBase::UIntSet selected(projListBox->GetSelectedProjects());
588 if (selected.size() == 1)
589 {
590 SwapProject(*selected.begin(), true);
591 m_batch->SaveTemp();
592 }
593 else
594 {
595 wxBell();
596 };
597 }
598
OnButtonMoveUp(wxCommandEvent & event)599 void BatchFrame::OnButtonMoveUp(wxCommandEvent& event)
600 {
601 const HuginBase::UIntSet selected(projListBox->GetSelectedProjects());
602 if (selected.size() == 1)
603 {
604 SwapProject(*selected.begin() - 1, false);
605 m_batch->SaveTemp();
606 }
607 else
608 {
609 wxBell();
610 };
611 }
612
OnButtonOpenBatch(wxCommandEvent & event)613 void BatchFrame::OnButtonOpenBatch(wxCommandEvent& event)
614 {
615 wxString defaultdir = wxConfigBase::Get()->Read(wxT("/BatchFrame/batchPath"),wxT(""));
616 wxFileDialog dlg(0,
617 _("Specify batch file to open"),
618 defaultdir, wxT(""),
619 _("Batch files (*.ptb)|*.ptb;|All files (*)|*"),
620 wxFD_OPEN, wxDefaultPosition);
621 if (dlg.ShowModal() == wxID_OK)
622 {
623 wxConfig::Get()->Write(wxT("/BatchFrame/batchPath"), dlg.GetDirectory()); // remember for later
624 int clearCode = m_batch->LoadBatchFile(dlg.GetPath());
625 //1 is error code for not clearing batch
626 if(clearCode!=1)
627 {
628 /*if(clearCode==2) //we just cancelled the batch, so we need to try loading again
629 m_batch->LoadBatchFile(dlg.GetPath());*/
630 projListBox->DeleteAllItems();
631 projListBox->Fill(m_batch);
632 m_batch->SaveTemp();
633 }
634 }
635 }
636
OnButtonOpenWithHugin(wxCommandEvent & event)637 void BatchFrame::OnButtonOpenWithHugin(wxCommandEvent& event)
638 {
639 const wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
640 const HuginBase::UIntSet selected(projListBox->GetSelectedProjects());
641 if (selected.size() == 1)
642 {
643 if (projListBox->GetText(*selected.begin(), 0).Cmp(_T("")) != 0)
644 #ifdef __WXMAC__
645 wxExecute(_T("open -b net.sourceforge.Hugin \"" + m_batch->GetProject(*selected.begin())->path + _T("\"")));
646 #else
647 wxExecute(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + _T("hugin \"" + m_batch->GetProject(*selected.begin())->path + _T("\" -notips")));
648 #endif
649 else
650 {
651 SetStatusText(_("Cannot open app in Hugin."));
652 };
653 }
654 else
655 {
656 if (selected.empty())
657 {
658 //ask user if he/she wants to load an empty project
659 wxMessageDialog message(this, _("No project selected. Open Hugin without project?"),
660 #ifdef _WIN32
661 _("PTBatcherGUI"),
662 #else
663 wxT(""),
664 #endif
665 wxYES_NO | wxICON_INFORMATION);
666 if (message.ShowModal() == wxID_YES)
667 {
668 #ifdef __WXMAC__
669 wxExecute(_T("open -b net.sourceforge.Hugin"));
670 #else
671 wxExecute(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + _T("hugin"));
672 #endif
673 }
674 }
675 else
676 {
677 wxBell();
678 SetStatusText(_("Please select only one project"));
679 };
680 };
681 }
682
OnButtonPause(wxCommandEvent & event)683 void BatchFrame::OnButtonPause(wxCommandEvent& event)
684 {
685 if(m_batch->GetRunningCount()>0)
686 {
687 if(!m_batch->IsPaused())
688 {
689 m_batch->PauseBatch();
690 GetToolBar()->ToggleTool(XRCID("tool_pause"),true);
691 SetStatusInformation(_("Batch paused"));
692 if (m_tray)
693 {
694 m_tray->SetIcon(m_iconPaused, _("Pausing processing Hugin's batch queue"));
695 };
696 }
697 else
698 {
699 m_batch->PauseBatch();
700 GetToolBar()->ToggleTool(XRCID("tool_pause"),false);
701 SetStatusInformation(_("Continuing batch..."));
702 if (m_tray)
703 {
704 m_tray->SetIcon(m_iconRunning, _("Processing Hugin's batch queue"));
705 };
706 }
707 }
708 else //if no projects are running, we deactivate the button
709 {
710 GetToolBar()->ToggleTool(XRCID("tool_pause"),false);
711 }
712 UpdateTaskBarProgressBar();
713 }
714
OnButtonRemoveComplete(wxCommandEvent & event)715 void BatchFrame::OnButtonRemoveComplete(wxCommandEvent& event)
716 {
717 bool removeErrors=false;
718 if(!m_batch->NoErrors())
719 {
720 wxMessageDialog message(this,_("There are failed projects in the list.\nRemove them too?"),
721 #ifdef _WIN32
722 _("PTBatcherGUI"),
723 #else
724 wxT(""),
725 #endif
726 wxYES_NO | wxICON_INFORMATION );
727 if(message.ShowModal()==wxID_YES)
728 {
729 removeErrors=true;
730 }
731 }
732 for(int i=projListBox->GetItemCount()-1; i>=0; i--)
733 {
734 if(m_batch->GetStatus(i)==Project::FINISHED ||
735 (removeErrors && m_batch->GetStatus(i)==Project::FAILED))
736 {
737 projListBox->Deselect(i);
738 projListBox->DeleteItem(i);
739 m_batch->RemoveProjectAtIndex(i);
740 }
741 }
742 m_batch->SaveTemp();
743 }
744
OnButtonRemoveFromList(wxCommandEvent & event)745 void BatchFrame::OnButtonRemoveFromList(wxCommandEvent& event)
746 {
747
748 const HuginBase::UIntSet selected = projListBox->GetSelectedProjects();
749 if(!selected.empty())
750 {
751 for (auto i = selected.rbegin(); i != selected.rend(); ++i)
752 {
753 const int selIndex = *i;
754 if (m_batch->GetStatus(selIndex) == Project::RUNNING || m_batch->GetStatus(selIndex) == Project::PAUSED)
755 {
756 wxMessageDialog message(this, _("Cannot remove project in progress.\nDo you want to cancel it?"),
757 #ifdef _WIN32
758 _("PTBatcherGUI"),
759 #else
760 wxT(""),
761 #endif
762 wxYES_NO | wxICON_INFORMATION);
763 if (message.ShowModal() == wxID_YES)
764 {
765 OnButtonSkip(event);
766 };
767 }
768 else
769 {
770 SetStatusText(wxString::Format(_("Removed project %s"), m_batch->GetProject(selIndex)->path.c_str()));
771 projListBox->Deselect(selIndex);
772 projListBox->DeleteItem(selIndex);
773 m_batch->RemoveProjectAtIndex(selIndex);
774 m_batch->SaveTemp();
775 };
776 };
777 }
778 else
779 {
780 SetStatusText(_("Please select a project to remove"));
781 }
782 }
783
784
OnButtonReset(wxCommandEvent & event)785 void BatchFrame::OnButtonReset(wxCommandEvent& event)
786 {
787 const HuginBase::UIntSet selected(projListBox->GetSelectedProjects());
788 if(!selected.empty())
789 {
790 for (auto selIndex : selected)
791 {
792 if (m_batch->GetStatus(selIndex) == Project::RUNNING || m_batch->GetStatus(selIndex) == Project::PAUSED)
793 {
794 wxMessageDialog message(this, _("Cannot reset project in progress.\nDo you want to cancel it?"),
795 #ifdef _WIN32
796 _("PTBatcherGUI"),
797 #else
798 wxT(""),
799 #endif
800 wxYES_NO | wxICON_INFORMATION);
801 if (message.ShowModal() == wxID_YES)
802 {
803 OnButtonSkip(event);
804 }
805 }
806 else
807 {
808 m_batch->SetStatus(selIndex, Project::WAITING);
809 SetStatusText(wxString::Format(_("Reset project %s"), m_batch->GetProject(selIndex)->path.c_str()));
810 };
811 };
812 }
813 else
814 {
815 SetStatusText(_("Please select a project to reset"));
816 }
817 m_batch->SaveTemp();
818 }
819
OnButtonResetAll(wxCommandEvent & event)820 void BatchFrame::OnButtonResetAll(wxCommandEvent& event)
821 {
822 if(m_batch->GetRunningCount()!=0)
823 {
824 wxMessageDialog message(this, _("Cannot reset projects in progress.\nDo you want to cancel the batch?"),
825 #ifdef _WIN32
826 _("PTBatcherGUI"),
827 #else
828 wxT(""),
829 #endif
830 wxYES_NO | wxICON_INFORMATION);
831 if(message.ShowModal()==wxID_YES)
832 {
833 OnButtonCancel(event);
834 }
835 }
836 else
837 {
838 for(int i=projListBox->GetItemCount()-1; i>=0; i--)
839 {
840 m_batch->SetStatus(i,Project::WAITING);
841 }
842 }
843 m_batch->SaveTemp();
844 }
845
OnButtonRunBatch(wxCommandEvent & event)846 void BatchFrame::OnButtonRunBatch(wxCommandEvent& event)
847 {
848 if(m_batch->IsPaused())
849 {
850 //m_batch->paused = false;
851 OnButtonPause(event);
852 }
853 else
854 {
855 RunBatch();
856 }
857 }
858
OnButtonSaveBatch(wxCommandEvent & event)859 void BatchFrame::OnButtonSaveBatch(wxCommandEvent& event)
860 {
861 wxString defaultdir = wxConfigBase::Get()->Read(wxT("/BatchFrame/batchPath"),wxT(""));
862 wxFileDialog dlg(0,
863 _("Specify batch file to save"),
864 defaultdir, wxT(""),
865 _("Batch file (*.ptb)|*.ptb;|All files (*)|*"),
866 wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
867 if (dlg.ShowModal() == wxID_OK)
868 {
869 wxConfig::Get()->Write(wxT("/BatchFrame/batchPath"), dlg.GetDirectory()); // remember for later
870 m_batch->SaveBatchFile(dlg.GetPath());
871 }
872 }
873
OnButtonSkip(wxCommandEvent & event)874 void BatchFrame::OnButtonSkip(wxCommandEvent& event)
875 {
876 const HuginBase::UIntSet selected(projListBox->GetSelectedProjects());
877 if(!selected.empty())
878 {
879 for (auto selIndex : selected)
880 {
881 if (m_batch->GetStatus(selIndex) == Project::RUNNING
882 || m_batch->GetStatus(selIndex) == Project::PAUSED)
883 {
884 if (m_batch->GetStatus(selIndex) == Project::PAUSED)
885 {
886 if (m_batch->GetRunningCount() == 1)
887 {
888 GetToolBar()->ToggleTool(XRCID("tool_pause"), false);
889 }
890 for (int i = 0; i < m_batch->GetRunningCount(); i++)
891 {
892 if (m_batch->GetStatus(selIndex) == Project::PAUSED
893 && m_batch->CompareProjectsInLists(i, selIndex))
894 {
895 m_batch->CancelProject(i);
896 }
897 }
898 }
899 else
900 {
901 //we go through all running projects to find the one with the same id as chosen one
902 for (int i = 0; i < m_batch->GetRunningCount(); i++)
903 {
904 if (m_batch->GetStatus(selIndex) == Project::RUNNING
905 && m_batch->CompareProjectsInLists(i, selIndex))
906 {
907 m_batch->CancelProject(i);
908 }
909 }
910 }
911 }
912 else
913 {
914 m_batch->SetStatus(selIndex, Project::FAILED);
915 };
916 };
917 }
918 }
919
SelectEndTask(wxControlWithItems * list,const Batch::EndTask endTask)920 void SelectEndTask(wxControlWithItems* list, const Batch::EndTask endTask)
921 {
922 for (unsigned int i = 0; i<list->GetCount(); i++)
923 {
924 if (static_cast<Batch::EndTask>((size_t)list->GetClientData(i)) == endTask)
925 {
926 list->SetSelection(i);
927 return;
928 };
929 };
930 list->SetSelection(0);
931 };
932
SetCheckboxes()933 void BatchFrame::SetCheckboxes()
934 {
935 wxConfigBase* config=wxConfigBase::Get();
936 int i;
937 // read older version
938 #if defined __WXMAC__ || defined __WXOSX_COCOA__
939 i = 0;
940 #else
941 i=config->Read(wxT("/BatchFrame/ShutdownCheck"), 0l);
942 #endif
943 if (i != 0)
944 {
945 SelectEndTask(m_endChoice, Batch::SHUTDOWN);
946 m_batch->atEnd = Batch::SHUTDOWN;
947 };
948 config->DeleteEntry(wxT("/BatchFrame/ShutdownCheck"));
949 // now read current version
950 i = config->Read(wxT("/BatchFrame/AtEnd"), 0l);
951 #if defined __WXMAC__ || defined __WXOSX_COCOA__
952 // wxWidgets for MacOS does not support wxShutdown
953 if (i == Batch::SHUTDOWN)
954 {
955 i = 0;
956 };
957 #endif
958 m_batch->atEnd = static_cast<Batch::EndTask>(i);
959 SelectEndTask(m_endChoice, m_batch->atEnd);
960 i=config->Read(wxT("/BatchFrame/OverwriteCheck"), 0l);
961 XRCCTRL(*this,"cb_overwrite",wxCheckBox)->SetValue(i!=0);
962 m_batch->overwrite=(i!=0);
963 i=config->Read(wxT("/BatchFrame/VerboseCheck"), 0l);
964 XRCCTRL(*this,"cb_verbose",wxCheckBox)->SetValue(i!=0);
965 m_batch->verbose=(i!=0);
966 i=config->Read(wxT("/BatchFrame/AutoRemoveCheck"), 1l);
967 XRCCTRL(*this,"cb_autoremove",wxCheckBox)->SetValue(i!=0);
968 m_batch->autoremove=(i!=0);
969 i=config->Read(wxT("/BatchFrame/AutoStitchCheck"), 0l);
970 XRCCTRL(*this,"cb_autostitch",wxCheckBox)->SetValue(i!=0);
971 m_batch->autostitch=(i!=0);
972 i=config->Read(wxT("/BatchFrame/SaveLog"), 0l);
973 XRCCTRL(*this, "cb_savelog",wxCheckBox)->SetValue(i!=0);
974 m_batch->saveLog=(i!=0);
975 };
976
GetEndTask()977 Batch::EndTask BatchFrame::GetEndTask()
978 {
979 return static_cast<Batch::EndTask>((size_t)m_endChoice->GetClientData(m_endChoice->GetSelection()));
980 };
981
GetCheckOverwrite()982 bool BatchFrame::GetCheckOverwrite()
983 {
984 return XRCCTRL(*this,"cb_overwrite",wxCheckBox)->IsChecked();
985 };
986
GetCheckVerbose()987 bool BatchFrame::GetCheckVerbose()
988 {
989 return XRCCTRL(*this,"cb_verbose",wxCheckBox)->IsChecked();
990 };
991
GetCheckAutoRemove()992 bool BatchFrame::GetCheckAutoRemove()
993 {
994 return XRCCTRL(*this,"cb_autoremove",wxCheckBox)->IsChecked();
995 };
996
GetCheckAutoStitch()997 bool BatchFrame::GetCheckAutoStitch()
998 {
999 return XRCCTRL(*this,"cb_autostitch",wxCheckBox)->IsChecked();
1000 };
1001
GetCheckSaveLog()1002 bool BatchFrame::GetCheckSaveLog()
1003 {
1004 return XRCCTRL(*this,"cb_savelog",wxCheckBox)->IsChecked();
1005 };
1006
OnCheckOverwrite(wxCommandEvent & event)1007 void BatchFrame::OnCheckOverwrite(wxCommandEvent& event)
1008 {
1009 wxConfigBase* config=wxConfigBase::Get();
1010 if(event.IsChecked())
1011 {
1012 m_batch->overwrite = true;
1013 config->Write(wxT("/BatchFrame/OverwriteCheck"), 1l);
1014 }
1015 else
1016 {
1017 m_batch->overwrite = false;
1018 config->Write(wxT("/BatchFrame/OverwriteCheck"), 0l);
1019 }
1020 config->Flush();
1021 }
1022
OnChoiceEnd(wxCommandEvent & event)1023 void BatchFrame::OnChoiceEnd(wxCommandEvent& event)
1024 {
1025 m_batch->atEnd = static_cast<Batch::EndTask>((size_t)m_endChoice->GetClientData(event.GetSelection()));
1026 wxConfigBase* config=wxConfigBase::Get();
1027 config->Write(wxT("/BatchFrame/AtEnd"), static_cast<long>(m_batch->atEnd));
1028 config->Flush();
1029 }
1030
OnCheckVerbose(wxCommandEvent & event)1031 void BatchFrame::OnCheckVerbose(wxCommandEvent& event)
1032 {
1033 wxConfigBase* config=wxConfigBase::Get();
1034 if(event.IsChecked())
1035 {
1036 m_batch->verbose = true;
1037 config->Write(wxT("/BatchFrame/VerboseCheck"), 1l);
1038 }
1039 else
1040 {
1041 m_batch->verbose = false;
1042 config->Write(wxT("/BatchFrame/VerboseCheck"), 0l);
1043 };
1044 config->Flush();
1045 m_batch->ShowOutput(m_batch->verbose);
1046 }
1047
SetInternalVerbose(bool newVerbose)1048 void BatchFrame::SetInternalVerbose(bool newVerbose)
1049 {
1050 m_batch->verbose=newVerbose;
1051 };
1052
OnCheckAutoRemove(wxCommandEvent & event)1053 void BatchFrame::OnCheckAutoRemove(wxCommandEvent& event)
1054 {
1055 m_batch->autoremove=event.IsChecked();
1056 wxConfigBase* config=wxConfigBase::Get();
1057 if(m_batch->autoremove)
1058 {
1059 config->Write(wxT("/BatchFrame/AutoRemoveCheck"), 1l);
1060 }
1061 else
1062 {
1063 config->Write(wxT("/BatchFrame/AutoRemoveCheck"), 0l);
1064 }
1065 config->Flush();
1066 };
1067
OnCheckAutoStitch(wxCommandEvent & event)1068 void BatchFrame::OnCheckAutoStitch(wxCommandEvent& event)
1069 {
1070 m_batch->autostitch=event.IsChecked();
1071 wxConfigBase* config=wxConfigBase::Get();
1072 if(m_batch->autostitch)
1073 {
1074 config->Write(wxT("/BatchFrame/AutoStitchCheck"), 1l);
1075 }
1076 else
1077 {
1078 config->Write(wxT("/BatchFrame/AutoStitchCheck"), 0l);
1079 }
1080 config->Flush();
1081 };
1082
OnCheckSaveLog(wxCommandEvent & event)1083 void BatchFrame::OnCheckSaveLog(wxCommandEvent& event)
1084 {
1085 m_batch->saveLog=event.IsChecked();
1086 wxConfigBase* config=wxConfigBase::Get();
1087 if(m_batch->saveLog)
1088 {
1089 config->Write(wxT("/BatchFrame/SaveLog"), 1l);
1090 }
1091 else
1092 {
1093 config->Write(wxT("/BatchFrame/SaveLog"), 0l);
1094 }
1095 config->Flush();
1096 };
1097
OnClose(wxCloseEvent & event)1098 void BatchFrame::OnClose(wxCloseEvent& event)
1099 {
1100 // check size of batch queue
1101 if (m_batch->GetProjectCount() > 500)
1102 {
1103 wxMessageDialog message(this, _("The batch queue contains many items.\nThis can have negative effects on performance.\nShould the batch queue be cleared now?"),
1104 #ifdef __WXMSW__
1105 _("PTBatcherGUI"),
1106 #else
1107 wxT(""),
1108 #endif
1109 wxYES_NO | wxICON_INFORMATION);
1110 message.SetYesNoLabels(_("Clear batch queue now"), _("Keep batch queue"));
1111 if (message.ShowModal() == wxID_YES)
1112 {
1113 m_batch->ClearBatch();
1114 m_batch->SaveTemp();
1115 };
1116 };
1117 //save windows position
1118 wxConfigBase* config=wxConfigBase::Get();
1119 if(IsMaximized())
1120 {
1121 config->Write(wxT("/BatchFrame/Max"), 1l);
1122 config->Write(wxT("/BatchFrame/Minimized"), 0l);
1123 }
1124 else
1125 {
1126 config->Write(wxT("/BatchFrame/Max"), 0l);
1127 if(m_tray!=NULL && !IsShown())
1128 {
1129 config->Write(wxT("/BatchFrame/Minimized"), 1l);
1130 }
1131 else
1132 {
1133 config->Write(wxT("/BatchFrame/Minimized"), 0l);
1134 config->Write(wxT("/BatchFrame/Width"), GetSize().GetWidth());
1135 config->Write(wxT("/BatchFrame/Height"), GetSize().GetHeight());
1136 };
1137 }
1138 config->Flush();
1139 if(m_tray!=NULL)
1140 {
1141 delete m_tray;
1142 m_tray = NULL;
1143 }
1144 delete m_updateProjectsTimer;
1145 this->Destroy();
1146 }
1147
PropagateDefaults()1148 void BatchFrame::PropagateDefaults()
1149 {
1150 m_batch->atEnd = GetEndTask();
1151 m_batch->overwrite=GetCheckOverwrite();
1152 m_batch->verbose=GetCheckVerbose();
1153 m_batch->autoremove=GetCheckAutoRemove();
1154 m_batch->autostitch=GetCheckAutoStitch();
1155 }
1156
RunBatch()1157 void BatchFrame::RunBatch()
1158 {
1159 if(!IsRunning())
1160 {
1161 SetStatusInformation(_("Starting batch"));
1162 if (m_tray)
1163 {
1164 m_tray->SetIcon(m_iconRunning, _("Processing Hugin's batch queue"));
1165 };
1166 }
1167 m_batch->RunBatch();
1168 }
1169
SetLocaleAndXRC(wxLocale * locale,wxString xrc)1170 void BatchFrame::SetLocaleAndXRC(wxLocale* locale, wxString xrc)
1171 {
1172 m_locale = locale;
1173 m_xrcPrefix = xrc;
1174 }
1175
SwapProject(int index,bool down)1176 void BatchFrame::SwapProject(int index, bool down)
1177 {
1178 if(index>=0 && index<(projListBox->GetItemCount()-1))
1179 {
1180 projListBox->SwapProject(index);
1181 m_batch->SwapProject(index);
1182 if(down)
1183 {
1184 projListBox->Deselect(index);
1185 projListBox->Select(index + 1);
1186 }
1187 else
1188 {
1189 projListBox->Select(index);
1190 projListBox->Deselect(index + 1);
1191 };
1192 }
1193 }
1194
1195
OnProcessTerminate(wxProcessEvent & event)1196 void BatchFrame::OnProcessTerminate(wxProcessEvent& event)
1197 {
1198 if(m_batch->GetRunningCount()==1)
1199 {
1200 GetToolBar()->ToggleTool(XRCID("tool_pause"),false);
1201 if (m_tray)
1202 {
1203 m_tray->SetIcon(m_iconNormal, _("Hugin's Batch processor"));
1204 };
1205 }
1206 event.Skip();
1207 }
1208
RestoreSize()1209 void BatchFrame::RestoreSize()
1210 {
1211 //get saved size
1212 wxConfigBase* config=wxConfigBase::Get();
1213 int width = config->Read(wxT("/BatchFrame/Width"), -1l);
1214 int height = config->Read(wxT("/BatchFrame/Height"), -1l);
1215 int max = config->Read(wxT("/BatchFrame/Max"), -1l);
1216 int min = config->Read(wxT("/BatchFrame/Minimized"), -1l);
1217 if((width != -1) && (height != -1))
1218 {
1219 SetSize(width,height);
1220 }
1221 else
1222 {
1223 SetSize(600,400);
1224 }
1225
1226 if(max==1)
1227 {
1228 Maximize();
1229 };
1230 m_startedMinimized=(m_tray!=NULL) && (min==1);
1231 }
1232
OnBatchFailed(wxCommandEvent & event)1233 void BatchFrame::OnBatchFailed(wxCommandEvent& event)
1234 {
1235 if(m_batch->GetFailedProjectsCount()>0)
1236 {
1237 if (m_tray)
1238 {
1239 m_tray->SetIcon(m_iconNormal, _("Hugin's Batch processor"));
1240 };
1241 FailedProjectsDialog failedProjects_dlg(this, m_batch, m_xrcPrefix);
1242 failedProjects_dlg.ShowModal();
1243 };
1244 };
1245
OnBatchInformation(wxCommandEvent & e)1246 void BatchFrame::OnBatchInformation(wxCommandEvent& e)
1247 {
1248 SetStatusInformation(e.GetString());
1249 if (m_tray && e.GetInt() == 1)
1250 {
1251 // batch finished, reset icon in task bar
1252 m_tray->SetIcon(m_iconNormal, _("Hugin's Batch processor"));
1253 };
1254 };
1255
SetStatusInformation(wxString status)1256 void BatchFrame::SetStatusInformation(wxString status)
1257 {
1258 SetStatusText(status);
1259 if(m_tray!=NULL)
1260 {
1261 #if defined __WXMSW__ && wxUSE_TASKBARICON_BALLOONS
1262 m_tray->ShowBalloon(_("PTBatcherGUI"),status,5000,wxICON_INFORMATION);
1263 #else
1264 #ifndef __WXMAC__
1265 // the balloon does not work correctly on MacOS; it gets the focus
1266 // and can not be closed
1267 if(!IsShown())
1268 {
1269 TaskBarBalloon* balloon=new TaskBarBalloon(_("PTBatcherGUI"),status);
1270 balloon->showBalloon(5000);
1271 };
1272 #endif
1273 #endif
1274 };
1275 };
1276
OnProgress(wxCommandEvent & e)1277 void BatchFrame::OnProgress(wxCommandEvent& e)
1278 {
1279 m_progStatusBar->SetProgress(e.GetInt());
1280 UpdateTaskBarProgressBar();
1281 };
1282
UpdateTaskBarProgressBar()1283 void BatchFrame::UpdateTaskBarProgressBar()
1284 {
1285 #if defined __WXMSW__ && wxCHECK_VERSION(3,1,0)
1286 // provide also a feedback in task bar if available
1287 if (IsShown())
1288 {
1289 wxTaskBarButton* taskBarButton = MSWGetTaskBarButton();
1290 if (taskBarButton != NULL)
1291 {
1292 if (m_progStatusBar->GetProgress() < 0)
1293 {
1294 taskBarButton->SetProgressValue(wxTASKBAR_BUTTON_NO_PROGRESS);
1295 }
1296 else
1297 {
1298 taskBarButton->SetProgressRange(100);
1299 taskBarButton->SetProgressState(m_batch->IsPaused() ? wxTASKBAR_BUTTON_PAUSED : wxTASKBAR_BUTTON_NORMAL);
1300 taskBarButton->SetProgressValue(m_progStatusBar->GetProgress());
1301 };
1302 };
1303 };
1304 #endif
1305 };
1306
OnMinimize(wxIconizeEvent & e)1307 void BatchFrame::OnMinimize(wxIconizeEvent& e)
1308 {
1309 //hide/show window in taskbar when minimizing
1310 if(m_tray!=NULL)
1311 {
1312 Show(!e.IsIconized());
1313 //switch off verbose output if PTBatcherGUI is in tray/taskbar
1314 if(e.IsIconized())
1315 {
1316 m_batch->verbose=false;
1317 }
1318 else
1319 {
1320 m_batch->verbose=XRCCTRL(*this,"cb_verbose",wxCheckBox)->IsChecked();
1321 UpdateTaskBarProgressBar();
1322 };
1323 m_batch->ShowOutput(m_batch->verbose);
1324 }
1325 else //don't hide window if no tray icon
1326 {
1327 if (!e.IsIconized())
1328 {
1329 // window is restored, update progress indicators
1330 UpdateTaskBarProgressBar();
1331 };
1332 e.Skip();
1333 };
1334 };
1335
UpdateBatchVerboseStatus()1336 void BatchFrame::UpdateBatchVerboseStatus()
1337 {
1338 m_batch->verbose=XRCCTRL(*this,"cb_verbose",wxCheckBox)->IsChecked();
1339 m_batch->ShowOutput(m_batch->verbose);
1340 };
1341
OnRefillListBox(wxCommandEvent & event)1342 void BatchFrame::OnRefillListBox(wxCommandEvent& event)
1343 {
1344 const HuginBase::UIntSet selected = projListBox->GetSelectedProjects();
1345 std::set<long> selectedID;
1346 for (auto index : selected)
1347 {
1348 selectedID.insert(m_batch->GetProject(index)->id);
1349 };
1350 projListBox->DeleteAllItems();
1351 projListBox->Fill(m_batch);
1352 for(auto id:selectedID)
1353 {
1354 int index=projListBox->GetIndex(id);
1355 if(index!=-1)
1356 {
1357 projListBox->Select(index);
1358 };
1359 };
1360 };
1361
OnMinimizeTrayMenu(wxCommandEvent & event)1362 void BatchFrame::OnMinimizeTrayMenu(wxCommandEvent& event)
1363 {
1364 UpdateTrayIcon(event.IsChecked());
1365 wxConfigBase* config=wxConfigBase::Get();
1366 config->Write(wxT("/BatchFrame/minimizeTray"), event.IsChecked());
1367 config->Flush();
1368 }
1369
UpdateTrayIcon(const bool createTrayIcon)1370 void BatchFrame::UpdateTrayIcon(const bool createTrayIcon)
1371 {
1372 if (createTrayIcon)
1373 {
1374 // create tray icon only if it not exists
1375 if (m_tray)
1376 {
1377 delete m_tray;
1378 m_tray = NULL;
1379 }
1380 m_tray = new BatchTaskBarIcon();
1381 if (m_batch->IsRunning())
1382 {
1383 m_tray->SetIcon(m_iconRunning, _("Processing Hugin's batch queue"));
1384 }
1385 else
1386 {
1387 if (m_batch->IsPaused())
1388 {
1389 m_tray->SetIcon(m_iconPaused, _("Pausing processing Hugin's batch queue"));
1390 }
1391 else
1392 {
1393 m_tray->SetIcon(m_iconNormal, _("Hugin's Batch processor"));
1394 }
1395 }
1396 }
1397 else
1398 {
1399 // destroy tray icon
1400 if (m_tray)
1401 {
1402 delete m_tray;
1403 m_tray = NULL;
1404 }
1405 }
1406 }
1407