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