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