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