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