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