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