Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MainFrame.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
27 #include "hugin_config.h"
28 
29 #include <wx/dir.h>
30 #include <wx/stdpaths.h>
31 #include <wx/wfstream.h>
32 #include "panoinc_WX.h"
33 #include "panoinc.h"
34 
35 #include "base_wx/platform.h"
36 #include "base_wx/wxPlatform.h"
37 #include "base_wx/wxutils.h"
38 
39 #include "vigra/imageinfo.hxx"
40 #include "vigra_ext/Correlation.h"
41 
42 #include "hugin/config_defaults.h"
44 #include "hugin/MainFrame.h"
45 #include "base_wx/wxPanoCommand.h"
46 #include "base_wx/CommandHistory.h"
47 #include "hugin/PanoPanel.h"
48 #include "hugin/ImagesPanel.h"
49 #include "hugin/MaskEditorPanel.h"
50 #include "hugin/OptimizePanel.h"
52 #include "hugin/PreviewFrame.h"
53 #include "hugin/GLPreviewFrame.h"
54 #include "hugin/huginApp.h"
55 #include "hugin/CPEditorPanel.h"
56 #include "hugin/CPListFrame.h"
59 #include "hugin/PanoOperation.h"
60 #include "hugin/PapywizardImport.h"
61 
63 #include "base_wx/RunStitchPanel.h"
64 #include "base_wx/wxImageCache.h"
65 #include "base_wx/PTWXDlg.h"
69 
70 #include "base_wx/huginConfig.h"
71 #include "hugin/AboutDialog.h"
72 #include "hugin/RawImport.h"
73 #include "hugin/BrowseDialog.h"
74 
75 #if HUGIN_HSI
76 #include "PluginItems.h"
77 #endif
78 
79 #ifdef __MINGW32__
80 // fixes for mingw compilation...
81 #undef FindWindow
82 #endif
83 
88 class HuginSplashScreen : public wxFrame
89 {
90 public:
92  HuginSplashScreen(wxWindow* parent, wxBitmap bitmap) :
93  wxFrame(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxFRAME_TOOL_WINDOW | wxFRAME_NO_TASKBAR | wxSTAY_ON_TOP)
94  {
95  SetExtraStyle(GetExtraStyle() | wxWS_EX_TRANSIENT);
96  wxSizer* topSizer=new wxBoxSizer(wxVERTICAL);
97  wxStaticBitmap* staticBitmap=new wxStaticBitmap(this,wxID_ANY,bitmap);
98  topSizer->Add(staticBitmap,1,wxEXPAND);
99  SetSizerAndFit(topSizer);
100  SetClientSize(bitmap.GetWidth(), bitmap.GetHeight());
101  CenterOnScreen();
102  Show(true);
103  SetFocus();
104 #if defined(__WXMSW__) || defined(__WXMAC__)
105  Update();
106 #elif defined(__WXGTK20__)
107  //do nothing
108 #else
109  wxYieldIfNeeded();
110 #endif
111  };
112  DECLARE_DYNAMIC_CLASS(HuginSplashScreen)
113 };
114 
116 
117 
118 bool PanoDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
119 {
120  DEBUG_TRACE("OnDropFiles");
121  MainFrame * mf = MainFrame::Get();
122  if (!mf) return false;
123 
124  if (!m_imageOnly && filenames.GetCount() == 1) {
125  wxFileName file(filenames[0]);
126  if (file.GetExt().CmpNoCase("pto") == 0 ||
127  file.GetExt().CmpNoCase("ptp") == 0 ||
128  file.GetExt().CmpNoCase("pts") == 0 )
129  {
130  // load project
132  {
133  mf->LoadProjectFile(file.GetFullPath());
134  // remove old images from cache
135  ImageCache::getInstance().flush();
136  }
137  return true;
138  }
139  }
140 
141  // try to add as images
142  std::vector<std::string> filesv;
143  std::vector<std::string> rawFilesv;
144  wxArrayString invalidFiles;
145  for (unsigned int i=0; i< filenames.GetCount(); i++) {
146  wxFileName file(filenames[i]);
147  // first check if raw file
148  // vigra::isImage reports also some raw files as image because
149  // technical some of them are tiff files
150  if (IsRawExtension(file.GetExt()))
151  {
152  if (containsInvalidCharacters(filenames[i]))
153  {
154  invalidFiles.Add(file.GetFullPath());
155  }
156  else
157  {
158  rawFilesv.push_back((const char *)file.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
159  };
160  }
161  else
162  {
163  // now check if drop file is a image
164  if (vigra::isImage(file.GetFullPath().mb_str(HUGIN_CONV_FILENAME)))
165  {
166  if (containsInvalidCharacters(filenames[i]))
167  {
168  invalidFiles.Add(file.GetFullPath());
169  }
170  else
171  {
172  filesv.push_back((const char *)filenames[i].mb_str(HUGIN_CONV_FILENAME));
173  };
174  };
175  };
176  }
177  // show warning about invalid file names
178  if (!invalidFiles.empty())
179  {
180  ShowFilenameWarning(mf, invalidFiles);
181  }
182  // we got some images to add.
183  if (!filesv.empty())
184  {
185  // use a Command to ensure proper undo and updating of GUI parts
186  wxBusyCursor();
187  if(pano.getNrOfCtrlPoints()>0)
188  {
190  }
191  else
192  {
193  std::vector<PanoCommand::PanoCommand*> cmds;
194  cmds.push_back(new PanoCommand::wxAddImagesCmd(pano, filesv));
195  cmds.push_back(new PanoCommand::DistributeImagesCmd(pano));
196  cmds.push_back(new PanoCommand::CenterPanoCmd(pano));
198  };
199  };
200  if (!rawFilesv.empty())
201  {
202  if (rawFilesv.size() == 1)
203  {
204  hugin_utils::MessageDialog message = hugin_utils::GetMessageDialog(_("You selected only one raw file. This is not recommended.\nAll raw files should be converted at once."),
205  _("Hugin"), wxICON_EXCLAMATION | wxOK | wxCANCEL, mf);
206  message->SetOKLabel(_("Convert anyway."));
207  if (message->ShowModal() != wxID_OK)
208  {
209  return true;
210  };
211  };
212  RawImportDialog dlg(mf, &pano, rawFilesv);
213  // check that raw files are from same camera and that all can be read
214  if (dlg.CheckRawFiles())
215  {
216  // now show dialog
217  if (dlg.ShowModal() == wxID_OK)
218  {
220  };
221  };
222  };
223  return true;
224 }
225 
226 wxDEFINE_EVENT(EVT_LOADING_FAILED, wxCommandEvent);
227 
228 enum
229 {
230  wxIDPYTHONSCRIPTS = wxID_HIGHEST + 2000,
231  wxIDUSEROUTPUTSEQUENCE = wxID_HIGHEST + 2500,
232  wxIDUSERASSISTANT = wxID_HIGHEST + 3000
233 };
234 
235 MainFrame::MainFrame(wxWindow* parent, HuginBase::Panorama & pano)
236  : cp_frame(0), pano(pano)
237 {
238  preview_frame = 0;
239  svmModel=NULL;
240 
241  bool disableOpenGL=false;
242  if(wxGetKeyState(WXK_COMMAND))
243  {
244  wxDialog dlg;
245  wxXmlResource::Get()->LoadDialog(&dlg, NULL, "disable_opengl_dlg");
246  long noOpenGL=wxConfigBase::Get()->Read("DisableOpenGL", 0l);
247  if(noOpenGL==1)
248  {
249  XRCCTRL(dlg, "disable_dont_ask_checkbox", wxCheckBox)->SetValue(true);
250  };
251  if(dlg.ShowModal()==wxID_OK)
252  {
253  if(XRCCTRL(dlg, "disable_dont_ask_checkbox", wxCheckBox)->IsChecked())
254  {
255  wxConfigBase::Get()->Write("DisableOpenGL", 1l);
256  }
257  else
258  {
259  wxConfigBase::Get()->Write("DisableOpenGL", 0l);
260  };
261  disableOpenGL=true;
262  }
263  else
264  {
265  wxConfigBase::Get()->Write("DisableOpenGL", 0l);
266  };
267  }
268  else
269  {
270  long noOpenGL=wxConfigBase::Get()->Read("DisableOpenGL", 0l);
271  disableOpenGL=(noOpenGL==1);
272  };
273 
274  wxBitmap bitmap;
275  HuginSplashScreen* splash = 0;
276  wxYield();
277 
278  if (bitmap.LoadFile(huginApp::Get()->GetXRCPath() + "data/splash.png", wxBITMAP_TYPE_PNG))
279  {
280  // embed package version into string.
281  {
282  wxMemoryDC dc;
283  dc.SelectObject(bitmap);
284 #ifdef __WXMAC__
285  wxFont font(9, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
286 #else
287  wxFont font(8, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
288 #endif
289  dc.SetFont(font);
290  dc.SetTextForeground(*wxBLACK);
291  dc.SetTextBackground(*wxWHITE);
292  int tw, th;
293  wxString version;
294  version.Printf(_("Version %s"), wxString(hugin_utils::GetHuginVersion().c_str(), wxConvLocal).c_str());
295  dc.GetTextExtent(version, &tw, &th);
296  // place text on bitmap.
297  dc.DrawText(version, bitmap.GetWidth() - tw - 3, bitmap.GetHeight() - th - 3);
298  dc.SelectObject(wxNullBitmap);
299  }
300  bitmap.SetScaleFactor(GetDPIScaleFactor());
301  splash = new HuginSplashScreen(NULL, bitmap);
302  } else {
303  wxLogFatalError(_("Fatal installation error\nThe file data/splash.png was not found at:") + huginApp::Get()->GetXRCPath());
304  abort();
305  }
306  //splash->Refresh();
307  wxYield();
308 
309  // save our pointer
310  m_this = this;
311 
312  DEBUG_TRACE("");
313  // load our children. some children might need special
314  // initialization. this will be done later.
315  wxXmlResource::Get()->LoadFrame(this, parent, "main_frame");
316  DEBUG_TRACE("");
317 
318  // load our menu bar
319 #ifdef __WXMAC__
320  wxApp::s_macAboutMenuItemId = XRCID("action_show_about");
321  wxApp::s_macPreferencesMenuItemId = XRCID("action_show_prefs");
322  wxApp::s_macExitMenuItemId = XRCID("action_exit_hugin");
323  wxApp::s_macHelpMenuTitleName = _("&Help");
324 #endif
325  wxMenuBar* mainMenu=wxXmlResource::Get()->LoadMenuBar(this, "main_menubar");
326  m_menu_file_simple=wxXmlResource::Get()->LoadMenu("file_menu_simple");
327  m_menu_file_advanced=wxXmlResource::Get()->LoadMenu("file_menu_advanced");
328  mainMenu->Insert(0, m_menu_file_simple, _("&File"));
329  SetMenuBar(mainMenu);
330  m_optOnlyActiveImages = (wxConfigBase::Get()->Read("/OptimizePanel/OnlyActiveImages", 1l) != 0);
331  m_optIgnoreLineCp = false;
332  // observe the panorama, this should be the first observer
333  pano.addObserver(this);
334 
335 #ifdef HUGIN_HSI
336  wxMenuBar* menubar=GetMenuBar();
337  // the plugin menu will be generated dynamically
338  wxMenu *pluginMenu=new wxMenu();
339  // search for all .py files in plugins directory
340  wxDir dir(GetDataPath()+"plugins");
341  if (dir.IsOpened())
342  {
343  wxString filename;
344  bool cont = dir.GetFirst(&filename, "*.py", wxDIR_FILES | wxDIR_HIDDEN);
345  PluginItems items;
346  while (cont)
347  {
348  wxFileName file(dir.GetName(), filename);
349  file.MakeAbsolute();
350  PluginItem item(file);
351  if (item.IsAPIValid())
352  {
353  items.push_back(item);
354  };
355  cont = dir.GetNext(&filename);
356  };
357  items.sort(comparePluginItem);
358 
359  int pluginID = wxIDPYTHONSCRIPTS;
360  for (PluginItems::const_iterator it = items.begin(); it != items.end(); ++it)
361  {
362  PluginItem item = *it;
363  int categoryID = pluginMenu->FindItem(item.GetCategory());
364  wxMenu* categoryMenu;
365  if (categoryID == wxNOT_FOUND)
366  {
367  categoryMenu = new wxMenu();
368  pluginMenu->AppendSubMenu(categoryMenu, item.GetCategory());
369  }
370  else
371  {
372  categoryMenu = pluginMenu->FindItem(categoryID)->GetSubMenu();
373  };
374  categoryMenu->Append(pluginID, item.GetName(), item.GetDescription());
375  m_plugins[pluginID] = item.GetFilename();
376  Bind(wxEVT_MENU, &MainFrame::OnPlugin, this, pluginID);
377  pluginID++;
378  };
379  // show the new menu
380  if (pluginMenu->GetMenuItemCount() > 0)
381  {
382  menubar->Insert(menubar->GetMenuCount() - 2, pluginMenu, _("&Actions"));
383  };
384  };
385 #else
386  GetMenuBar()->Enable(XRCID("action_python_script"), false);
387 #endif
388 
389  // create tool bar
390  SetToolBar(wxXmlResource::Get()->LoadToolBar(this, "main_toolbar"));
391 
392  // Disable tools by default
393  enableTools(false);
394 
395  // put an "unknown" object in an xrc file and
396  // take as wxObject (second argument) the return value of wxXmlResource::Get
397  // finish the images_panel
398  DEBUG_TRACE("");
399 
400  // image_panel
401  images_panel = XRCCTRL(*this, "images_panel_unknown", ImagesPanel);
402  assert(images_panel);
403  images_panel->Init(&pano);
404  DEBUG_TRACE("");
405 
406  m_notebook = XRCCTRL((*this), "controls_notebook", wxNotebook);
407 // m_notebook = ((wxNotebook*) ((*this).FindWindow(XRCID("controls_notebook"))));
408 // m_notebook = ((wxNotebook*) (FindWindow(XRCID("controls_notebook"))));
410 
411  // the mask panel
412  mask_panel = XRCCTRL(*this, "mask_panel_unknown", MaskEditorPanel);
413  assert(mask_panel);
414  mask_panel->Init(&pano);
415 
416  // the pano_panel
417  DEBUG_TRACE("");
418  pano_panel = XRCCTRL(*this, "panorama_panel_unknown", PanoPanel);
419  assert(pano_panel);
420  pano_panel->Init(&pano);
421  pano_panel->panoramaChanged (pano); // initialize from pano
422 
423  cpe = XRCCTRL(*this, "cp_editor_panel_unknown", CPEditorPanel);
424  assert(cpe);
425  cpe->Init(&pano);
426 
427  opt_panel = XRCCTRL(*this, "optimizer_panel_unknown", OptimizePanel);
428  assert(opt_panel);
429  opt_panel->Init(&pano);
430  m_show_opt_panel=true;
431 
432  opt_photo_panel = XRCCTRL(*this, "optimizer_photometric_panel_unknown", OptimizePhotometricPanel);
433  assert(opt_photo_panel);
434  opt_photo_panel->Init(&pano);
436 
437  // generate list of most recently uses files and add it to menu
438  // needs to be initialized before the fast preview, there we call AddFilesToMenu()
439  wxConfigBase * config=wxConfigBase::Get();
440  m_mruFiles.Load(*config);
441  m_mruFiles.UseMenu(m_menu_file_advanced->FindItem(XRCID("menu_mru"))->GetSubMenu());
442 
443  preview_frame = new PreviewFrame(this, pano);
444  if(disableOpenGL)
445  {
446  gl_preview_frame=NULL;
448  m_mruFiles.AddFilesToMenu();
449  }
450  else
451  {
452  gl_preview_frame = new GLPreviewFrame(this, pano);
453  };
454 
455  // add saved user defined output sequences
456  {
457  wxArrayString files;
458  // search all .executor files, do not follow links
459  wxDir::GetAllFiles(GetDataPath()+"output", &files, "*.executor", wxDIR_FILES | wxDIR_HIDDEN | wxDIR_NO_FOLLOW);
460  const size_t nrAllUserSequences = files.size();
461  wxDir::GetAllFiles(hugin_utils::GetUserAppDataDir(), &files, "*.executor", wxDIR_FILES | wxDIR_HIDDEN | wxDIR_NO_FOLLOW);
462  if (!files.IsEmpty())
463  {
464  // we found some files
465  long outputId = wxIDUSEROUTPUTSEQUENCE;
466  int outputMenuId=mainMenu->FindMenu(_("&Output"));
467  if (outputMenuId != wxNOT_FOUND)
468  {
469  wxMenu* outputSequencesMenu = new wxMenu;
470  size_t i = 0;
471  for (auto file : files)
472  {
473  if (i > 0 && i == nrAllUserSequences && outputSequencesMenu->GetMenuItemCount() > 0)
474  {
475  outputSequencesMenu->AppendSeparator();
476  if (gl_preview_frame)
477  {
478  // add assistant to context menu on align button
479  gl_preview_frame->AddUserDefinedSequence(-1, wxEmptyString, wxEmptyString);
480  };
481 
482  };
483  wxFileInputStream inputStream(file);
484  if (inputStream.IsOk())
485  {
486  // read descriptions from file
487  wxFileConfig executorFile(inputStream);
488  wxString desc = HuginQueue::GetSettingStringTranslated(&executorFile, "/General/Description", wxEmptyString);
489  wxString help = HuginQueue::GetSettingStringTranslated(&executorFile, "/General/Help", wxEmptyString);
490  if (help.IsEmpty())
491  {
492  help = wxString::Format(_("User defined sequence: %s"), file);
493  };
494  // add menu
495  if (!desc.IsEmpty())
496  {
497  outputSequencesMenu->Append(outputId, desc, help);
498  Bind(wxEVT_MENU, &MainFrame::OnUserDefinedStitchSaved, this, outputId);
499  m_userOutput[outputId] = file;
500  if (gl_preview_frame)
501  {
502  // add output sequence to context menu on create button
503  gl_preview_frame->AddUserDefinedSequence(outputId, desc, help);
504  };
505  ++outputId;
506  };
507  };
508  i++;
509  };
510  if ((outputSequencesMenu->GetMenuItemCount() == 1 && !(outputSequencesMenu->FindItemByPosition(0)->IsSeparator())) ||
511  outputSequencesMenu->GetMenuItemCount() > 1)
512  {
513  m_outputUserMenu = mainMenu->GetMenu(outputMenuId)->AppendSubMenu(outputSequencesMenu, _("User defined output sequences"));
514  }
515  else
516  {
517  delete outputSequencesMenu;
518  };
519  };
520  };
521  };
522  // add saved user defined assistants
523  {
524  wxArrayString files;
525  // search all .assistant files, do not follow links
526  wxDir::GetAllFiles(GetDataPath() + "assistant", &files, "*.assistant", wxDIR_FILES | wxDIR_HIDDEN | wxDIR_NO_FOLLOW);
527  const size_t nrAllUserSequences = files.size();
528  wxDir::GetAllFiles(hugin_utils::GetUserAppDataDir(), &files, "*.assistant", wxDIR_FILES | wxDIR_HIDDEN | wxDIR_NO_FOLLOW);
529  if (!files.IsEmpty())
530  {
531  // we found some files
532  long assistantId = wxIDUSERASSISTANT;
533  const int editMenuId = mainMenu->FindMenu(_("&Edit"));
534  if (editMenuId != wxNOT_FOUND)
535  {
536  wxMenu* userAssistantMenu = new wxMenu;
537  size_t i = 0;
538  for (auto file : files)
539  {
540  if (i > 0 && i == nrAllUserSequences && userAssistantMenu->GetMenuItemCount() > 0)
541  {
542  userAssistantMenu->AppendSeparator();
543  if (gl_preview_frame)
544  {
545  // add assistant to context menu on align button
546  gl_preview_frame->AddUserDefinedAssistant(-1, wxEmptyString, wxEmptyString);
547  };
548  };
549  wxFileInputStream inputStream(file);
550  if (inputStream.IsOk())
551  {
552  // read descriptions from file
553  wxFileConfig assistantFile(inputStream);
554  wxString desc = HuginQueue::GetSettingStringTranslated(&assistantFile, "/General/Description", wxEmptyString);
555  wxString help = HuginQueue::GetSettingStringTranslated(&assistantFile, "/General/Help", wxEmptyString);
556  help = help.Trim(true).Trim(false);
557  if (help.IsEmpty())
558  {
559  help = wxString::Format(_("User defined assistant: %s"), file);
560  };
561  // add menu
562  if (!desc.IsEmpty())
563  {
564  userAssistantMenu->Append(assistantId, desc, help);
565  Bind(wxEVT_MENU, &MainFrame::OnRunAssistantUserdefined, this, assistantId);
566  m_userAssistant[assistantId] = file;
567  if (gl_preview_frame)
568  {
569  // add assistant to context menu on align button
570  gl_preview_frame->AddUserDefinedAssistant(assistantId, desc, help);
571  };
572  ++assistantId;
573  };
574  };
575  i++;
576  };
577  if (userAssistantMenu->GetMenuItemCount() > 0)
578  {
579  m_assistantUserMenu = mainMenu->GetMenu(editMenuId)->Insert(5, wxID_ANY, _("User defined assistant"), userAssistantMenu);
580  }
581  else
582  {
583  delete userAssistantMenu;
584  };
585  };
586  };
587  };
588 
589 
590  // set the minimize icon
591 #ifdef __WXMSW__
592  wxIconBundle myIcons(GetXRCPath() + "data/hugin.ico", wxBITMAP_TYPE_ICO);
593  SetIcons(myIcons);
594 #else
595  wxIcon myIcon(GetXRCPath() + "data/hugin.png",wxBITMAP_TYPE_PNG);
596  SetIcon(myIcon);
597 #endif
598 
599  // create a new drop handler. wxwindows deletes the automaticall
600  SetDropTarget(new PanoDropTarget(pano));
601  DEBUG_TRACE("");
602 
604 
605  // create a status bar
606  const int fields (2);
607  CreateStatusBar(fields);
608  int widths[fields] = {-1, 85};
609  SetStatusWidths( fields, &widths[0]);
610  SetStatusText(_("Started"), 0);
611  wxYield();
612  DEBUG_TRACE("");
613 
614  // Set sizing characteristics
615  //set minumum size
616 #if defined __WXMAC__ || defined __WXMSW__
617  // a minimum nice looking size; smaller than this would clutter the layout.
618  SetSizeHints(900, 675);
619 #else
620  // For ASUS eeePc
621  SetSizeHints(780, 455); //set minumum size
622 #endif
623 
624  // set progress display for image cache.
625  ImageCache::getInstance().setProgressDisplay(this);
626 #if defined __WXMSW__
627  unsigned long long mem = HUGIN_IMGCACHE_UPPERBOUND;
628  unsigned long mem_low = wxConfigBase::Get()->Read("/ImageCache/UpperBound", HUGIN_IMGCACHE_UPPERBOUND);
629  unsigned long mem_high = wxConfigBase::Get()->Read("/ImageCache/UpperBoundHigh", (long) 0);
630  if (mem_high > 0) {
631  mem = ((unsigned long long) mem_high << 32) + mem_low;
632  }
633  else {
634  mem = mem_low;
635  }
636  ImageCache::getInstance().SetUpperLimit(mem);
637 #else
638  ImageCache::getInstance().SetUpperLimit(wxConfigBase::Get()->Read("/ImageCache/UpperBound", HUGIN_IMGCACHE_UPPERBOUND));
639 #endif
640 
641  if(splash) {
642  splash->Close();
643  delete splash;
644  }
645  wxYield();
646 
647  // disable automatic Layout() calls, to it by hand
648  SetAutoLayout(false);
650 
651 // By using /SUBSYSTEM:CONSOLE /ENTRY:"WinMainCRTStartup" in the linker
652 // options for the debug build, a console window will be used for stdout
653 // and stderr. No need to redirect to a file. Better security since we can't
654 // guarantee that c: exists and writing a file to the root directory is
655 // never a good idea. release build still uses /SUBSYSTEM:WINDOWS
656 
657 #if 0
658 #ifdef DEBUG
659 #ifdef __WXMSW__
660 
661  freopen("c:\\hugin_stdout.txt", "w", stdout); // redirect stdout to file
662  freopen("c:\\hugin_stderr.txt", "w", stderr); // redirect stderr to file
663 #endif
664 #endif
665 #endif
666  //reload gui level
668  long guiLevel=config->Read("/GuiLevel",(long)0);
669  guiLevel = std::max<long>(0, std::min<long>(2, guiLevel));
670  if(guiLevel==GUI_SIMPLE && disableOpenGL)
671  {
672  guiLevel=GUI_ADVANCED;
673  };
674  SetGuiLevel(static_cast<GuiLevel>(guiLevel));
675 
676 #ifndef __WXMSW__
677  // check settings of help window and fix when needed
678  FixHelpSettings();
679 #endif
680  // bind handler for menu items
681  Bind(wxEVT_MENU, &MainFrame::OnNewProject, this, XRCID("action_new_project"));
682  Bind(wxEVT_MENU, &MainFrame::OnLoadProject, this, XRCID("action_load_project"));
683  Bind(wxEVT_MENU, &MainFrame::OnBrowseProjects, this, XRCID("action_browse_projects"));
684  Bind(wxEVT_MENU, &MainFrame::OnSaveProject, this, XRCID("action_save_project"));
685  Bind(wxEVT_MENU, &MainFrame::OnSaveProjectAs, this, XRCID("action_save_as_project"));
686  Bind(wxEVT_MENU, &MainFrame::OnSavePTStitcherAs, this, XRCID("action_save_as_ptstitcher"));
687  Bind(wxEVT_MENU, &MainFrame::OnOpenPTBatcher, this, XRCID("action_open_batch_processor"));
688  Bind(wxEVT_MENU, &MainFrame::OnMergeProject, this, XRCID("action_import_project"));
689  Bind(wxEVT_MENU, &MainFrame::OnReadPapywizard, this, XRCID("action_import_papywizard"));
690  Bind(wxEVT_MENU, &MainFrame::OnApplyTemplate, this, XRCID("action_apply_template"));
691  Bind(wxEVT_MENU, &MainFrame::OnUserQuit, this, XRCID("action_exit_hugin"));
692  for (int i = 0; i < 9; ++i)
693  {
694  Bind(wxEVT_MENU, &MainFrame::OnMRUFiles, this, wxID_FILE1 + i);
695  }
696  Bind(wxEVT_MENU, &MainFrame::OnAbout, this, XRCID("action_show_about"));
697  Bind(wxEVT_MENU, &MainFrame::OnHelp, this, XRCID("action_show_help"));
698  Bind(wxEVT_MENU, &MainFrame::OnTipOfDay, this, XRCID("action_show_tip"));
699  Bind(wxEVT_MENU, &MainFrame::OnKeyboardHelp, this, XRCID("action_show_shortcuts"));
700  Bind(wxEVT_MENU, &MainFrame::OnFAQ, this, XRCID("action_show_faq"));
701  Bind(wxEVT_MENU, &MainFrame::OnShowPrefs, this, XRCID("action_show_prefs"));
702  Bind(wxEVT_MENU, &MainFrame::OnRunAssistant, this, XRCID("action_assistant"));
703  Bind(wxEVT_MENU, &MainFrame::OnSendToAssistantQueue, this, XRCID("action_batch_assistant"));
704  Bind(wxEVT_MENU, &MainFrame::OnSetGuiSimple, this, XRCID("action_gui_simple"));
705  Bind(wxEVT_MENU, &MainFrame::OnSetGuiAdvanced, this, XRCID("action_gui_advanced"));
706  Bind(wxEVT_MENU, &MainFrame::OnSetGuiExpert, this, XRCID("action_gui_expert"));
707 #ifdef HUGIN_HSI
708  Bind(wxEVT_MENU, &MainFrame::OnPythonScript, this, XRCID("action_python_script"));
709 #endif
710  Bind(wxEVT_MENU, &MainFrame::OnUndo, this, XRCID("ID_EDITUNDO"));
711  Bind(wxEVT_MENU, &MainFrame::OnRedo, this, XRCID("ID_EDITREDO"));
712  Bind(wxEVT_MENU, &MainFrame::OnFullScreen, this, XRCID("ID_SHOW_FULL_SCREEN"));
713  Bind(wxEVT_MENU, &MainFrame::OnTogglePreviewFrame, this, XRCID("ID_SHOW_PREVIEW_FRAME"));
714  Bind(wxEVT_MENU, &MainFrame::OnToggleGLPreviewFrame, this, XRCID("ID_SHOW_GL_PREVIEW_FRAME"));
715  Bind(wxEVT_BUTTON, &MainFrame::OnTogglePreviewFrame, this, XRCID("ID_SHOW_PREVIEW_FRAME"));
716  Bind(wxEVT_BUTTON, &MainFrame::OnToggleGLPreviewFrame, this, XRCID("ID_SHOW_GL_PREVIEW_FRAME"));
717 
718  Bind(wxEVT_MENU, &MainFrame::OnOptimize, this, XRCID("action_optimize"));
719  Bind(wxEVT_MENU, &MainFrame::OnOnlyActiveImages, this, XRCID("action_optimize_only_active"));
720  Bind(wxEVT_MENU, &MainFrame::OnIgnoreLineCp, this, XRCID("action_optimize_ignore_line_cp"));
721  Bind(wxEVT_BUTTON, &MainFrame::OnOptimize, this, XRCID("action_optimize"));
722  Bind(wxEVT_MENU, &MainFrame::OnFineTuneAll, this, XRCID("action_finetune_all_cp"));
723  Bind(wxEVT_MENU, &MainFrame::OnRemoveCPinMasks, this, XRCID("action_remove_cp_in_masks"));
724 
725  Bind(wxEVT_MENU, &MainFrame::OnShowCPFrame, this, XRCID("ID_CP_TABLE"));
726  Bind(wxEVT_BUTTON, &MainFrame::OnShowCPFrame, this, XRCID("ID_CP_TABLE"));
727 
728  Bind(wxEVT_MENU, &MainFrame::OnShowPanel, this, XRCID("ID_SHOW_PANEL_IMAGES"));
729  Bind(wxEVT_MENU, &MainFrame::OnShowPanel, this, XRCID("ID_SHOW_PANEL_MASK"));
730  Bind(wxEVT_MENU, &MainFrame::OnShowPanel, this, XRCID("ID_SHOW_PANEL_CP_EDITOR"));
731  Bind(wxEVT_MENU, &MainFrame::OnShowPanel, this, XRCID("ID_SHOW_PANEL_OPTIMIZER"));
732  Bind(wxEVT_MENU, &MainFrame::OnShowPanel, this, XRCID("ID_SHOW_PANEL_OPTIMIZER_PHOTOMETRIC"));
733  Bind(wxEVT_MENU, &MainFrame::OnShowPanel, this, XRCID("ID_SHOW_PANEL_PANORAMA"));
734  Bind(wxEVT_MENU, &MainFrame::OnDoStitch, this, XRCID("action_stitch"));
735  Bind(wxEVT_MENU, &MainFrame::OnUserDefinedStitch, this, XRCID("action_stitch_userdefined"));
736  Bind(wxEVT_MENU, &MainFrame::OnAddImages, this, XRCID("action_add_images"));
737  Bind(wxEVT_BUTTON, &MainFrame::OnAddImages, this, XRCID("action_add_images"));
738  Bind(wxEVT_MENU, &MainFrame::OnAddTimeImages, this, XRCID("action_add_time_images"));
739  Bind(wxEVT_BUTTON, &MainFrame::OnAddTimeImages, this, XRCID("action_add_time_images"));
740  Bind(wxEVT_CLOSE_WINDOW, &MainFrame::OnExit, this);
741  Bind(wxEVT_SIZE, &MainFrame::OnSize, this);
742  Bind(EVT_LOADING_FAILED, &MainFrame::OnLoadingFailed, this);
743 
744  DEBUG_TRACE("");
745 }
746 
748 {
749  DEBUG_TRACE("dtor");
751  {
752  delete m_menu_file_advanced;
753  }
754  else
755  {
756  delete m_menu_file_simple;
757  };
758  ImageCache::getInstance().setProgressDisplay(NULL);
759  delete & ImageCache::getInstance();
761 // delete cpe;
762 // delete images_panel;
763  DEBUG_DEBUG("removing observer");
764  pano.removeObserver(this);
765 
766  // get the global config object
767  wxConfigBase* config = wxConfigBase::Get();
768 
769  hugin_utils::StoreFramePosition(this, "MainFrame");
770 
771  //store most recently used files
772  m_mruFiles.Save(*config);
773  //store gui level
774  config->Write("/GuiLevel",(long)m_guiLevel);
775  // store optimize only active images
776  config->Write("/OptimizePanel/OnlyActiveImages", m_optOnlyActiveImages ? 1l : 0l);
777 
778  config->Flush();
779  if(svmModel!=NULL)
780  {
782  };
784 
785  DEBUG_TRACE("dtor end");
786 }
787 
789 {
790  // set flag to indicate list should show correlation instead of error
791  if (m_showCorrelation == 2)
792  {
793  const std::string lastCommand = PanoCommand::GlobalCmdHist::getInstance().getLastCommandName();
794  if (!(lastCommand == "remove control point" || lastCommand == "remove control points"))
795  {
796  m_showCorrelation = 0;
797  };
798  };
799  if (m_showCorrelation == 1)
800  {
802  };
803  wxToolBar* theToolBar = GetToolBar();
804  wxMenuBar* theMenuBar = GetMenuBar();
806  theMenuBar->Enable (XRCID("ID_EDITUNDO"), can_undo);
807  theToolBar->EnableTool(XRCID("ID_EDITUNDO"), can_undo);
809  theMenuBar->Enable (XRCID("ID_EDITREDO"), can_redo);
810  theToolBar->EnableTool(XRCID("ID_EDITREDO"), can_redo);
811 
812  //show or hide optimizer and exposure optimizer tab depending on optimizer master switches
813  if(pano.getOptimizerSwitch()==0 && !m_show_opt_panel)
814  {
815  m_notebook->InsertPage(3, opt_panel, _("Optimizer"));
816  m_show_opt_panel=true;
817  };
818  if(pano.getOptimizerSwitch()!=0 && m_show_opt_panel)
819  {
820  m_notebook->RemovePage(3);
821  m_show_opt_panel=false;
822  };
824  {
825  if(m_show_opt_panel)
826  {
827  m_notebook->InsertPage(4, opt_photo_panel, _("Exposure"));
828  }
829  else
830  {
831  m_notebook->InsertPage(3, opt_photo_panel, _("Exposure"));
832  }
834  };
836  {
837  if(m_show_opt_panel)
838  {
839  m_notebook->RemovePage(4);
840  }
841  else
842  {
843  m_notebook->RemovePage(3);
844  };
846  };
847  theMenuBar->Enable(XRCID("ID_SHOW_PANEL_OPTIMIZER"), m_show_opt_panel);
848  theMenuBar->Enable(XRCID("ID_SHOW_PANEL_OPTIMIZER_PHOTOMETRIC"), m_show_opt_photo_panel);
849 }
850 
851 //void MainFrame::panoramaChanged(HuginBase::Panorama &panorama)
853 {
854  DEBUG_TRACE("");
855  assert(&pano == &panorama);
857 }
858 
859 void MainFrame::OnUserQuit(wxCommandEvent & e)
860 {
861  Close();
862 }
863 
864 bool MainFrame::CloseProject(bool cancelable, CloseReason reason)
865 {
866  if (pano.isDirty()) {
867  wxString messageString;
868  switch (reason)
869  {
870  case LOAD_NEW_PROJECT:
871  messageString = _("Save changes to the project file before opening another project?");
872  break;
873  case NEW_PROJECT:
874  messageString = _("Save changes to the project file before starting a new project?");
875  break;
876  case CLOSE_PROGRAM:
877  default:
878  messageString = _("Save changes to the project file before closing?");
879  break;
880  };
881  hugin_utils::MessageDialog message = hugin_utils::GetMessageDialog(messageString, _("Hugin"), wxICON_EXCLAMATION | wxYES_NO | (cancelable ? (wxCANCEL) : 0), wxGetActiveWindow());
882  switch(reason)
883  {
884  case LOAD_NEW_PROJECT:
885  message->SetExtendedMessage(_("If you load another project without saving, your changes since last save will be discarded."));
886  break;
887  case NEW_PROJECT:
888  message->SetExtendedMessage(_("If you start a new project without saving, your changes since last save will be discarded."));
889  break;
890  case CLOSE_PROGRAM:
891  default:
892  message->SetExtendedMessage(_("If you close without saving, your changes since your last save will be discarded."));
893  break;
894  };
895  #if defined __WXMAC__ || defined __WXMSW__
896  // Apple human interface guidelines and Windows user experience interaction guidelines
897  message->SetYesNoLabels(wxID_SAVE, _("Do&n't Save"));
898  #else
899  // Gnome human interface guidelines:
900  message->SetYesNoLabels(wxID_SAVE, _("&Close without saving"));
901  #endif
902  const int answer = message->ShowModal();
903  switch (answer)
904  {
905  case wxID_YES:
906  {
907  wxCommandEvent dummy;
908  OnSaveProject(dummy);
909  return !pano.isDirty();
910  }
911  case wxID_CANCEL:
912  return false;
913  default: //no save
914  return true;
915  }
916  }
917  else return true;
918 }
919 
920 void MainFrame::OnExit(wxCloseEvent & e)
921 {
922  DEBUG_TRACE("");
924  {
925  if(!CloseProject(e.CanVeto(), CLOSE_PROGRAM))
926  {
927  if (e.CanVeto())
928  {
929  e.Veto();
930  return;
931  }
932  wxLogError(_("forced close"));
933  }
934  }
935  else
936  {
937  if(e.CanVeto())
938  {
939  Hide();
940  e.Veto();
941  return;
942  };
943  };
944 
945  if(preview_frame)
946  {
947  preview_frame->Close(true);
948  }
949  if(gl_preview_frame)
950  {
952  {
954  }
955  else
956  {
957  gl_preview_frame->Close(true);
958  };
959  }
960 
961  ImageCache::getInstance().flush();
962  Destroy();
963  DEBUG_TRACE("");
964 }
965 
966 void MainFrame::OnSaveProject(wxCommandEvent & e)
967 {
968  DEBUG_TRACE("");
969  try {
970  wxFileName scriptName = m_filename;
971  if (m_filename == wxEmptyString) {
972  OnSaveProjectAs(e);
973  scriptName = m_filename;
974  } else {
975  // the project file is just a PTOptimizer script...
976  DEBUG_DEBUG("stripping " << path << " from image filenames");
977  const std::string script(scriptName.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
979 
980  SetStatusText(wxString::Format(_("saved project %s"), m_filename.c_str()),0);
982  {
983  if(gl_preview_frame)
984  {
985  gl_preview_frame->SetTitle(scriptName.GetName() + "." + scriptName.GetExt() + " - " + _("Hugin - Panorama Creator"));
986  };
987  SetTitle(scriptName.GetName() + "." + scriptName.GetExt() + " - " + _("Panorama editor"));
988  }
989  else
990  {
991  SetTitle(scriptName.GetName() + "." + scriptName.GetExt() + " - " + _("Hugin - Panorama Creator"));
992  };
993 
994  pano.clearDirty();
995  }
996  } catch (std::exception & e) {
997  wxString err(e.what(), wxConvLocal);
998  hugin_utils::HuginMessageBox(wxString::Format(_("Could not save project file \"%s\".\nMaybe the file or the folder is read-only.\n\n(Error code: %s)"),m_filename,err),
999  _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
1000  }
1001 }
1002 
1003 void MainFrame::OnSaveProjectAs(wxCommandEvent & e)
1004 {
1005  DEBUG_TRACE("");
1006  wxFileName scriptName;
1007  if (m_filename.IsEmpty())
1008  {
1009  scriptName.Assign(getDefaultProjectName(pano) + ".pto");
1010  }
1011  else
1012  {
1013  scriptName=m_filename;
1014  };
1015  scriptName.Normalize(wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS | wxPATH_NORM_TILDE | wxPATH_NORM_SHORTCUT);
1016  wxFileDialog dlg(wxGetActiveWindow(),
1017  _("Save project file"),
1018  scriptName.GetPath(), scriptName.GetFullName(),
1019  _("Project files (*.pto)|*.pto|All files (*)|*"),
1020  wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
1021  if (dlg.ShowModal() == wxID_OK) {
1022  wxConfig::Get()->Write("/actualPath", dlg.GetDirectory()); // remember for later
1023  wxString fn = dlg.GetPath();
1024  if (fn.Right(4).CmpNoCase(".pto")!=0)
1025  {
1026  fn.Append(".pto");
1027  if (wxFile::Exists(fn)) {
1028  if (!hugin_utils::AskUserOverwrite(fn, _("Hugin"), wxGetActiveWindow()))
1029  {
1030  return;
1031  }
1032  }
1033  }
1034  m_filename = fn;
1035  m_mruFiles.AddFileToHistory(m_filename);
1036  OnSaveProject(e);
1037  }
1038 }
1039 
1040 void MainFrame::OnSavePTStitcherAs(wxCommandEvent & e)
1041 {
1042  DEBUG_TRACE("");
1043  wxString scriptName = m_filename;
1044  if (m_filename == wxEmptyString) {
1045  scriptName = getDefaultProjectName(pano);
1046  }
1047  wxFileName scriptNameFN(scriptName);
1048  wxString fn = scriptNameFN.GetName() + ".txt";
1049  wxFileDialog dlg(wxGetActiveWindow(),
1050  _("Save PTmender script file"),
1051  wxConfigBase::Get()->Read("/actualPath",wxEmptyString), fn,
1052  _("PTmender files (*.txt)|*.txt"),
1053  wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
1054  if (dlg.ShowModal() == wxID_OK) {
1055  wxString fname = dlg.GetPath();
1056  // the project file is just a PTStitcher script...
1057  wxFileName scriptName = fname;
1058  HuginBase::UIntSet all;
1059  if (pano.getNrOfImages() > 0) {
1060  fill_set(all, 0, pano.getNrOfImages()-1);
1061  }
1062  std::ofstream script(scriptName.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
1063  pano.printStitcherScript(script, pano.getOptions(), all);
1064  script.close();
1065  }
1066 
1067 }
1068 
1069 void MainFrame::LoadProjectFile(const wxString & filename)
1070 {
1071  DEBUG_TRACE("");
1072 
1073  // remove old images from cache
1074  // hmm probably not a good idea, if the project is reloaded..
1075  // ImageCache::getInstance().flush();
1076 
1077  SetStatusText( _("Open project: ") + filename);
1078 
1079  wxFileName fname(filename);
1080  wxString path = fname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
1081  if (fname.IsOk() && fname.FileExists())
1082  {
1083  m_filename = filename;
1084  wxBusyCursor wait;
1087  new PanoCommand::wxLoadPTProjectCmd(pano, (const char *)filename.mb_str(HUGIN_CONV_FILENAME), (const char *)path.mb_str(HUGIN_CONV_FILENAME), true)
1088  );
1090  {
1091  hugin_utils::HuginMessageBox(wxString::Format(_("Could not load project file \"%s\".\nIt is not a valid pto file."), filename), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
1095  return;
1096  };
1099  DEBUG_DEBUG("project contains " << pano.getNrOfImages() << " after load");
1100  GuiLevel reqGuiLevel=GetMinimumGuiLevel(pano);
1101  if(reqGuiLevel>m_guiLevel)
1102  {
1103  SetGuiLevel(reqGuiLevel);
1104  };
1105  if (pano.getNrOfImages() > 0)
1106  {
1107  SetStatusText(_("Project opened"));
1108  m_mruFiles.AddFileToHistory(fname.GetFullPath());
1109  if (m_guiLevel == GUI_SIMPLE)
1110  {
1111  if (gl_preview_frame)
1112  {
1113  gl_preview_frame->SetTitle(fname.GetName() + "." + fname.GetExt() + " - " + _("Hugin - Panorama Stitcher"));
1114  };
1115  SetTitle(fname.GetName() + "." + fname.GetExt() + " - " + _("Panorama editor"));
1116  }
1117  else
1118  {
1119  SetTitle(fname.GetName() + "." + fname.GetExt() + " - " + _("Hugin - Panorama Stitcher"));
1120  };
1121  }
1122  else
1123  {
1124  SetStatusText(_("Loading canceled"));
1125  m_filename = "";
1126  if (m_guiLevel == GUI_SIMPLE)
1127  {
1128  if (gl_preview_frame)
1129  {
1130  gl_preview_frame->SetTitle(_("Hugin - Panorama Stitcher"));
1131  };
1132  SetTitle(_("Panorama editor"));
1133  }
1134  else
1135  {
1136  SetTitle(_("Hugin - Panorama Stitcher"));
1137  };
1138  };
1139  if (! (fname.GetExt() == "pto")) {
1140  // do not remember filename if its not a hugin project
1141  // to avoid overwriting the original project with an
1142  // incompatible one
1143  m_filename = wxEmptyString;
1144  }
1145  // get the global config object
1146  wxConfigBase* config = wxConfigBase::Get();
1147  config->Write("/actualPath", path); // remember for later
1148  } else {
1149  SetStatusText( _("Error opening project: ") + filename);
1150  DEBUG_ERROR("Could not open file " << filename);
1151  }
1152 
1153  // force update of preview window
1154  if ( !(preview_frame->IsIconized() ||(! preview_frame->IsShown()) ) ) {
1155  wxCommandEvent dummy;
1156  preview_frame->OnUpdate(dummy);
1157  };
1158  if (gl_preview_frame)
1159  {
1161  };
1162 }
1163 
1164 #ifdef __WXMAC__
1165 void MainFrame::MacOnOpenFile(const wxString & filename)
1166 {
1167  if(!CloseProject(true, LOAD_NEW_PROJECT)) return; //if closing old project is canceled do nothing.
1168 
1169  ImageCache::getInstance().flush();
1170  LoadProjectFile(filename);
1171 }
1172 #endif
1173 
1174 void MainFrame::OnLoadProject(wxCommandEvent & e)
1175 {
1176  DEBUG_TRACE("");
1177 
1178  if(CloseProject(true, LOAD_NEW_PROJECT)) //if closing old project is canceled do nothing.
1179  {
1180  // get the global config object
1181  wxConfigBase* config = wxConfigBase::Get();
1182 
1183  wxString defaultdir = config->Read("/actualPath",wxEmptyString);
1184  wxFileDialog dlg(wxGetActiveWindow(),
1185  _("Open project file"),
1186  defaultdir, wxEmptyString,
1187  _("Project files (*.pto)|*.pto|All files (*)|*"),
1188  wxFD_OPEN, wxDefaultPosition);
1189  dlg.SetDirectory(defaultdir);
1190  if (dlg.ShowModal() == wxID_OK)
1191  {
1192  wxString filename = dlg.GetPath();
1193  if(vigra::isImage(filename.mb_str(HUGIN_CONV_FILENAME)))
1194  {
1195  if (hugin_utils::HuginMessageBox(wxString::Format(_("File %s is an image file and not a project file.\nThis file can't be open with File, Open.\nDo you want to add this image file to the current project?"), filename.c_str()),
1196  _("Hugin"), wxYES_NO | wxICON_QUESTION, wxGetActiveWindow()) == wxYES)
1197  {
1198  wxArrayString filenameArray;
1199  filenameArray.Add(filename);
1200  AddImages(filenameArray);
1201  };
1202  return;
1203  }
1204  else
1205  {
1206  // remove old images from cache
1207  ImageCache::getInstance().flush();
1208 
1209  LoadProjectFile(filename);
1210  return;
1211  };
1212  }
1213  }
1214  // do not close old project
1215  // nothing to open
1216  SetStatusText( _("Open project: cancel"));
1217 }
1218 
1219 void MainFrame::OnBrowseProjects(wxCommandEvent& e)
1220 {
1221  // first check if there are unsaved changes
1222  if (CloseProject(true, LOAD_NEW_PROJECT))
1223  {
1224  // remove old images from cache
1225  ImageCache::getInstance().flush();
1226  // get the global config object
1227  wxConfigBase* config = wxConfigBase::Get();
1228  // show dialog
1229  BrowsePTOFilesDialog dialog(this, config->Read("/actualPath", ""));
1230  if (dialog.ShowModal() == wxID_OK)
1231  {
1232  // open newly selected file
1233  LoadProjectFile(dialog.GetSelectedProject());
1234  // remember path for later
1235  config->Write("/actualPath", dialog.GetSelectedPath());
1236  };
1237  };
1238 }
1239 
1240 void MainFrame::OnNewProject(wxCommandEvent & e)
1241 {
1242  if(!CloseProject(true, NEW_PROJECT)) return; //if closing current project is canceled
1243 
1244  m_filename = wxEmptyString;
1247  // remove old images from cache
1248  ImageCache::getInstance().flush();
1249  if(m_guiLevel==GUI_SIMPLE)
1250  {
1251  if(gl_preview_frame)
1252  {
1253  gl_preview_frame->SetTitle(_("Hugin - Panorama Stitcher"));
1254  };
1255  SetTitle(_("Panorama editor"));
1256  }
1257  else
1258  {
1259  SetTitle(_("Hugin - Panorama Stitcher"));
1260  };
1261 
1262  wxCommandEvent dummy;
1263  preview_frame->OnUpdate(dummy);
1264  if (gl_preview_frame)
1265  {
1267  };
1268 }
1269 
1270 void MainFrame::OnAddImages( wxCommandEvent& event )
1271 {
1272  DEBUG_TRACE("");
1274  HuginBase::UIntSet images;
1275  PanoCommand::PanoCommand* cmd = addImage.GetCommand(wxGetActiveWindow(), pano, images, m_guiLevel);
1276  if(cmd!=NULL)
1277  {
1279  };
1280 
1281  DEBUG_TRACE("");
1282 }
1283 
1284 void MainFrame::AddImages(wxArrayString& filenameArray)
1285 {
1286  wxArrayString invalidFiles;
1287  for(unsigned int i=0;i<filenameArray.GetCount(); i++)
1288  {
1289  if(containsInvalidCharacters(filenameArray[i]))
1290  {
1291  invalidFiles.Add(filenameArray[i]);
1292  };
1293  };
1294  if(!invalidFiles.empty())
1295  {
1296  ShowFilenameWarning(this, invalidFiles);
1297  }
1298  else
1299  {
1300  std::vector<std::string> filesv;
1301  for (unsigned int i=0; i< filenameArray.GetCount(); i++) {
1302  filesv.push_back((const char *)filenameArray[i].mb_str(HUGIN_CONV_FILENAME));
1303  }
1304 
1305  // we got some images to add.
1306  if (!filesv.empty()) {
1307  // use a Command to ensure proper undo and updating of GUI
1308  // parts
1309  wxBusyCursor();
1311  new PanoCommand::wxAddImagesCmd(pano, filesv)
1312  );
1313  };
1314  };
1315 };
1316 
1317 void MainFrame::OnAddTimeImages( wxCommandEvent& event )
1318 {
1320  HuginBase::UIntSet images;
1321  PanoCommand::PanoCommand* cmd = imageSeriesOp.GetCommand(wxGetActiveWindow(), pano, images, m_guiLevel);
1322  if(cmd!=NULL)
1323  {
1325  };
1326 };
1327 
1328 void MainFrame::OnShowPanel(wxCommandEvent & e)
1329 {
1330  if(e.GetId()==XRCID("ID_SHOW_PANEL_MASK"))
1331  m_notebook->SetSelection(1);
1332  else
1333  if(e.GetId()==XRCID("ID_SHOW_PANEL_CP_EDITOR"))
1334  m_notebook->SetSelection(2);
1335  else
1336  if(e.GetId()==XRCID("ID_SHOW_PANEL_OPTIMIZER"))
1337  m_notebook->SetSelection(3);
1338  else
1339  if(e.GetId()==XRCID("ID_SHOW_PANEL_OPTIMIZER_PHOTOMETRIC"))
1340  {
1341  if(m_show_opt_panel)
1342  {
1343  m_notebook->SetSelection(4);
1344  }
1345  else
1346  {
1347  m_notebook->SetSelection(3);
1348  };
1349  }
1350  else
1351  if(e.GetId()==XRCID("ID_SHOW_PANEL_PANORAMA"))
1352  {
1354  {
1355  m_notebook->SetSelection(5);
1356  }
1357  else
1358  {
1360  {
1361  m_notebook->SetSelection(4);
1362  }
1363  else
1364  {
1365  m_notebook->SetSelection(3);
1366  };
1367  };
1368  }
1369  else
1370  m_notebook->SetSelection(0);
1371 }
1372 
1373 void MainFrame::OnLoadingFailed(wxCommandEvent & e)
1374 {
1375  // check if file exists
1376  if (wxFileExists(e.GetString()))
1377  {
1378  // file exists, but could not loaded
1379  hugin_utils::HuginMessageBox(wxString::Format(_("Could not load image \"%s\".\nThis file is not a valid image.\nThis file will be removed from the project."), e.GetString()),
1380  _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
1381  }
1382  else
1383  {
1384  // file does not exists
1385  hugin_utils::HuginMessageBox(wxString::Format(_("Could not load image \"%s\".\nThis file was renamed, deleted or is on a non-accessible drive.\nThis file will be removed from the project."), e.GetString()),
1386  _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
1387  };
1388  // now remove the file from the pano
1389  const std::string filename(e.GetString().mb_str(HUGIN_CONV_FILENAME));
1390  HuginBase::UIntSet imagesToRemove;
1391  for (size_t i = 0; i < pano.getNrOfImages(); ++i)
1392  {
1393  if (pano.getImage(i).getFilename() == filename)
1394  {
1395  imagesToRemove.insert(i);
1396  };
1397  };
1398  if (!imagesToRemove.empty())
1399  {
1401  };
1402 }
1403 
1404 
1405 void MainFrame::OnAbout(wxCommandEvent & e)
1406 {
1407  AboutDialog dlg(wxGetActiveWindow());
1408  dlg.ShowModal();
1409 }
1410 
1411 /*
1412 void MainFrame::OnAbout(wxCommandEvent & e)
1413 {
1414  DEBUG_TRACE("");
1415  wxDialog dlg;
1416  wxString strFile;
1417  wxString langCode;
1418 
1419  wxXmlResource::Get()->LoadDialog(&dlg, this, "about_dlg");
1420 
1421 #if __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
1422  //rely on the system's locale choice
1423  strFile = MacGetPathToBundledResourceFile(CFSTR("about.htm"));
1424  if(strFile!=wxEmptyString) XRCCTRL(dlg,"about_html",wxHtmlWindow)->LoadPage(strFile);
1425 #else
1426  //if the language is not default, load custom About file (if exists)
1427  langCode = huginApp::Get()->GetLocale().GetName().Left(2).Lower();
1428  DEBUG_INFO("Lang Code: " << langCode.mb_str(wxConvLocal));
1429  if(langCode != wxString("en"))
1430  {
1431  strFile = GetXRCPath() + "data/about_" + langCode + ".htm";
1432  if(wxFile::Exists(strFile))
1433  {
1434  DEBUG_TRACE("Using About: " << strFile.mb_str(wxConvLocal));
1435  XRCCTRL(dlg,"about_html",wxHtmlWindow)->LoadPage(strFile);
1436  }
1437  }
1438 #endif
1439  dlg.ShowModal();
1440 }
1441 */
1442 
1443 void MainFrame::OnHelp(wxCommandEvent & e)
1444 {
1445  DisplayHelp();
1446 }
1447 
1448 void MainFrame::OnKeyboardHelp(wxCommandEvent & e)
1449 {
1450  DisplayHelp("Hugin_Keyboard_shortcuts.html");
1451 }
1452 
1453 void MainFrame::OnFAQ(wxCommandEvent & e)
1454 {
1455  DisplayHelp("Hugin_FAQ.html");
1456 }
1457 
1458 
1459 void MainFrame::DisplayHelp(wxString section)
1460 {
1461  if (section.IsEmpty())
1462  {
1463  GetHelpController().DisplayContents();
1464  }
1465  else
1466  {
1467  GetHelpController().DisplaySection(section);
1468  };
1469 }
1470 
1471 void MainFrame::OnTipOfDay(wxCommandEvent& WXUNUSED(e))
1472 {
1473  wxString strFile;
1474  bool bShowAtStartup;
1475 // DGSW FIXME - Unreferenced
1476 // bool bTipsExist = false;
1477  int nValue;
1478 
1479  wxConfigBase * config = wxConfigBase::Get();
1480  nValue = config->Read("/MainFrame/ShowStartTip",1l);
1481 
1482  //TODO: tips not localisable
1483  DEBUG_INFO("Tip index: " << nValue);
1484  strFile = GetXRCPath() + "data/tips.txt"; //load default file
1485 
1486  DEBUG_INFO("Reading tips from " << strFile.mb_str(wxConvLocal));
1487  wxTipProvider *tipProvider = new LocalizedFileTipProvider(strFile, nValue);
1488  bShowAtStartup = wxShowTip(wxGetActiveWindow(), tipProvider, (nValue ? true : false));
1489 
1490  //store startup preferences
1491  nValue = (bShowAtStartup ? tipProvider->GetCurrentTip() : 0);
1492  DEBUG_INFO("Writing tip index: " << nValue);
1493  config->Write("/MainFrame/ShowStartTip", nValue);
1494  delete tipProvider;
1495 }
1496 
1497 
1498 void MainFrame::OnShowPrefs(wxCommandEvent & e)
1499 {
1500  DEBUG_TRACE("");
1501  PreferencesDialog pref_dlg(wxGetActiveWindow());
1502  pref_dlg.ShowModal();
1503  //update image cache size
1504  wxConfigBase* cfg=wxConfigBase::Get();
1505 #if defined __WXMSW__
1506  unsigned long long mem = HUGIN_IMGCACHE_UPPERBOUND;
1507  unsigned long mem_low = cfg->Read("/ImageCache/UpperBound", HUGIN_IMGCACHE_UPPERBOUND);
1508  unsigned long mem_high = cfg->Read("/ImageCache/UpperBoundHigh", (long) 0);
1509  if (mem_high > 0)
1510  {
1511  mem = ((unsigned long long) mem_high << 32) + mem_low;
1512  }
1513  else
1514  {
1515  mem = mem_low;
1516  }
1517  ImageCache::getInstance().SetUpperLimit(mem);
1518 #else
1519  ImageCache::getInstance().SetUpperLimit(cfg->Read("/ImageCache/UpperBound", HUGIN_IMGCACHE_UPPERBOUND));
1520 #endif
1522  if(gl_preview_frame)
1523  {
1524  gl_preview_frame->SetShowProjectionHints(cfg->Read("/GLPreviewFrame/ShowProjectionHints",HUGIN_SHOW_PROJECTION_HINTS)!=0);
1525  };
1526 }
1527 
1528 void MainFrame::OnTogglePreviewFrame(wxCommandEvent & e)
1529 {
1530  DEBUG_TRACE("");
1531  if (preview_frame->IsIconized()) {
1532  preview_frame->Iconize(false);
1533  }
1534  preview_frame->Show();
1535  preview_frame->Raise();
1536 
1537  // we need to force an update since autoupdate fires
1538  // before the preview frame is shown
1539  wxCommandEvent dummy;
1540  preview_frame->OnUpdate(dummy);
1541 }
1542 
1543 void MainFrame::OnToggleGLPreviewFrame(wxCommandEvent & e)
1544 {
1545  if(gl_preview_frame==NULL)
1546  {
1547  return;
1548  };
1549 #if defined __WXMSW__ || defined __WXMAC__
1551 #endif
1552  if (gl_preview_frame->IsIconized()) {
1553  gl_preview_frame->Iconize(false);
1554  }
1555  gl_preview_frame->Show();
1556 #if defined __WXMSW__
1557  // on wxMSW Show() does not send OnShowEvent needed to update the
1558  // visibility state of the fast preview windows
1559  // so explicit calling this event handler
1560  wxShowEvent se;
1561  se.SetShow(true);
1563 #elif defined __WXGTK__
1565 #endif
1566  gl_preview_frame->Raise();
1567 }
1568 
1569 void MainFrame::OnShowCPFrame(wxCommandEvent & e)
1570 {
1571  DEBUG_TRACE("");
1572  if (cp_frame) {
1573  if (cp_frame->IsIconized()) {
1574  cp_frame->Iconize(false);
1575  }
1576  cp_frame->Show();
1577  cp_frame->Raise();
1578  } else {
1579  cp_frame = new CPListFrame(this, pano);
1580  cp_frame->Show();
1581  }
1582 }
1583 
1585 {
1586  cp_frame = 0;
1587 }
1588 
1589 void MainFrame::OnOptimize(wxCommandEvent & e)
1590 {
1591  DEBUG_TRACE("");
1592  wxCommandEvent dummy;
1593  opt_panel->OnOptimizeButton(dummy);
1594 }
1595 
1596 void MainFrame::OnOnlyActiveImages(wxCommandEvent &e)
1597 {
1598  SetOptimizeOnlyActiveImages(GetMenuBar()->IsChecked(XRCID("action_optimize_only_active")));
1599 };
1600 
1601 void MainFrame::SetOptimizeOnlyActiveImages(const bool onlyActive)
1602 {
1603  m_optOnlyActiveImages = onlyActive;
1604  wxMenuBar* menubar = GetMenuBar();
1605  if (menubar)
1606  {
1607  menubar->Check(XRCID("action_optimize_only_active"), onlyActive);
1608  };
1611  // notify all observer so they can update their display
1612  pano.changeFinished();
1613 };
1614 
1616 {
1617  return m_optOnlyActiveImages;
1618 };
1619 
1620 void MainFrame::OnIgnoreLineCp(wxCommandEvent &e)
1621 {
1622  m_optIgnoreLineCp = GetMenuBar()->IsChecked(XRCID("action_optimize_ignore_line_cp"));
1624  // notify all observer so they can update their display
1625  pano.changeFinished();
1626 };
1627 
1628 void MainFrame::SetOptimizeIgnoreLineCp(const bool ignoreLineCP)
1629 {
1630  m_optIgnoreLineCp = ignoreLineCP;
1631  wxMenuBar* menubar = GetMenuBar();
1632  if (menubar)
1633  {
1634  menubar->Check(XRCID("action_optimize_ignore_line_cp"), ignoreLineCP);
1635  // notify all observer so they can update their display
1636  pano.changeFinished();
1637  };
1638 };
1639 
1641 {
1642  return m_optIgnoreLineCp;
1643 };
1644 
1645 void MainFrame::OnPhotometricOptimize(wxCommandEvent & e)
1646 {
1647  wxCommandEvent dummy;
1649 };
1650 
1651 void MainFrame::OnDoStitch(wxCommandEvent & e)
1652 {
1653  DEBUG_TRACE("");
1654  wxCommandEvent cmdEvt(wxEVT_COMMAND_BUTTON_CLICKED,XRCID("pano_button_stitch"));
1655  pano_panel->GetEventHandler()->AddPendingEvent(cmdEvt);
1656 }
1657 
1658 void MainFrame::OnUserDefinedStitch(wxCommandEvent & e)
1659 {
1661 }
1662 
1663 void MainFrame::OnUserDefinedStitchSaved(wxCommandEvent & e)
1664 {
1665  auto filename = m_userOutput.find(e.GetId());
1666  if (filename != m_userOutput.end())
1667  {
1668  pano_panel->DoUserDefinedStitch(filename->second);
1669  }
1670  else
1671  {
1672  wxBell();
1673  };
1674 }
1675 
1676 void MainFrame::OnMergeProject(wxCommandEvent & e)
1677 {
1678  // get the global config object
1679  wxConfigBase* config = wxConfigBase::Get();
1680 
1681  wxString defaultdir = config->Read("/actualPath",wxEmptyString);
1682  wxFileDialog dlg(wxGetActiveWindow(),
1683  _("Open project file"),
1684  defaultdir, wxEmptyString,
1685  _("Project files (*.pto)|*.pto|All files (*)|*"),
1686  wxFD_OPEN, wxDefaultPosition);
1687  dlg.SetDirectory(defaultdir);
1688  if (dlg.ShowModal() == wxID_OK)
1689  {
1690  wxString filename = dlg.GetPath();
1691  wxFileName fname(filename);
1692  wxString path = fname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
1693  if (fname.IsOk() && fname.FileExists())
1694  {
1695  wxBusyCursor wait;
1697  std::ifstream in((const char *)fname.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
1698  int ptoversion=0;
1699  if (newPano.loadPTScript(in, ptoversion, (const char *)path.mb_str(HUGIN_CONV_FILENAME)))
1700  {
1701  HuginBase::Panorama new_pano;
1702  new_pano.setMemento(newPano);
1704  new PanoCommand::MergePanoCmd(pano, new_pano)
1705  );
1706  m_mruFiles.AddFileToHistory(fname.GetFullPath());
1707  // force update of preview window
1708  if ( !(preview_frame->IsIconized() ||(! preview_frame->IsShown()) ) )
1709  {
1710  wxCommandEvent dummy;
1711  preview_frame->OnUpdate(dummy);
1712  };
1713  }
1714  else
1715  {
1716  hugin_utils::HuginMessageBox(wxString::Format(_("Could not read project file %s."), fname.GetFullPath()), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
1717  };
1718  };
1719  }
1720 }
1721 
1722 void MainFrame::OnReadPapywizard(wxCommandEvent & e)
1723 {
1724  wxString currentDir = wxConfigBase::Get()->Read("/actualPath", wxEmptyString);
1725  wxFileDialog dlg(wxGetActiveWindow(), _("Open Papywizard xml file"),
1726  currentDir, wxEmptyString, _("Papywizard xml files (*.xml)|*.xml|All files (*)|*"),
1727  wxFD_OPEN, wxDefaultPosition);
1728  dlg.SetDirectory(currentDir);
1729  if (dlg.ShowModal() == wxID_OK)
1730  {
1731  wxConfigBase::Get()->Write("/actualPath", dlg.GetDirectory());
1732  Papywizard::ImportPapywizardFile(dlg.GetPath(), pano);
1733  };
1734 };
1735 
1736 void MainFrame::OnApplyTemplate(wxCommandEvent & e)
1737 {
1738  // get the global config object
1739  wxConfigBase* config = wxConfigBase::Get();
1740 
1741  wxFileDialog dlg(wxGetActiveWindow(),
1742  _("Choose template project"),
1743  config->Read("/templatePath",wxEmptyString), wxEmptyString,
1744  _("Project files (*.pto)|*.pto|All files (*)|*"),
1745  wxFD_OPEN, wxDefaultPosition);
1746  dlg.SetDirectory(wxConfigBase::Get()->Read("/templatePath",wxEmptyString));
1747  if (dlg.ShowModal() == wxID_OK) {
1748  wxString filename = dlg.GetPath();
1749  wxConfig::Get()->Write("/templatePath", dlg.GetDirectory()); // remember for later
1750 
1751  std::ifstream file((const char *)filename.mb_str(HUGIN_CONV_FILENAME));
1752 
1755 
1756  }
1757 }
1758 
1759 void MainFrame::OnOpenPTBatcher(wxCommandEvent & e)
1760 {
1761 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
1762  // Original patch for OSX by Charlie Reiman dd. 18 June 2011
1763  // Slightly modified by HvdW. Errors in here are mine, not Charlie's.
1764  FSRef appRef;
1765  FSRef actuallyLaunched;
1766  OSStatus err;
1767  FSRef documentArray[1]; // Don't really need an array if we only have 1 item
1768  LSLaunchFSRefSpec launchSpec;
1769  Boolean isDir;
1770 
1771  err = LSFindApplicationForInfo(kLSUnknownCreator,
1772  CFSTR("net.sourceforge.hugin.PTBatcherGUI"),
1773  NULL,
1774  &appRef,
1775  NULL);
1776  if (err != noErr) {
1777  // error, can't find PTBatcherGUI
1778  hugin_utils::HuginMessageBox(wxString::Format(_("External program %s not found in the bundle, reverting to system path"), "open"), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
1779  // Possibly a silly attempt otherwise the previous would have worked as well, but just try it.
1780  wxExecute(_T("open -b net.sourceforge.hugin.PTBatcherGUI"));
1781  }
1782  else {
1783  wxExecute(_T("open -b net.sourceforge.hugin.PTBatcherGUI"));
1784  }
1785 #else
1786  const wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
1787  wxExecute(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + _T("PTBatcherGUI"));
1788 #endif
1789 }
1790 
1791 void MainFrame::OnFineTuneAll(wxCommandEvent & e)
1792 {
1793  DEBUG_TRACE("");
1794  // fine-tune all points
1795 
1797 
1798  // create a map of all control points.
1799  std::set<unsigned int> unoptimized;
1800  for (unsigned int i=0; i < cps.size(); i++) {
1801  // create all control points.
1802  unoptimized.insert(i);
1803  }
1804 
1805  unsigned int nGood=0;
1806  unsigned int nBad=0;
1807 
1808  wxConfigBase *cfg = wxConfigBase::Get();
1809  double corrThresh=HUGIN_FT_CORR_THRESHOLD;
1810  cfg->Read("/Finetune/CorrThreshold", &corrThresh, HUGIN_FT_CORR_THRESHOLD);
1811  double curvThresh = HUGIN_FT_CURV_THRESHOLD;
1812  cfg->Read("/Finetune/CurvThreshold",&curvThresh, HUGIN_FT_CURV_THRESHOLD);
1813  // load parameters
1814  const long templWidth = cfg->Read("/Finetune/TemplateSize", HUGIN_FT_TEMPLATE_SIZE);
1815  const long sWidth = templWidth + cfg->Read("/Finetune/LocalSearchWidth", HUGIN_FT_LOCAL_SEARCH_WIDTH);
1816 
1817  {
1818  ProgressReporterDialog progress(unoptimized.size(), _("Fine-tuning all points"), _("Fine-tuning"), wxGetActiveWindow());
1819 
1820  ImageCache & imgCache = ImageCache::getInstance();
1821 
1822  // do not process the control points in random order,
1823  // but walk from image to image, to reduce image reloading
1824  // in low mem situations.
1825  for (unsigned int imgNr = 0 ; imgNr < pano.getNrOfImages(); imgNr++) {
1826  std::set<unsigned int>::iterator it=unoptimized.begin();
1827 
1828  imgCache.softFlush();
1829 
1830  while (it != unoptimized.end()) {
1831  if (cps[*it].image1Nr == imgNr || cps[*it].image2Nr == imgNr) {
1832  if (!progress.updateDisplayValue())
1833  {
1834  return;
1835  };
1836  if (cps[*it].mode == HuginBase::ControlPoint::X_Y) {
1837  // finetune only normal points
1838  DEBUG_DEBUG("fine tuning point: " << *it);
1839  wxImage wxSearchImg;
1840  ImageCache::ImageCacheRGB8Ptr searchImg = imgCache.getImage(
1841  pano.getImage(cps[*it].image2Nr).getFilename())->get8BitImage();
1842 
1843  ImageCache::ImageCacheRGB8Ptr templImg = imgCache.getImage(
1844  pano.getImage(cps[*it].image1Nr).getFilename())->get8BitImage();
1845 
1847  vigra::Diff2D roundP1(hugin_utils::roundi(cps[*it].x1), hugin_utils::roundi(cps[*it].y1));
1848  vigra::Diff2D roundP2(hugin_utils::roundi(cps[*it].x2), hugin_utils::roundi(cps[*it].y2));
1849 
1850  res = PointFineTuneProjectionAware(pano.getImage(cps[*it].image1Nr), *templImg, roundP1, templWidth,
1851  pano.getImage(cps[*it].image2Nr), *searchImg, roundP2, sWidth);
1852 
1853  // invert curvature. we always assume its a maxima, the curvature there is negative
1854  // however, we allow the user to specify a positive threshold, so we need to
1855  // invert it
1856  res.curv.x = - res.curv.x;
1857  res.curv.y = - res.curv.y;
1858 
1859  if (res.maxi < corrThresh || res.curv.x < curvThresh || res.curv.y < curvThresh ||
1860  res.maxpos.x < 0 || res.maxpos.y < 0 || res.corrPos.x < 0 || res.corrPos.y < 0)
1861  {
1862  // Bad correlation result.
1863  nBad++;
1864  if (res.maxi >= corrThresh) {
1865  cps[*it].error = 0;
1866  }
1867  cps[*it].error = res.maxi;
1868  DEBUG_DEBUG("low correlation: " << res.maxi << " curv: " << res.curv);
1869  } else {
1870  nGood++;
1871  // only update if a good correlation was found
1872  cps[*it].x1 = res.corrPos.x;
1873  cps[*it].y1 = res.corrPos.y;
1874  cps[*it].x2 = res.maxpos.x;
1875  cps[*it].y2 = res.maxpos.y;
1876  cps[*it].error = res.maxi;
1877  }
1878  }
1879  else
1880  {
1881  // for line control points set error = correlation to 1
1882  cps[*it].error = 1.0;
1883  };
1884  unsigned int rm = *it;
1885  ++it;
1886  unoptimized.erase(rm);
1887  } else {
1888  ++it;
1889  }
1890  }
1891  }
1892  }
1893  m_showCorrelation = 1;
1894  wxString result;
1895  result.Printf(_("%d points fine-tuned, %d points not updated due to low correlation\n\nHint: The errors of the fine-tuned points have been set to the correlation coefficient\nProblematic points can be spotted (just after fine-tune, before optimizing)\nby an error <= %.3f.\nThe error of points without a well defined peak (typically in regions with uniform color)\nwill be set to 0\n\nUse the Control Point list (F3) to see all points of the current project\n"),
1896  nGood, nBad, corrThresh);
1897  hugin_utils::HuginMessageBox(result, _("Hugin"), wxOK, this);
1898  // set newly optimized points
1900  new PanoCommand::UpdateCPsCmd(pano, cps, false)
1901  );
1902 }
1903 
1904 void MainFrame::OnRemoveCPinMasks(wxCommandEvent & e)
1905 {
1906  if(pano.getCtrlPoints().size()<2)
1907  return;
1909  if(!cps.empty())
1910  {
1913  );
1914  hugin_utils::HuginMessageBox(wxString::Format(_("Removed %lu control points"), static_cast<unsigned long>(cps.size())),
1915  _("Hugin"), wxOK | wxICON_INFORMATION, this);
1916  };
1917 }
1918 
1919 #ifdef HUGIN_HSI
1920 void MainFrame::OnPythonScript(wxCommandEvent & e)
1921 {
1922  wxString fname;
1923  wxFileDialog dlg(wxGetActiveWindow(),
1924  _("Select python script"),
1925  wxConfigBase::Get()->Read("/lensPath",wxEmptyString), wxEmptyString,
1926  _("Python script (*.py)|*.py|All files (*.*)|*.*"),
1927  wxFD_OPEN, wxDefaultPosition);
1928  dlg.SetDirectory(wxConfigBase::Get()->Read("/pythonScriptPath",wxEmptyString));
1929 
1930  if (dlg.ShowModal() == wxID_OK)
1931  {
1932  wxString filename = dlg.GetPath();
1933  wxConfig::Get()->Write("/pythonScriptPath", dlg.GetDirectory());
1934  std::string scriptfile((const char *)filename.mb_str(HUGIN_CONV_FILENAME));
1936  new PanoCommand::PythonScriptPanoCmd(pano,scriptfile)
1937  );
1938  }
1939 }
1940 
1941 void MainFrame::OnPlugin(wxCommandEvent & e)
1942 {
1943  wxFileName file=m_plugins[e.GetId()];
1944  if(file.FileExists())
1945  {
1946  std::string scriptfile((const char *)file.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
1948  new PanoCommand::PythonScriptPanoCmd(pano,scriptfile)
1949  );
1950  }
1951  else
1952  {
1953  hugin_utils::HuginMessageBox(wxString::Format("Python-Script %s not found.\nStopping processing.", file.GetFullPath()), _("Hugin"), wxOK | wxICON_INFORMATION, wxGetActiveWindow());
1954  };
1955 }
1956 
1957 #endif
1958 
1959 void MainFrame::OnUndo(wxCommandEvent & e)
1960 {
1961  DEBUG_TRACE("OnUndo");
1963  {
1965  }
1966  else
1967  {
1968  wxBell();
1969  };
1970 }
1971 
1972 void MainFrame::OnRedo(wxCommandEvent & e)
1973 {
1974  DEBUG_TRACE("OnRedo");
1976  {
1978  };
1979 }
1980 
1981 void MainFrame::ShowCtrlPoint(unsigned int cpNr)
1982 {
1983  DEBUG_DEBUG("Showing control point " << cpNr);
1984  m_notebook->SetSelection(2);
1985  cpe->ShowControlPoint(cpNr);
1986 }
1987 
1988 void MainFrame::ShowCtrlPointEditor(unsigned int img1, unsigned int img2)
1989 {
1990  if(!IsShown())
1991  {
1992  Show();
1993  Raise();
1994  };
1995  m_notebook->SetSelection(2);
1996  cpe->setLeftImage(img1);
1997  cpe->setRightImage(img2);
1998 }
1999 
2000 void MainFrame::ShowMaskEditor(size_t imgNr, bool switchToCropMode)
2001 {
2002  if(!IsShown())
2003  {
2004  Show();
2005  Raise();
2006  };
2007  m_notebook->SetSelection(1);
2008  mask_panel->setImage(imgNr, true);
2009  if (switchToCropMode)
2010  {
2012  };
2013 };
2014 
2016 {
2019  {
2020  m_notebook->SetSelection(5);
2021  }
2022  else
2023  {
2025  {
2026  m_notebook->SetSelection(4);
2027  }
2028  else
2029  {
2030  m_notebook->SetSelection(3);
2031  };
2032  };
2033 }
2034 
2037 {
2038  wxString msg;
2039  if (!m_message.empty())
2040  {
2041  msg = wxGetTranslation(wxString(m_message.c_str(), wxConvLocal));
2042  if (!m_filename.empty())
2043  {
2044  msg.Append(" ");
2045  msg.Append(wxString(ProgressDisplay::m_filename.c_str(), HUGIN_CONV_FILENAME));
2046  };
2047  };
2048  GetStatusBar()->SetStatusText(msg, 0);
2049 
2050 #ifdef __WXMSW__
2051  UpdateWindow(NULL);
2052 #endif
2053 }
2054 
2055 void MainFrame::enableTools(bool option)
2056 {
2057  wxToolBar* theToolBar = GetToolBar();
2058  theToolBar->EnableTool(XRCID("action_optimize"), option);
2059  theToolBar->EnableTool(XRCID("ID_SHOW_PREVIEW_FRAME"), option);
2060  //theToolBar->EnableTool(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), option);
2061  wxMenuBar* theMenuBar = GetMenuBar();
2062  theMenuBar->Enable(XRCID("action_optimize"), option);
2063  theMenuBar->Enable(XRCID("action_finetune_all_cp"), option);
2064  theMenuBar->Enable(XRCID("action_remove_cp_in_masks"), option);
2065  theMenuBar->Enable(XRCID("ID_SHOW_PREVIEW_FRAME"), option);
2066  theMenuBar->Enable(XRCID("action_stitch"), option);
2067  theMenuBar->Enable(XRCID("action_stitch_userdefined"), option);
2068  if (m_outputUserMenu != nullptr)
2069  {
2070  m_outputUserMenu->Enable(option);
2071  };
2072  if (m_assistantUserMenu != nullptr)
2073  {
2074  m_assistantUserMenu->Enable(option);
2075  };
2076  theMenuBar->Enable(XRCID("action_assistant"), option);
2077  theMenuBar->Enable(XRCID("action_batch_assistant"), option);
2078  m_menu_file_advanced->Enable(XRCID("action_import_papywizard"), option);
2079  //theMenuBar->Enable(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), option);
2080 }
2081 
2082 
2083 void MainFrame::OnSize(wxSizeEvent &e)
2084 {
2085 #ifdef DEBUG
2086  wxSize sz = this->GetSize();
2087  wxSize csz = this->GetClientSize();
2088  wxSize vsz = this->GetVirtualSize();
2089  DEBUG_TRACE(" size:" << sz.x << "," << sz.y <<
2090  " client: "<< csz.x << "," << csz.y <<
2091  " virtual: "<< vsz.x << "," << vsz.y);
2092 #endif
2093 
2094  Layout();
2095  e.Skip();
2096 }
2097 
2099 {
2100  return images_panel->GetDefaultSetting();
2101 };
2102 
2104 {
2105  images_panel->RunCPGenerator(setting, img);
2106 };
2107 
2109 {
2111 };
2112 
2114 {
2116 };
2117 
2118 const wxString & MainFrame::GetXRCPath()
2119 {
2120  return huginApp::Get()->GetXRCPath();
2121 };
2122 
2123 const wxString & MainFrame::GetDataPath()
2124 {
2125  return wxGetApp().GetDataPath();
2126 };
2127 
2130 {
2131  if (m_this) {
2132  return m_this;
2133  } else {
2134  DEBUG_FATAL("MainFrame not yet created");
2136  return 0;
2137  }
2138 }
2139 
2141 {
2142  return m_filename;
2143 }
2144 
2146 {
2147  return m_showCorrelation > 0;
2148 }
2149 
2150 void MainFrame::OnMRUFiles(wxCommandEvent &e)
2151 {
2152  size_t index = e.GetId() - wxID_FILE1;
2153  wxString f(m_mruFiles.GetHistoryFile(index));
2154  if (!f.empty())
2155  {
2156  wxFileName fn(f);
2157  if (fn.FileExists())
2158  {
2159  // if closing old project was canceled do nothing
2160  if (CloseProject(true, LOAD_NEW_PROJECT))
2161  {
2162  // remove old images from cache
2163  ImageCache::getInstance().flush();
2164  // finally load project
2165  LoadProjectFile(f);
2166  };
2167  }
2168  else
2169  {
2170  m_mruFiles.RemoveFileFromHistory(index);
2171  hugin_utils::HuginMessageBox(wxString::Format(_("File \"%s\" not found.\nMaybe file was renamed, moved or deleted."),f.c_str()),
2172  _("Hugin"), wxOK | wxICON_INFORMATION, wxGetActiveWindow());
2173  };
2174  };
2175 }
2176 
2177 void MainFrame::OnFullScreen(wxCommandEvent & e)
2178 {
2179  ShowFullScreen(!IsFullScreen(), wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION);
2180 #ifdef __WXGTK__
2181  //workaround a wxGTK bug that also the toolbar is hidden, but not requested to hide
2182  GetToolBar()->Show(true);
2183 #endif
2184 };
2185 
2187 {
2188  if(svmModel==NULL)
2189  {
2190  // determine file name of SVM model file
2191  // get XRC path from application
2192  wxString wxstrModelFileName = huginApp::Get()->GetDataPath() + HUGIN_CELESTE_MODEL;
2193  // convert wxString to string
2194  std::string strModelFileName(wxstrModelFileName.mb_str(HUGIN_CONV_FILENAME));
2195 
2196  // SVM model file
2197  if (! wxFile::Exists(wxstrModelFileName) ) {
2198  hugin_utils::HuginMessageBox(wxString::Format(_("Celeste model expected in %s not found, Hugin needs to be properly installed."), wxstrModelFileName), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
2199  return NULL;
2200  }
2201  if(!celeste::loadSVMmodel(svmModel,strModelFileName))
2202  {
2203  hugin_utils::HuginMessageBox(wxString::Format(_("Could not load Celeste model file %s"), wxstrModelFileName), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
2204  svmModel=NULL;
2205  };
2206  }
2207  return svmModel;
2208 };
2209 
2211 {
2212  return gl_preview_frame;
2213 }
2214 
2216 {
2217  if(gl_preview_frame==NULL && newLevel==GUI_SIMPLE)
2218  {
2220  return;
2221  };
2222  if(m_guiLevel==GUI_EXPERT && newLevel!=GUI_EXPERT && pano.getOptimizerSwitch()==0)
2223  {
2224  bool needsUpdateOptimizerVar=false;
2226  for(size_t i=0; i<optVec.size(); i++)
2227  {
2228  bool hasTrX=optVec[i].erase("TrX")>0;
2229  bool hasTrY=optVec[i].erase("TrY")>0;
2230  bool hasTrZ=optVec[i].erase("TrZ")>0;
2231  bool hasTpy=optVec[i].erase("Tpy")>0;
2232  bool hasTpp=optVec[i].erase("Tpp")>0;
2233  bool hasg=optVec[i].erase("g")>0;
2234  bool hast=optVec[i].erase("t")>0;
2235  needsUpdateOptimizerVar=needsUpdateOptimizerVar || hasTrX || hasTrY || hasTrZ || hasTpy || hasTpp || hasg || hast;
2236  };
2237  if(needsUpdateOptimizerVar)
2238  {
2241  );
2242  };
2243  };
2244  if(newLevel==GUI_SIMPLE && pano.getPhotometricOptimizerSwitch()==0)
2245  {
2246  bool needsUpdateOptimizerVar=false;
2248  for(size_t i=0; i<optVec.size(); i++)
2249  {
2250  bool hasVx=optVec[i].erase("Vx")>0;
2251  bool hasVy=optVec[i].erase("Vy")>0;
2252  needsUpdateOptimizerVar=needsUpdateOptimizerVar || hasVx || hasVy;
2253  };
2254  if(needsUpdateOptimizerVar)
2255  {
2258  );
2259  };
2260  };
2261  m_guiLevel=newLevel;
2266  if(gl_preview_frame)
2267  {
2269  };
2270  switch(m_guiLevel)
2271  {
2272  case GUI_SIMPLE:
2273  GetMenuBar()->FindItem(XRCID("action_gui_simple"))->Check();
2274  break;
2275  case GUI_ADVANCED:
2276  GetMenuBar()->FindItem(XRCID("action_gui_advanced"))->Check();
2277  break;
2278  case GUI_EXPERT:
2279  GetMenuBar()->FindItem(XRCID("action_gui_expert"))->Check();
2280  break;
2281  };
2282  if(m_guiLevel==GUI_SIMPLE)
2283  {
2284  if(!gl_preview_frame->IsShown())
2285  {
2286  wxCommandEvent dummy;
2287  OnToggleGLPreviewFrame(dummy);
2288  };
2289  wxGetApp().SetTopWindow(gl_preview_frame);
2290  GetMenuBar()->Remove(0);
2291  GetMenuBar()->Insert(0, m_menu_file_simple, _("&File"));
2292  if(m_filename.IsEmpty())
2293  {
2294  gl_preview_frame->SetTitle(_("Hugin - Panorama Stitcher"));
2295  SetTitle(_("Panorama editor"));
2296  }
2297  else
2298  {
2299  wxFileName scriptName = m_filename;
2300  gl_preview_frame->SetTitle(scriptName.GetName() + "." + scriptName.GetExt() + " - " + _("Hugin - Panorama Stitcher"));
2301  SetTitle(scriptName.GetName() + "." + scriptName.GetExt() + " - " + _("Panorama editor"));
2302  };
2303  Hide();
2304  }
2305  else
2306  {
2307  wxGetApp().SetTopWindow(this);
2308  GetMenuBar()->Remove(0);
2309  GetMenuBar()->Insert(0, m_menu_file_advanced, _("&File"));
2310  if(m_filename.IsEmpty())
2311  {
2312  SetTitle(_("Hugin - Panorama Stitcher"));
2313  }
2314  else
2315  {
2316  wxFileName scriptName = m_filename;
2317  SetTitle(scriptName.GetName() + "." + scriptName.GetExt() + " - " + _("Hugin - Panorama Stitcher"));
2318  };
2319  if(!IsShown())
2320  {
2321  Show();
2322  };
2323  };
2324 };
2325 
2326 void MainFrame::OnSetGuiSimple(wxCommandEvent & e)
2327 {
2328  GuiLevel reqGuiLevel=GetMinimumGuiLevel(pano);
2329  if(reqGuiLevel<=GUI_SIMPLE)
2330  {
2332  }
2333  else
2334  {
2335  if(reqGuiLevel==GUI_ADVANCED)
2336  {
2337  hugin_utils::HuginMessageBox(_("Can't switch to simple interface. The project is using stacks and/or vignetting center shift.\nThese features are not supported in simple interface."),
2338  _("Hugin"), wxOK | wxICON_INFORMATION, wxGetActiveWindow());
2339  }
2340  else
2341  {
2342  hugin_utils::HuginMessageBox(_("Can't switch to simple interface. The project is using translation or shear parameters.\nThese parameters are not supported in simple interface."),
2343  _("Hugin"), wxOK | wxICON_INFORMATION, wxGetActiveWindow());
2344  }
2346  };
2347 };
2348 
2349 void MainFrame::OnSetGuiAdvanced(wxCommandEvent & e)
2350 {
2351  GuiLevel reqGuiLevel=GetMinimumGuiLevel(pano);
2352  if(reqGuiLevel<=GUI_ADVANCED)
2353  {
2355  }
2356  else
2357  {
2358  hugin_utils::HuginMessageBox(_("Can't switch to advanced interface. The project is using translation or shear parameters.\nThese parameters are not supported in advanced interface."),
2359  _("Hugin"), wxOK | wxICON_INFORMATION, wxGetActiveWindow());
2361  };
2362 };
2363 
2364 void MainFrame::OnSetGuiExpert(wxCommandEvent & e)
2365 {
2367 };
2368 
2370 {
2371  GetMenuBar()->Enable(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), false);
2372  GetMenuBar()->Enable(XRCID("action_gui_simple"), false);
2373  GetToolBar()->EnableTool(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), false);
2374 };
2375 
2376 void MainFrame::RunAssistant(wxWindow* mainWin, const wxString& userdefinedAssistant)
2377 {
2378  //save project into temp directory
2379  wxString tempDir= wxConfig::Get()->Read("tempDir",wxEmptyString);
2380  if(!tempDir.IsEmpty())
2381  {
2382  if(tempDir.Last()!=wxFileName::GetPathSeparator())
2383  {
2384  tempDir.Append(wxFileName::GetPathSeparator());
2385  }
2386  };
2387  wxFileName scriptFileName(wxFileName::CreateTempFileName(tempDir+"ha"));
2388  const std::string script(scriptFileName.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
2389  pano.WritePTOFile(script, hugin_utils::getPathPrefix(script));
2390 
2391  // get assistant queue
2392  const wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
2393  wxArrayString tempfiles;
2394  HuginQueue::CommandQueue* commands;
2395  if (userdefinedAssistant.IsEmpty())
2396  {
2397  commands = HuginQueue::GetAssistantCommandQueue(pano, exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR), scriptFileName.GetFullPath());
2398  }
2399  else
2400  {
2401  std::stringstream errors;
2402  commands = HuginQueue::GetAssistantCommandQueueUserDefined(pano, exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR), scriptFileName.GetFullPath(), userdefinedAssistant, tempfiles, errors);
2403  if (commands->empty())
2404  {
2405  hugin_utils::HuginMessageBox(_("The assistant queue is empty. This indicates an error in the user defined assistant file.") + "\n\n" + wxString(errors.str()),
2406  _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
2407  //delete temporary files
2408  wxRemoveFile(scriptFileName.GetFullPath());
2409  return;
2410  };
2411  };
2412  //execute queue
2413  int ret = MyExecuteCommandQueue(commands, mainWin, _("Running assistant"));
2414 
2415  //read back panofile
2417  (const char *)scriptFileName.GetFullPath().mb_str(HUGIN_CONV_FILENAME), "",
2418  ret==0, false));
2419 
2420  //delete temporary files
2421  wxRemoveFile(scriptFileName.GetFullPath());
2422  if (!tempfiles.IsEmpty())
2423  {
2424  for (auto& f : tempfiles)
2425  {
2426  wxRemoveFile(f);
2427  };
2428  };
2429  // check that GUI level is still approbiate
2430  const GuiLevel reqGuiLevel = GetMinimumGuiLevel(pano);
2431  if (reqGuiLevel > m_guiLevel)
2432  {
2433  // output of assistant requires higher GUI level
2434  SetGuiLevel(reqGuiLevel);
2435  };
2436  //if return value is non-zero, an error occurred in the assistant
2437  if(ret!=0)
2438  {
2439  if (userdefinedAssistant.IsEmpty())
2440  {
2441  if (pano.getNrOfImages() == 1)
2442  {
2443  hugin_utils::HuginMessageBox(_("The assistant could not find vertical lines. Please add vertical lines in the panorama editor and optimize project manually."),
2444  _("Hugin"), wxOK | wxICON_INFORMATION, wxGetActiveWindow());
2445  }
2446  else
2447  {
2448  //check for unconnected images
2450  const HuginGraph::ImageGraph::Components comps = graph.GetComponents();
2451  if (comps.size() > 1)
2452  {
2453  // switch to images panel.
2454  unsigned i1 = *(comps[0].rbegin());
2455  unsigned i2 = *(comps[1].begin());
2456  ShowCtrlPointEditor(i1, i2);
2457  // display message box with
2458  hugin_utils::HuginMessageBox(wxString::Format(_("Warning %d unconnected image groups found:"), static_cast<int>(comps.size())) + Components2Str(comps) + "\n"
2459  + _("Please create control points between unconnected images using the Control Points tab in the panorama editor.\n\nAfter adding the points, press the \"Align\" button again"), _("Error"), wxOK, mainWin);
2460  return;
2461  };
2462  hugin_utils::HuginMessageBox(_("The assistant did not complete successfully. Please check the resulting project file."),
2463  _("Hugin"), wxOK | wxICON_INFORMATION, wxGetActiveWindow());
2464  };
2465  }
2466  else
2467  {
2468  hugin_utils::HuginMessageBox(_("The assistant did not complete successfully. Please check the resulting project file."),
2469  _("Hugin"), wxOK | wxICON_INFORMATION, wxGetActiveWindow());
2470  };
2471  };
2472 };
2473 
2474 void MainFrame::OnRunAssistant(wxCommandEvent & e)
2475 {
2476  RunAssistant(this);
2477 };
2478 
2480 {
2481  const auto filename = m_userAssistant.find(e.GetId());
2482  if (filename != m_userAssistant.end())
2483  {
2484  RunAssistant(this, filename->second);
2485  }
2486  else
2487  {
2488  wxBell();
2489  };
2490 };
2491 
2492 void MainFrame::OnSendToAssistantQueue(wxCommandEvent &e)
2493 {
2494  wxCommandEvent dummy;
2495  OnSaveProject(dummy);
2496  wxString projectFile = getProjectName();
2497  if(wxFileName::FileExists(projectFile))
2498  {
2499 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
2500  // Original patch for OSX by Charlie Reiman dd. 18 June 2011
2501  // Slightly modified by HvdW. Errors in here are mine, not Charlie's.
2502  FSRef appRef;
2503  FSRef actuallyLaunched;
2504  OSStatus err;
2505  FSRef documentArray[1]; // Don't really need an array if we only have 1 item
2506  LSLaunchFSRefSpec launchSpec;
2507  Boolean isDir;
2508 
2509  err = LSFindApplicationForInfo(kLSUnknownCreator,
2510  CFSTR("net.sourceforge.hugin.PTBatcherGUI"),
2511  NULL,
2512  &appRef,
2513  NULL);
2514  if (err != noErr)
2515  {
2516  // error, can't find PTBatcherGUI
2517  hugin_utils::HuginMessageBox(wxString::Format(_("External program %s not found in the bundle, reverting to system path"), "open"), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
2518  // Possibly a silly attempt otherwise the previous would have worked as well, but just try it.
2519  wxExecute(_T("open -b net.sourceforge.hugin.PTBatcherGUI ")+hugin_utils::wxQuoteFilename(projectFile));
2520  return;
2521  }
2522 
2523  wxCharBuffer projectFilebuffer=projectFile.ToUTF8();
2524  // Point to document
2525  err = FSPathMakeRef((unsigned char*) projectFilebuffer.data(), &documentArray[0], &isDir);
2526  if (err != noErr || isDir)
2527  {
2528  // Something went wrong.
2529  hugin_utils::HuginMessageBox(wxString::Format(_("Project file not found"), "open"), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
2530  return;
2531  }
2532  launchSpec.appRef = &appRef;
2533  launchSpec.numDocs = sizeof(documentArray)/sizeof(documentArray[0]);
2534  launchSpec.itemRefs = documentArray;
2535  launchSpec.passThruParams = NULL;
2536  launchSpec.launchFlags = kLSLaunchDontAddToRecents + kLSLaunchDontSwitch;
2537  launchSpec.asyncRefCon = NULL;
2538 
2539  err = LSOpenFromRefSpec(&launchSpec, &actuallyLaunched);
2540  if (err != noErr && err != kLSLaunchInProgressErr)
2541  {
2542  // Should be ok if it's in progress... I think.
2543  // Launch failed.
2544  hugin_utils::HuginMessageBox(wxString::Format(_("Can't launch PTBatcherGui"), "open"), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
2545  return;
2546  }
2547 
2548  // Should verify that actuallyLaunched and appRef are the same.
2549  if (FSCompareFSRefs(&appRef, &actuallyLaunched) != noErr)
2550  {
2551  // error, lauched the wrong thing.
2552  hugin_utils::HuginMessageBox(wxString::Format(_("Launched incorrect programme"), "open"), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
2553  return;
2554  }
2555 #else
2556  const wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
2557  wxExecute(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + "PTBatcherGUI -a "+hugin_utils::wxQuoteFilename(projectFile));
2558 #endif
2559  }
2560 };
2561 
2563 {
2565 };
2566 
void DisplayHelp(wxString section=wxEmptyString)
call help browser with given file
Definition: MainFrame.cpp:1459
wxDEFINE_EVENT(EVT_QUEUE_PROGRESS, wxCommandEvent)
#define DEBUG_INFO(msg)
Definition: utils.h:69
void OnShowCPFrame(wxCommandEvent &e)
Definition: MainFrame.cpp:1569
OptimizePanel * opt_panel
Definition: MainFrame.h:254
int MyExecuteCommandQueue(HuginQueue::CommandQueue *queue, wxWindow *parent, const wxString &title, const wxString &comment)
execute all commands in queue with redirection of output to frame and allow canceling the queue will ...
Base class for all panorama commands.
Definition: Command.h:38
bool ImportPapywizardFile(const wxString &filename, HuginBase::Panorama &pano)
import the settings from given filename into pano
PanoPanel * pano_panel
Definition: MainFrame.h:258
void destroySVMmodel(struct svm_model *&model)
frees the resource of model
Definition: Celeste.cpp:60
const bool GetOptimizeOnlyActiveImages() const
Definition: MainFrame.cpp:1615
int m_showCorrelation
Definition: MainFrame.h:279
#define HUGIN_SHOW_PROJECTION_HINTS
void OnUpdate(wxCommandEvent &event)
std::list< PluginItem > PluginItems
Definition: PluginItems.h:61
implementation of huginApp Class
void updateProgressDisplay()
receive notification about progress.
Definition: MainFrame.cpp:2036
std::map< int, wxString > m_userOutput
Definition: MainFrame.h:299
bool FileExists(const std::string &filename)
checks if file exists
Definition: utils.cpp:362
bool AskUserOverwrite(const wxString &filename, const wxString &caption, wxWindow *parent)
ask user if the given file should be overwritten, return true if the user confirmed the overwritting ...
Definition: wxutils.cpp:233
void SetGuiLevel(GuiLevel newLevel)
Definition: MainFrame.cpp:2215
void OnRemoveCPinMasks(wxCommandEvent &e)
Definition: MainFrame.cpp:1904
const wxString & GetDataPath()
return the current data path
Definition: huginApp.h:104
void OnUserQuit(wxCommandEvent &e)
Definition: MainFrame.cpp:859
void OnRunAssistant(wxCommandEvent &e)
Definition: MainFrame.cpp:2474
hugin preferences dialog
void OnApplyTemplate(wxCommandEvent &e)
Definition: MainFrame.cpp:1736
The OpenGL preview frame.
void setMemento(const PanoramaMemento &memento)
set the internal state
Definition: Panorama.cpp:1507
virtual PanoCommand::PanoCommand * GetCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images, GuiLevel guiLevel)
returns the appropriate PanoCommand::PanoCommand to be inserted into GlobalCmdHistory, checks if operation is enabled
void AddImages(wxArrayString &filenameArray)
adds the given files to the projects, with checking for invalid filenames
Definition: MainFrame.cpp:1284
void SetGuiLevel(GuiLevel newGuiLevel)
void ShowStitcherTab()
opens the stitcher tab
Definition: MainFrame.cpp:2015
const bool GetOptimizeIgnoreLineCp() const
Definition: MainFrame.cpp:1640
int roundi(T x)
Definition: hugin_math.h:73
void StorePositionAndSize()
store position and size of window in wxConfig
start a new project, reset options to values in preferences
Definition: wxPanoCommand.h:85
read settings from papywizard xml file
#define HUGIN_FT_LOCAL_SEARCH_WIDTH
vigra_ext::CorrelationResult PointFineTuneProjectionAware(const HuginBase::SrcPanoImage &templ, const vigra::UInt8RGBImage &templImg, vigra::Diff2D templPos, int templSize, const HuginBase::SrcPanoImage &search, const vigra::UInt8RGBImage &searchImg, vigra::Diff2D searchPos, int sWidth)
function for fine-tune with remapping to stereographic projection
void OnToggleGLPreviewFrame(wxCommandEvent &e)
Definition: MainFrame.cpp:1543
void AddUserDefinedAssistant(int id, const wxString &desc, const wxString &help)
adds the given user defined assistant to SplitButton menu
void OnRedo(wxCommandEvent &e)
Definition: MainFrame.cpp:1972
GLPreviewFrame * gl_preview_frame
Definition: MainFrame.h:263
ImagesPanel * images_panel
Definition: MainFrame.h:251
bool m_show_opt_photo_panel
Definition: MainFrame.h:257
void OnUndo(wxCommandEvent &e)
Definition: MainFrame.cpp:1959
center panorama horizontically
Definition: PanoCommand.h:250
wxMenuItem * m_assistantUserMenu
Definition: MainFrame.h:287
struct celeste::svm_model * svmModel
Definition: MainFrame.h:259
control point editor panel.
Definition: CPEditorPanel.h:64
OptimizePhotometricPanel * opt_photo_panel
Definition: MainFrame.h:256
bool removeObserver(PanoramaObserver *observer)
remove a panorama observer.
Definition: Panorama.cpp:1551
#define HUGIN_CONV_FILENAME
Definition: platform.h:40
GuiLevel GetMinimumGuiLevel(HuginBase::PanoramaData &pano)
returns the requiered GuiLevel for the given panorama to work correctly
Definition: GuiLevel.cpp:29
std::unique_ptr< wxMessageDialogBase > MessageDialog
Definition: wxutils.h:87
hugin_utils::FDiff2D corrPos
Definition: Correlation.h:66
#define DEBUG_TRACE(msg)
Definition: utils.h:67
const wxString GetSelectedCPGenerator()
return the currently selected cp generator description
Definition: MainFrame.cpp:2113
void RunAssistant(wxWindow *mainWin, const wxString &userdefinedAssistant=wxEmptyString)
Definition: MainFrame.cpp:2376
#define HUGIN_FT_CURV_THRESHOLD
void registerPTWXDlgFcn()
Definition: PTWXDlg.cpp:178
void OnUserDefinedStitch(wxCommandEvent &e)
Definition: MainFrame.cpp:1658
void OnSavePTStitcherAs(wxCommandEvent &e)
Definition: MainFrame.cpp:1040
void OnExit(wxCloseEvent &e)
Definition: MainFrame.cpp:920
void RunCPGenerator(CPDetectorSetting &setting, const HuginBase::UIntSet &img)
run the cp generator with the given setting on selected images
const wxString GetDescription() const
return description
Reading python plugins metadata.
CPEditorPanel * cpe
Definition: MainFrame.h:253
void OnTipOfDay(wxCommandEvent &e)
Definition: MainFrame.cpp:1471
void deregisterPTWXDlgFcn()
Definition: PTWXDlg.cpp:185
void OnMergeProject(wxCommandEvent &e)
Definition: MainFrame.cpp:1676
This is a cache for all the images we use.
Definition: ImageCache.h:52
void SetOptimizeOnlyActiveImages(const bool onlyActive)
sets the status of the &quot;optimize only active images&quot; menu item
Definition: MainFrame.cpp:1601
#define DEBUG_ASSERT(cond)
Definition: utils.h:80
void OnPhotometricOptimize(wxCommandEvent &e)
Definition: MainFrame.cpp:1645
HuginBase::ImageCache::ImageCacheRGB8Ptr ImageCacheRGB8Ptr
Definition: wxImageCache.h:33
simple class that forward the drop to the mainframe
Definition: MainFrame.h:61
include file for the hugin project
A tip file provider that uses gettext to translate the tips.
wxHelpController & GetHelpController()
Definition: MainFrame.h:183
virtual void clearDirty()
clear dirty flag.
Definition: Panorama.h:645
void OnSendToAssistantQueue(wxCommandEvent &e)
Definition: MainFrame.cpp:2492
mask editor panel.
void setImage(unsigned int imgNr, bool updateListSelection=false)
sets the image, which is currently edited
void setLeftImage(unsigned int imgNr)
set left image
void InitPreviews()
init previews
const CPVector & getCtrlPoints() const
get all control point of this Panorama
Definition: Panorama.h:319
void GeneratePanoOperationVector()
generates the PanoOperationVector for context menu
void OnLoadingFailed(wxCommandEvent &e)
event handler called when loading of image file failed
Definition: MainFrame.cpp:1373
static MainFrame * m_this
Definition: MainFrame.h:282
wxMenuItem * m_outputUserMenu
Definition: MainFrame.h:286
remove several control points
Definition: PanoCommand.h:307
void DoUserDefinedStitch(const wxString &settings=wxString())
stitching with user defined file
Definition: PanoPanel.cpp:1331
void ShowControlPoint(unsigned int cpNr)
show a control point
Definition of PanoOperation class.
std::vector< HuginBase::UIntSet > Components
stores the components of the graph
Definition: ImageGraph.h:50
MessageDialog GetMessageDialog(const wxString &message, const wxString &caption, int style, wxWindow *parent)
Definition: wxutils.cpp:212
void SetGuiLevel(GuiLevel newGuiLevel)
Definition: PanoPanel.cpp:1657
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:523
static huginApp * Get()
hack.. kind of a pseudo singleton...
Definition: huginApp.cpp:651
wxNotebook * m_notebook
Definition: MainFrame.h:249
void OnUserDefinedStitchSaved(wxCommandEvent &e)
Definition: MainFrame.cpp:1663
Dialog for raw import.
Definition: RawImport.h:34
PanoCommand to combine other PanoCommands.
Definition: PanoCommand.h:39
#define DEBUG_FATAL(msg)
Definition: utils.h:78
void Init(HuginBase::Panorama *pano)
WXIMPEX void FixHelpSettings()
helper function to check window position settings of help window
Definition: wxPlatform.cpp:53
apply a template to a panorama object
Definition: wxPanoCommand.h:96
Hugin&#39;s first panel.
Definition: ImagesPanel.h:40
std::set< unsigned int > UIntSet
Definition: PanoramaData.h:51
void OnSetGuiAdvanced(wxCommandEvent &e)
Definition: MainFrame.cpp:2349
void Init(HuginBase::Panorama *pano)
Definition: PanoPanel.cpp:250
bool m_show_opt_panel
Definition: MainFrame.h:255
The main window frame.
Definition: MainFrame.h:83
CommandQueue * GetAssistantCommandQueue(const HuginBase::Panorama &pano, const wxString &ExePath, const wxString &project)
generates the command queue for running the assistant
algorithms for remove control points by statistic method
void ShowCtrlPoint(unsigned int cpNr)
Definition: MainFrame.cpp:1981
void LoadOpenGLLayout()
loads the layout of the OpenGL windows and restores it
wxString m_filename
Definition: MainFrame.h:277
updates the optimize vector, aka all variables which should be optimized
Definition: PanoCommand.h:201
Model for a panorama.
Definition: Panorama.h:152
bool m_optIgnoreLineCp
Definition: MainFrame.h:290
bool loadSVMmodel(struct svm_model *&model, std::string &model_file)
loads the SVM model from file
Definition: Celeste.cpp:45
wxMenu * m_menu_file_simple
Definition: MainFrame.h:284
void LoadProjectFile(const wxString &filename)
Definition: MainFrame.cpp:1069
#define HUGIN_IMGCACHE_UPPERBOUND
const wxFileName GetFilename() const
returns filename
std::string getPathPrefix(const std::string &filename)
Get the path to a filename.
Definition: utils.cpp:184
HuginBase::Panorama & pano
Definition: MainFrame.h:274
void OnFineTuneAll(wxCommandEvent &e)
Definition: MainFrame.cpp:1791
Definition of dialog and functions to import RAW images to project file.
const wxString & GetDataPath()
get the path to data directory
Definition: MainFrame.cpp:2123
const OptimizeVector & getOptimizeVector() const
return the optimize settings stored inside panorama
Definition: Panorama.h:454
bool loadPTScript(std::istream &i, int &ptoVersion, const std::string &prefix="")
load a Hugin file
#define HUGIN_FT_TEMPLATE_SIZE
wxFileHistory m_mruFiles
Definition: MainFrame.h:248
class, which stores all settings of one cp detector
void OnKeyboardHelp(wxCommandEvent &e)
Definition: MainFrame.cpp:1448
PanoCommand::PanoCommand * GetPanoCommand()
return PanoCommand for adding converted raw files to Panorama
Definition: RawImport.cpp:625
bool comparePluginItem(PluginItem item1, PluginItem item2)
compares 2 plugin with category and name
Definition: PluginItems.cpp:39
std::size_t getNrOfImages() const
number of images.
Definition: Panorama.h:205
static MainFrame * Get()
hack.. kind of a pseudo singleton...
Definition: MainFrame.cpp:2129
void SetIgnoreLineCP(const bool noLineCp)
for external setting of &quot;ignore line cp&quot; checkbox
void OnIgnoreLineCp(wxCommandEvent &e)
Definition: MainFrame.cpp:1620
const PanoCommand * getLastCommand() const
return the last PanoCommand
void SetOnlyActiveImages(const bool onlyActive)
for external setting of &quot;only active image&quot; checkbox
void OnFAQ(wxCommandEvent &e)
Definition: MainFrame.cpp:1453
void OnMRUFiles(wxCommandEvent &e)
event handler for recently used files
Definition: MainFrame.cpp:2150
void SwitchToCropMode()
switches the controls to crop mode
void AddUserDefinedSequence(int id, const wxString &desc, const wxString &help)
adds the given user defined output sequence to SplitButton menu
Dialog for browsing pto files.
Definition: BrowseDialog.h:72
void SetGuiLevel(GuiLevel newLevel)
sets the gui level
void OnCPListFrameClosed()
Definition: MainFrame.cpp:1584
virtual void panoramaChanged(HuginBase::Panorama &pano)
this is called whenever the panorama has changed.
Definition: PanoPanel.cpp:278
void DisableOpenGLTools()
disables all OpenGL related menu items and toobar buttons
Definition: MainFrame.cpp:2369
void OnAddImages(wxCommandEvent &e)
Definition: MainFrame.cpp:1270
merge two project files
Definition: PanoCommand.h:375
class for generating plugin menu items
Definition: PluginItems.h:35
virtual bool wasSuccessful() const
Definition: Command.cpp:93
void SetOnlyActiveImages(const bool onlyActive)
for external setting of &quot;only active image&quot; checkbox
void panoramaImagesChanged(HuginBase::Panorama &pano, const HuginBase::UIntSet &imgNr)
notifies about changes to images
Definition: MainFrame.cpp:852
wxString GetCurrentOptimizerString()
returns the string which describes the current selected optimizer setting
Definition: MainFrame.cpp:2562
PanoOperation to add several user selected images to the panorama.
Definition: PanoOperation.h:73
IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow, wxWindow)
class for showing splash screen the class wxSplashScreen from wxWidgets does not work correctly for o...
Definition: MainFrame.cpp:88
Maximum of correlation, position and value.
Definition: Correlation.h:56
std::string getLastCommandName() const
returns the name of the last command
Dialog for about window.
Definition: AboutDialog.h:40
Definition of dialog for numeric transforms.
hugin_utils::FDiff2D curv
Definition: Correlation.h:68
void OnTogglePreviewFrame(wxCommandEvent &e)
Definition: MainFrame.cpp:1528
wxwindows specific panorama commands
bool canRedo() const
Return true iff there is a command to redo.
const wxString GetName() const
return name from metadata
void OnOptimizeButton(wxCommandEvent &e)
run the optimizer
update all control points
Definition: PanoCommand.h:117
void clearRedoQueue()
clear all commands in the redo queue
virtual ~MainFrame()
dtor.
Definition: MainFrame.cpp:747
distributes all images above the sphere, for the assistant
Definition: PanoCommand.h:649
void SetShowProjectionHints(bool new_value)
set status if projection hints should be shown or not
void SetOptimizeIgnoreLineCp(const bool ignoreLineCP)
sets the status of the &quot;ignore line cp&quot; menu item
Definition: MainFrame.cpp:1628
static GlobalCmdHist & getInstance()
const wxString & GetXRCPath()
get the path to the xrc directory
Definition: MainFrame.cpp:2118
void OnOptimizeButton(wxCommandEvent &e)
run the optimizer
void ShowMaskEditor(size_t imgNr, bool switchToCropMode=false)
opens the mask/crop editor with the given image selected
Definition: MainFrame.cpp:2000
void OnBrowseProjects(wxCommandEvent &e)
Definition: MainFrame.cpp:1219
void Init(HuginBase::Panorama *pano)
void addCommand(PanoCommand *command, bool execute=true)
Adds a command to the history.
void OnLoadProject(wxCommandEvent &e)
Definition: MainFrame.cpp:1174
const bool IsAPIValid() const
returns true, if plugin can run on given system and version
run the optimizer.
Definition: OptimizePanel.h:38
void OnOptimize(wxCommandEvent &e)
Definition: MainFrame.cpp:1589
CPListFrame * cp_frame
Definition: MainFrame.h:264
void clear()
Erases all the undo/redo history.
void ReloadCPDetectorSettings()
Reloads the cp detector settings from config, necessary after edit preferences.
#define DEBUG_ERROR(msg)
Definition: utils.h:76
wxMenu * m_menu_file_advanced
Definition: MainFrame.h:285
void Init(HuginBase::Panorama *pano)
The image preview frame.
Definition: PreviewFrame.h:40
void OnSaveProjectAs(wxCommandEvent &e)
Definition: MainFrame.cpp:1003
void OnSaveProject(wxCommandEvent &e)
Definition: MainFrame.cpp:966
void RunCPGenerator(CPDetectorSetting &setting, const HuginBase::UIntSet &img)
run the cp generator with the given setting on selected images
Definition: MainFrame.cpp:2103
bool CloseProject(bool cancelable, CloseReason reason)
Definition: MainFrame.cpp:864
void SetGuiLevel(GuiLevel newGuiLevel)
void Init(HuginBase::Panorama *pano)
void OnShowPanel(wxCommandEvent &e)
Definition: MainFrame.cpp:1328
GuiLevel m_guiLevel
Definition: MainFrame.h:265
void StoreFramePosition(wxTopLevelWindow *frame, const wxString &basename)
Definition: wxutils.cpp:135
void addObserver(PanoramaObserver *o)
add a panorama observer.
Definition: Panorama.cpp:1546
void OnDoStitch(wxCommandEvent &e)
Definition: MainFrame.cpp:1651
struct celeste::svm_model * GetSVMModel()
Definition: MainFrame.cpp:2186
void changeFinished(bool keepDirty)
notify observers about changes in this class
Definition: Panorama.cpp:831
PanoOperation to add all image in a defined timeinterval to the panorama.
Definition: PanoOperation.h:85
include file for the hugin project
#define HUGIN_CELESTE_MODEL
const PanoramaOptions & getOptions() const
returns the options for this panorama
Definition: Panorama.h:481
void OnHelp(wxCommandEvent &e)
Definition: MainFrame.cpp:1443
bool canUndo() const
Return true iff there is a command to undo.
const wxString GetSettingStringTranslated(wxConfigBase *setting, const wxString &name, const wxString defaultValue)
read a translated string from settings and remove all whitespaces
Definition: Executor.cpp:288
void setRightImage(unsigned int imgNr)
set right image
const int getPhotometricOptimizerSwitch() const
return the photometric optimizer master switch
Definition: Panorama.h:467
#define HUGIN_FT_CORR_THRESHOLD
GLPreviewFrame * getGLPreview()
Definition: MainFrame.cpp:2210
Components GetComponents()
find all connected components
Definition: ImageGraph.cpp:101
void OnRunAssistantUserdefined(wxCommandEvent &e)
Definition: MainFrame.cpp:2479
Memento class for a Panorama object.
Definition: Panorama.h:49
bool isDirty() const
true if there are unsaved changes
Definition: Panorama.h:636
void ShowCtrlPointEditor(unsigned int img1, unsigned int img2)
opens the control points tab with the both images selected
Definition: MainFrame.cpp:1988
const int getOptimizerSwitch() const
returns optimizer master switch
Definition: Panorama.h:461
MainFrame(wxWindow *parent, HuginBase::Panorama &pano)
ctor.
Definition: MainFrame.cpp:235
#define DEBUG_DEBUG(msg)
Definition: utils.h:68
std::string GetUserAppDataDir()
returns the directory for user specific Hugin settings, e.g.
Definition: utils.cpp:497
void Init(HuginBase::Panorama *pano)
bool containsInvalidCharacters(const wxString stringToTest)
returns true, if the given strings contains invalid characters
Definition: platform.cpp:510
HuginSplashScreen(wxWindow *parent, wxBitmap bitmap)
Definition: MainFrame.cpp:92
bool m_optOnlyActiveImages
Definition: MainFrame.h:289
add image(s) to a panorama
Definition: wxPanoCommand.h:50
Definition of dialog to browse directory with pto files.
virtual void redo()
Redoes the last undone action.
std::string GetHuginVersion()
return a string with version numbers
Definition: utils.cpp:907
void OnOnlyActiveImages(wxCommandEvent &e)
Definition: MainFrame.cpp:1596
void OnNewProject(wxCommandEvent &e)
Definition: MainFrame.cpp:1240
hugin_utils::FDiff2D maxpos
Definition: Correlation.h:64
void OnSetGuiSimple(wxCommandEvent &e)
Definition: MainFrame.cpp:2326
CPDetectorSetting & GetDefaultSetting()
returns the default cp detector settings
Definition: ImagesPanel.h:74
std::vector< ControlPoint > CPVector
Definition: ControlPoint.h:99
functions for interaction with the hugin configuration file
platform/compiler specific stuff.
wxString GetCurrentOptimizerString()
return the currently selected optimizer setting as string from the drop down list box ...
bool WritePTOFile(const std::string &filename, const std::string &prefix="")
write data to given pto file
Definition: Panorama.cpp:2059
void OnOpenPTBatcher(wxCommandEvent &e)
Definition: MainFrame.cpp:1759
std::vector< std::set< std::string > > OptimizeVector
void OnShowPrefs(wxCommandEvent &e)
Definition: MainFrame.cpp:1498
Define the pano edit panel.
Definition: PanoPanel.h:43
void OnFullScreen(wxCommandEvent &e)
event handler for full screen
Definition: MainFrame.cpp:2177
MaskEditorPanel * mask_panel
Definition: MainFrame.h:252
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition: Panorama.h:211
void OnShowEvent(wxShowEvent &e)
remove multiple images from a panorama
Definition: PanoCommand.h:94
GuiLevel
Definition: GuiLevel.h:31
void CleanPanoOperationVector()
clears the PanoOperationVector
void fill_set(_Container &c, typename _Container::key_type begin, typename _Container::key_type end)
Definition: stl_utils.h:81
virtual void undo()
Undoes the last action.
bool IsRawExtension(const wxString &testExt)
return true, if given extension is in list of known raw extension (comparision is case insensitive ...
Definition: platform.cpp:111
CommandQueue * GetAssistantCommandQueueUserDefined(const HuginBase::Panorama &pano, const wxString &ExePath, const wxString &project, const wxString &assistantSetting, wxArrayString &tempFilesDelete, std::ostream &errStream)
generates the command queue for running the assistant
void OnAbout(wxCommandEvent &e)
Definition: MainFrame.cpp:1405
CPDetectorSetting & GetDefaultSetting()
returns default cp detector setting
Definition: MainFrame.cpp:2098
virtual void panoramaChanged(HuginBase::Panorama &pano)
Enable or disable undo and redo.
Definition: MainFrame.cpp:788
const wxString GetCategory() const
return category name
void OnAddTimeImages(wxCommandEvent &e)
Definition: MainFrame.cpp:1317
str wxQuoteFilename(const str &arg)
Quote a filename, so that it is surrounded by &quot;&quot;.
Definition: wxPlatform.h:82
dump the current project and load a new one.
Definition: wxPanoCommand.h:66
void OnSize(wxSizeEvent &e)
Definition: MainFrame.cpp:2083
wxString getProjectName()
Definition: MainFrame.cpp:2140
const wxString & GetXRCPath()
return the current xrc path
Definition: huginApp.h:98
void SetGuiLevel(GuiLevel newGuiLevel)
sets the GuiLevel for all controls on this panel
UIntSet getCPinMasks(HuginBase::Panorama pano)
returns these control points, which are in masks
Definition: CleanCP.cpp:186
bool IsShowingCorrelation() const
Definition: MainFrame.cpp:2145
PreviewFrame * preview_frame
Definition: MainFrame.h:262
const wxString GetSelectedCPGenerator()
return the currently selected cp generator description
void ResetPreviewZoom()
reset zoom level for preview window
wxString Components2Str(const HuginGraph::ImageGraph::Components &comp)
Definition: huginApp.cpp:84
int HuginMessageBox(const wxString &message, const wxString &caption, int style, wxWindow *parent)
Definition: wxutils.cpp:176
std::map< int, wxString > m_userAssistant
Definition: MainFrame.h:300
wxString getDefaultProjectName(const HuginBase::Panorama &pano, const wxString filenameTemplate)
gets the default project name, as defined in the preferences
std::vector< NormalCommand * > CommandQueue
Definition: Executor.h:61
void printStitcherScript(std::ostream &o, const PanoramaOptions &target, const UIntSet &imgs) const
create the stitcher script
Definition: Panorama.cpp:778
void OnSetGuiExpert(wxCommandEvent &e)
Definition: MainFrame.cpp:2364
bool CheckRawFiles()
return true, if all raw files are from the same camera
Definition: RawImport.cpp:630
create a CommandQueue for running the assistant using CLI tools
void OnReadPapywizard(wxCommandEvent &e)
Definition: MainFrame.cpp:1722
void enableTools(bool option)
Definition: MainFrame.cpp:2055
class to work with images graphs created from a HuginBase::Panorama class it creates a graph based on...
Definition: ImageGraph.h:44