Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
huginApp.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
27 #include "hugin_config.h"
28 
29 #include "panoinc_WX.h"
30 
31 #ifdef __WXMAC__
32 #include <wx/sysopt.h>
33 #include <wx/dir.h>
34 #endif
35 
36 #include "panoinc.h"
37 
38 #include "hugin/config_defaults.h"
39 #include "hugin/huginApp.h"
40 #include "hugin/ImagesPanel.h"
41 #include "hugin/MaskEditorPanel.h"
42 #include "hugin/CPEditorPanel.h"
44 #include "hugin/PanoPanel.h"
45 #include "hugin/CPListFrame.h"
46 #include "hugin/PreviewPanel.h"
47 #include "hugin/GLPreviewFrame.h"
48 #include "hugin/RawImport.h"
49 #include "base_wx/PTWXDlg.h"
50 #include "base_wx/CommandHistory.h"
51 #include "base_wx/wxcms.h"
52 #include "base_wx/wxPanoCommand.h"
53 #include "hugin/HtmlWindow.h"
54 #include "hugin/treelistctrl.h"
55 #include "hugin/ImagesTree.h"
56 #include "hugin/SplitButton.h"
57 
58 #include "base_wx/platform.h"
59 #include "base_wx/huginConfig.h"
60 #include <wx/cshelp.h>
61 #include <wx/stdpaths.h>
62 #ifdef __WXMSW__
63 #include <wx/dir.h>
64 #include <wx/taskbarbutton.h>
65 #endif
66 #if defined __WXGTK__
67 #include "base_wx/wxPlatform.h"
68 #endif
69 
70 #include <tiffio.h>
71 
72 #include "AboutDialog.h"
73 
74 //for natural sorting
75 #include "hugin_utils/alphanum.h"
76 #include "lensdb/LensDB.h"
77 
78 bool checkVersion(wxString v1, wxString v2)
79 {
80  return doj::alphanum_comp(std::string(v1.mb_str(wxConvLocal)),std::string(v2.mb_str(wxConvLocal))) < 0;
81 };
82 
84 {
85  wxString ret;
86  for (unsigned i=0; i < comp.size(); i++) {
87  ret.Append(wxT("["));
88  HuginGraph::ImageGraph::Components::value_type::const_iterator it = comp[i].begin();
89  while (it != comp[i].end())
90  {
91  unsigned int imgNr = *it;
92  ret << imgNr;
93  it++;
94  if (it != comp[i].end() && *it == imgNr + 1)
95  {
96  ret.Append(wxT("-"));
97  while (it != comp[i].end() && *it == imgNr + 1)
98  {
99  ++it;
100  ++imgNr;
101  };
102  ret << imgNr;
103  if (it != comp[i].end())
104  {
105  ret.Append(wxT(", "));
106  };
107  }
108  else
109  {
110  if (it != comp[i].end())
111  {
112  ret.Append(wxT(", "));
113  };
114  };
115  };
116 
117  ret.Append(wxT("]"));
118  if (i + 1 != comp.size())
119  {
120  ret.Append(wxT(", "));
121  };
122  }
123  return ret;
124 }
125 
126 // make wxwindows use this class as the main application
127 #if defined USE_GDKBACKEND_X11
128 // wxWidgets does not support wxGLCanvas on Wayland
129 // so until it is fixed upstream enforce using x11 backend
130 // see ticket http://trac.wxwidgets.org/ticket/17702
131 #warning Using Hugin with hard coded GDK_BACKEND=x11
132 wxIMPLEMENT_WX_THEME_SUPPORT
133 wxIMPLEMENT_APP_NO_MAIN(huginApp);
134 #include <stdlib.h>
135 int main(int argc, char **argv)
136 {
137  wxDISABLE_DEBUG_SUPPORT();
138  char backend[]="GDK_BACKEND=x11";
139  putenv(backend);
140  return wxEntry(argc, argv);
141 };
142 #else
144 #endif
145 
146 wxDEFINE_EVENT(EVT_IMAGE_READY, ImageReadyEvent);
147 
148 ImageReadyEvent::ImageReadyEvent(HuginBase::ImageCache::RequestPtr request, HuginBase::ImageCache::EntryPtr entry) : wxEvent(0, EVT_IMAGE_READY), request(request), entry(entry)
149 {
150 }
151 
152 wxEvent* ImageReadyEvent::Clone() const
153 {
154  return new ImageReadyEvent(request, entry);
155 }
156 
158 {
159  DEBUG_TRACE("ctor");
160  m_this=this;
161  m_monitorProfile = NULL;
162 #if wxUSE_ON_FATAL_EXCEPTION
163  wxHandleFatalExceptions();
164 #endif
165  Bind(EVT_IMAGE_READY, &huginApp::relayImageLoaded, this);
166 }
167 
169 {
170  DEBUG_TRACE("dtor");
171  // delete temporary dir
172 // if (!wxRmdir(m_workDir)) {
173 // DEBUG_ERROR("Could not remove temporary directory");
174 // }
175 
176  // todo: remove all listeners from the panorama object
177 
178 // delete frame;
180  // delete monitor profile
181  if (m_monitorProfile)
182  {
183  cmsCloseProfile(m_monitorProfile);
184  };
185  DEBUG_TRACE("dtor end");
186 }
187 
189 {
190  DEBUG_TRACE("=========================== huginApp::OnInit() begin ===================");
191  SetAppName(wxT("hugin"));
192 #if defined __WXGTK__
193  CheckConfigFilename();
194 #endif
195 
196  // Connect to ImageCache: we need to tell it when it is safe to handle UI events.
197  ImageCache::getInstance().asyncLoadCompleteSignal = &huginApp::imageLoadedAsync;
198 
199 #ifdef __WXMAC__
200  // do not use the native list control on OSX (it is very slow with the control point list window)
201  wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), 1);
202  // On OS X the file open does by default not show the file type list
203  // Apple means this is not necessary
204  // but the the add images dialog needs this selection, so force to
205  // display always the file type list
206  wxSystemOptions::SetOption(wxOSX_FILEDIALOG_ALWAYS_SHOW_TYPES, 1);
207 #endif
208 
209  // register our custom pano tools dialog handlers
211 
212  // required by wxHtmlHelpController
213  wxFileSystem::AddHandler(new wxZipFSHandler);
214 
215  // initialize help provider
216  wxHelpControllerHelpProvider* provider = new wxHelpControllerHelpProvider;
217  wxHelpProvider::Set(provider);
218 
219 #if defined __WXMSW__
220  wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
221  m_utilsBinDir = exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
222  exePath.RemoveLastDir();
223  const wxString huginRoot=exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
224  m_xrcPrefix = huginRoot + wxT("share\\hugin\\xrc\\");
225  m_DataDir = huginRoot + wxT("share\\hugin\\data\\");
226 
227  // locale setup
228  locale.AddCatalogLookupPathPrefix(huginRoot + wxT("share\\locale"));
229 
230 #elif defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
231  // initialize paths
232  {
233  wxString thePath = MacGetPathToBundledResourceFile(CFSTR("xrc"));
234  if (thePath == wxT("")) {
235  wxMessageBox(_("xrc directory not found in bundle"), _("Fatal Error"));
236  return false;
237  }
238  m_xrcPrefix = thePath + wxT("/");
239  m_DataDir = thePath + wxT("/");
240  }
241 
242 #ifdef HUGIN_HSI
243  // Set PYTHONHOME for the hsi module
244  {
245  wxString pythonHome = MacGetPathToBundledFrameworksDirectory() + wxT("/Python27.framework/Versions/Current");
246  if(! wxDir::Exists(pythonHome)){
247  wxMessageBox(wxString::Format(_("Directory '%s' does not exists"), pythonHome.c_str()));
248  } else {
249  wxUnsetEnv(wxT("PYTHONPATH"));
250  if(! wxSetEnv(wxT("PYTHONHOME"), pythonHome)){
251  wxMessageBox(_("Could not set environment variable PYTHONHOME"));
252  } else {
253  DEBUG_TRACE("PYTHONHOME set to " << pythonHome);
254  }
255  }
256  }
257 #endif
258 
259 #elif defined UNIX_SELF_CONTAINED_BUNDLE
260  // initialize paths
261  {
262  wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
263  m_utilsBinDir = exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
264  exePath.RemoveLastDir();
265  const wxString huginRoot=exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
266  m_xrcPrefix = huginRoot + wxT("share/hugin/xrc/");
267  m_DataDir = huginRoot + wxT("share/hugin/data/");
268 
269  // locale setup
270  locale.AddCatalogLookupPathPrefix(huginRoot + wxT("share/locale"));
271  }
272 
273 #else
274  // add the locale directory specified during configure
275  m_xrcPrefix = wxT(INSTALL_XRC_DIR);
276  m_DataDir = wxT(INSTALL_DATA_DIR);
277  locale.AddCatalogLookupPathPrefix(wxT(INSTALL_LOCALE_DIR));
278 #endif
279 
280  if ( ! wxFile::Exists(m_xrcPrefix + wxT("/main_frame.xrc")) ) {
281  wxMessageBox(_("xrc directory not found, hugin needs to be properly installed\nTried Path:" + m_xrcPrefix ), _("Fatal Error"));
282  return false;
283  }
284 
285  // here goes and comes configuration
286  wxConfigBase * config = wxConfigBase::Get();
287  // do not record default values in the preferences file
288  config->SetRecordDefaults(false);
289 
290  config->Flush();
291 
292  // need to explicitly initialize locale for C++ library/runtime
293  setlocale(LC_ALL, "");
294  // initialize i18n
295  int localeID = config->Read(wxT("language"), (long) HUGIN_LANGUAGE);
296  DEBUG_TRACE("localeID: " << localeID);
297  {
298  bool bLInit;
299  bLInit = locale.Init(localeID);
300  if (bLInit) {
301  DEBUG_TRACE("locale init OK");
302  DEBUG_TRACE("System Locale: " << locale.GetSysName().mb_str(wxConvLocal))
303  DEBUG_TRACE("Canonical Locale: " << locale.GetCanonicalName().mb_str(wxConvLocal))
304  } else {
305  DEBUG_TRACE("locale init failed");
306  }
307  }
308 
309  // set the name of locale recource to look for
310  locale.AddCatalog(wxT("hugin"));
311 
312  // initialize image handlers
313  wxInitAllImageHandlers();
314 
315  // Initialize all the XRC handlers.
316  wxXmlResource::Get()->InitAllHandlers();
317 
318  // load all XRC files.
319  #ifdef _INCLUDE_UI_RESOURCES
320  InitXmlResource();
321  #else
322 
323  // add custom XRC handlers
324  wxXmlResource::Get()->AddHandler(new ImagesPanelXmlHandler());
325  wxXmlResource::Get()->AddHandler(new CPEditorPanelXmlHandler());
326  wxXmlResource::Get()->AddHandler(new CPImageCtrlXmlHandler());
327  wxXmlResource::Get()->AddHandler(new CPImagesComboBoxXmlHandler());
328  wxXmlResource::Get()->AddHandler(new MaskEditorPanelXmlHandler());
329  wxXmlResource::Get()->AddHandler(new MaskImageCtrlXmlHandler());
330  wxXmlResource::Get()->AddHandler(new OptimizePanelXmlHandler());
331  wxXmlResource::Get()->AddHandler(new OptimizePhotometricPanelXmlHandler());
332  wxXmlResource::Get()->AddHandler(new PanoPanelXmlHandler());
333  wxXmlResource::Get()->AddHandler(new PreviewPanelXmlHandler());
334  wxXmlResource::Get()->AddHandler(new HtmlWindowXmlHandler());
335  wxXmlResource::Get()->AddHandler(new wxcode::wxTreeListCtrlXmlHandler());
336  wxXmlResource::Get()->AddHandler(new ImagesTreeCtrlXmlHandler());
337  wxXmlResource::Get()->AddHandler(new CPListCtrlXmlHandler());
338  wxXmlResource::Get()->AddHandler(new SplitButtonXmlHandler());
339 
340  // load XRC files
341  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("cp_list_frame.xrc"));
342  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("preview_frame.xrc"));
343  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("edit_script_dialog.xrc"));
344  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("main_menu.xrc"));
345  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("main_tool.xrc"));
346  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("about.xrc"));
347  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("pref_dialog.xrc"));
348  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("cpdetector_dialog.xrc"));
349  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("reset_dialog.xrc"));
350  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("optimize_photo_panel.xrc"));
351  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("cp_editor_panel.xrc"));
352  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("images_panel.xrc"));
353  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("main_frame.xrc"));
354  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("optimize_panel.xrc"));
355  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("pano_panel.xrc"));
356  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("mask_editor_panel.xrc"));
357  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("lensdb_dialogs.xrc"));
358  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("image_variable_dlg.xrc"));
359  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("dlg_warning.xrc"));
360  wxXmlResource::Get()->Load(m_xrcPrefix + wxT("import_raw_dialog.xrc"));
361 #endif
362 
363 #ifdef __WXMAC__
364  // If hugin is starting with file opening AppleEvent, MacOpenFile will be called on first wxYield().
365  // Those need to be initialised before first call of Yield which happens in Mainframe constructor.
366  m_macInitDone=false;
367  m_macOpenFileOnStart=false;
368 #endif
369  // read monitor profile
371  // create main frame
372  frame = new MainFrame(NULL, pano);
373  SetTopWindow(frame);
374 
375  // setup main frame size, after it has been created.
376  RestoreFramePosition(frame, wxT("MainFrame"));
377 #ifdef __WXMSW__
378  frame->SendSizeEvent();
379 // wxUSE_TASKBARBUTTON 1 is default, nevertheless check that the feature has not been deactivated by the user, otherwise issue a warning
380 #if wxUSE_TASKBARBUTTON
381  wxTaskBarJumpList jumpList;
382  wxFileName exeFile(wxStandardPaths::Get().GetExecutablePath());
383  exeFile.SetName("PTBatcherGUI");
384  wxTaskBarJumpListItem *item1 = new wxTaskBarJumpListItem(
385  NULL, wxTASKBAR_JUMP_LIST_TASK, _("Open Batch Processor"), exeFile.GetFullPath(), wxEmptyString,
386  _("Opens PTBatcherGUI, the batch processor for Hugin's project files"),
387  exeFile.GetFullPath(), 0);
388  jumpList.GetTasks().Append(item1);
389  exeFile.SetName("calibrate_lens_gui");
390  wxTaskBarJumpListItem *item2 = new wxTaskBarJumpListItem(
391  NULL, wxTASKBAR_JUMP_LIST_TASK, _("Open Lens calibrate tool"), exeFile.GetFullPath(), wxEmptyString,
392  _("Opens Calibrate_lens_gui, a simple GUI for lens calibration"),
393  exeFile.GetFullPath(), 0);
394  jumpList.GetTasks().Append(item2);
395 #else
396  #if defined _MSC_VER
397  #pragma message("Warning: huginApp.cpp - wxWidgets is compiled without support for taskbar buttons. Some features have therefore disabled.")
398  #else
399  #warning "Warning: huginApp.cpp - wxWidgets is compiled without support for taskbar buttons. Some features have therefore disabled."
400  #endif
401 #endif
402 #endif
403  // init help system
404  provider->SetHelpController(&frame->GetHelpController());
405 #ifdef __WXMSW__
406  frame->GetHelpController().Initialize(m_xrcPrefix + wxT("data/hugin_help_en_EN.chm"));
407 #else
408 #if wxUSE_WXHTML_HELP
409  // using wxHtmlHelpController
410 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
411  // On Mac, xrc/data/help_LOCALE should be in the bundle as LOCALE.lproj/help
412  // which we can rely on the operating sytem to pick the right locale's.
413  wxString strFile = MacGetPathToBundledResourceFile(CFSTR("help"));
414  if (!strFile.IsEmpty())
415  {
416  frame->GetHelpController().AddBook(wxFileName(strFile + wxT("/hugin_help_en_EN.hhp")));
417  }
418  else
419  {
420  wxLogError(wxString::Format(wxT("Could not find help directory in the bundle"), strFile.c_str()));
421  return false;
422  }
423 #else
424  frame->GetHelpController().AddBook(wxFileName(m_xrcPrefix + wxT("data/help_en_EN/hugin_help_en_EN.hhp")));
425 #endif
426 #else
427  // using wxExtHelpController
428  frame->GetHelpController().Initialize(Initialize(m_xrcPrefix + wxT("data/help_en_EN")));
429 #endif
430 #endif
431 
432  // we are closing Hugin, if the top level window is deleted
433  SetExitOnFrameDelete(true);
434  // show the frame.
436  {
437  SetTopWindow(frame->getGLPreview());
438  }
439  else
440  {
441  frame->Show(TRUE);
442  };
443 
444  wxString cwd = wxFileName::GetCwd();
445 
446  m_workDir = config->Read(wxT("tempDir"),wxT(""));
447  // FIXME, make secure against some symlink attacks
448  // get a temp dir
449  if (m_workDir == wxT("")) {
450 #if (defined __WXMSW__)
451  DEBUG_DEBUG("figuring out windows temp dir");
452  /* added by Yili Zhao */
453  wxChar buffer[MAX_PATH];
454  GetTempPath(MAX_PATH, buffer);
455  m_workDir = buffer;
456 #elif (defined __WXMAC__) && (defined MAC_SELF_CONTAINED_BUNDLE)
457  DEBUG_DEBUG("temp dir on Mac");
458  m_workDir = MacGetPathToUserDomainTempDir();
459  if(m_workDir == wxT(""))
460  m_workDir = wxT("/tmp");
461 #else //UNIX
462  DEBUG_DEBUG("temp dir on unix");
463  // try to read environment variable
464  if (!wxGetEnv(wxT("TMPDIR"), &m_workDir)) {
465  // still no tempdir, use /tmp
466  m_workDir = wxT("/tmp");
467  }
468 #endif
469 
470  }
471 
472  if (!wxFileName::DirExists(m_workDir)) {
473  DEBUG_DEBUG("creating temp dir: " << m_workDir.mb_str(wxConvLocal));
474  if (!wxMkdir(m_workDir)) {
475  DEBUG_ERROR("Tempdir could not be created: " << m_workDir.mb_str(wxConvLocal));
476  }
477  }
478  if (!wxSetWorkingDirectory(m_workDir)) {
479  DEBUG_ERROR("could not change to temp. dir: " << m_workDir.mb_str(wxConvLocal));
480  }
481  DEBUG_DEBUG("using temp dir: " << m_workDir.mb_str(wxConvLocal));
482 
483  // set some suitable defaults
486 
487  // suppress tiff warnings
488  TIFFSetWarningHandler(0);
489 
490  if (argc > 1)
491  {
492 #ifdef __WXMSW__
493  //on Windows we need to update the fast preview first
494  //otherwise there is an infinite loop when starting with a project file
495  //and closed panorama editor aka mainframe
497  {
498  frame->getGLPreview()->Update();
499  };
500 #endif
501  wxFileName file(argv[1]);
502  // if the first file is a project file, open it
503  if (file.GetExt().CmpNoCase(wxT("pto")) == 0 ||
504  file.GetExt().CmpNoCase(wxT("pts")) == 0 ||
505  file.GetExt().CmpNoCase(wxT("ptp")) == 0 )
506  {
507  if(file.IsRelative())
508  file.MakeAbsolute(cwd);
509  // Loading the project file with set actualPath to its
510  // parent directory. (actualPath is used as starting
511  // directory by many subsequent file selection dialogs.)
512  frame->LoadProjectFile(file.GetFullPath());
513  } else {
514  std::vector<std::string> filesv;
515  std::vector<std::string> rawFilesv;
516  bool actualPathSet = false;
517  for (int i=1; i< argc; i++)
518  {
519 #if defined __WXMSW__
520  //expand wildcards
521  wxFileName fileList(argv[i]);
522  if(fileList.IsRelative())
523  fileList.MakeAbsolute(cwd);
524  wxDir dir;
525  wxString foundFile;
526  wxFileName file;
527  if(fileList.DirExists())
528  if(dir.Open(fileList.GetPath()))
529  if(dir.GetFirst(&foundFile,fileList.GetFullName(),wxDIR_FILES | wxDIR_HIDDEN))
530  do
531  {
532  file=foundFile;
533  file.MakeAbsolute(dir.GetName());
534 #else
535  wxFileName file(argv[i]);
536 #endif
537  if (file.IsRelative())
538  {
539  file.MakeAbsolute(cwd);
540  };
541  if (IsRawExtension(file.GetExt()))
542  {
543  // we got a raw file from command line
544  if (!containsInvalidCharacters(file.GetFullPath()))
545  {
546  rawFilesv.push_back((const char*)file.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
547  // Use the first filename to set actualPath.
548  if (!actualPathSet)
549  {
550  config->Write(wxT("/actualPath"), file.GetPath());
551  actualPathSet = true;
552  };
553  };
554  }
555  else
556  {
557  if (vigra::isImage(file.GetFullPath().mb_str(HUGIN_CONV_FILENAME)))
558  {
559  if (!containsInvalidCharacters(file.GetFullPath()))
560  {
561  filesv.push_back((const char *)(file.GetFullPath().mb_str(HUGIN_CONV_FILENAME)));
562  // Use the first filename to set actualPath.
563  if (!actualPathSet)
564  {
565  config->Write(wxT("/actualPath"), file.GetPath());
566  actualPathSet = true;
567  };
568  };
569  };
570  };
571 #if defined __WXMSW__
572  } while (dir.GetNext(&foundFile));
573 #endif
574  }
575  if(!filesv.empty())
576  {
577  std::vector<PanoCommand::PanoCommand*> cmds;
578  cmds.push_back(new PanoCommand::wxAddImagesCmd(pano,filesv));
579  cmds.push_back(new PanoCommand::DistributeImagesCmd(pano));
580  cmds.push_back(new PanoCommand::CenterPanoCmd(pano));
582  };
583  if (!rawFilesv.empty())
584  {
585  if (rawFilesv.size() == 1)
586  {
587  wxMessageDialog message(GetTopWindow(), _("You selected only one raw file. This is not recommended.\nAll raw files should be converted at once."),
588 #ifdef _WIN32
589  _("Hugin"),
590 #else
591  wxT(""),
592 #endif
593  wxICON_EXCLAMATION | wxOK | wxCANCEL);
594  message.SetOKLabel(_("Convert anyway."));
595  if (message.ShowModal() != wxID_OK)
596  {
597  return true;
598  };
599  };
600  RawImportDialog dlg(GetTopWindow(), &pano, rawFilesv);
601  // check that raw files are from same camera and that all can be read
602  if (dlg.CheckRawFiles())
603  {
604  // now show dialog
605  if (dlg.ShowModal() == wxID_OK)
606  {
608  };
609  };
610  };
611  };
612  }
613 #ifdef __WXMAC__
614  m_macInitDone = true;
615  if(m_macOpenFileOnStart) {frame->LoadProjectFile(m_macFileNameToOpenOnStart);}
616  m_macOpenFileOnStart = false;
617 #endif
618 
619  //check for no tip switch, needed by PTBatcher
620  wxString secondParam = argc > 2 ? wxString(argv[2]) : wxString();
621  if(secondParam.Cmp(_T("-notips"))!=0)
622  {
623  //load tip startup preferences (tips will be started after splash terminates)
624  int nValue = config->Read(wxT("/MainFrame/ShowStartTip"), 1l);
625 
626  //show tips if needed now
627  if(nValue > 0)
628  {
629  wxCommandEvent dummy;
630  frame->OnTipOfDay(dummy);
631  }
632  }
633 
634  DEBUG_TRACE("=========================== huginApp::OnInit() end ===================");
635  return true;
636 }
637 
639 {
640  DEBUG_TRACE("");
641  delete wxHelpProvider::Set(NULL);
642  return 0;
643 }
644 
646 {
647  if (m_this) {
648  return m_this;
649  } else {
650  DEBUG_FATAL("huginApp not yet created");
652  return 0;
653  }
654 }
655 
657 {
658  if (m_this) {
659  return m_this->frame;
660  } else {
661  return 0;
662  }
663 }
664 
666 {
667  if (event.entry.get())
668  {
669  ImageCache::getInstance().postEvent(event.request, event.entry);
670  }
671  else
672  {
673  // loading failed, first remove request from image cache list
674  ImageCache::getInstance().removeRequest(event.request);
675  // now notify main frame to remove the failed image from project
676  wxCommandEvent e(EVT_LOADING_FAILED);
677  e.SetString(wxString(event.request->getFilename().c_str(), HUGIN_CONV_FILENAME));
678  frame->GetEventHandler()->AddPendingEvent(e);
679  };
680 }
681 
682 void huginApp::imageLoadedAsync(ImageCache::RequestPtr request, ImageCache::EntryPtr entry)
683 {
684  ImageReadyEvent event(request, entry);
685  // AddPendingEvent adds the event to the event queue and returns without
686  // processing it. This is necessary since we are probably not in the
687  // UI thread, but the event handler must be run in the UI thread since it
688  // could update image views.
689  Get()->AddPendingEvent(event);
690 }
691 
692 #ifdef __WXMAC__
693 void huginApp::MacOpenFile(const wxString &fileName)
694 {
695  if(!m_macInitDone)
696  {
697  m_macOpenFileOnStart=true;
698  m_macFileNameToOpenOnStart = fileName;
699  return;
700  }
701 
702  if(frame) frame->MacOnOpenFile(fileName);
703 }
704 #endif
705 
706 #if wxUSE_ON_FATAL_EXCEPTION
707 void huginApp::OnFatalException()
708 {
709  GenerateReport(wxDebugReport::Context_Exception);
710 };
711 #endif
712 
714 
715 
716 // utility functions
717 
718 void RestoreFramePosition(wxTopLevelWindow * frame, const wxString & basename)
719 {
720  DEBUG_TRACE(basename.mb_str(wxConvLocal));
721 
722  wxConfigBase * config = wxConfigBase::Get();
723 
724  // get display size
725  int dx,dy;
726  wxDisplaySize(&dx,&dy);
727 
728 #if ( __WXGTK__ )
729 // restoring the splitter positions properly when maximising doesn't work.
730 // Disabling maximise on wxWidgets >= 2.6.0 and gtk
731  //size
732  int w = config->Read(wxT("/") + basename + wxT("/width"),-1l);
733  int h = config->Read(wxT("/") + basename + wxT("/height"),-1l);
734  if (w > 0 && w <= dx) {
735  frame->SetClientSize(w,h);
736  } else {
737  frame->Fit();
738  }
739  //position
740  int x = config->Read(wxT("/") + basename + wxT("/positionX"),-1l);
741  int y = config->Read(wxT("/") + basename + wxT("/positionY"),-1l);
742  if ( y >= 0 && x >= 0 && x < dx && y < dy) {
743  frame->Move(x, y);
744  } else {
745  frame->Move(0, 44);
746  }
747 #else
748  bool maximized = config->Read(wxT("/") + basename + wxT("/maximized"), 0l) != 0;
749  if (maximized) {
750  frame->Maximize();
751  } else {
752  //size
753  int w = config->Read(wxT("/") + basename + wxT("/width"),-1l);
754  int h = config->Read(wxT("/") + basename + wxT("/height"),-1l);
755  if (w > 0 && w <= dx) {
756  frame->SetClientSize(w,h);
757  } else {
758  frame->Fit();
759  }
760  //position
761  int x = config->Read(wxT("/") + basename + wxT("/positionX"),-1l);
762  int y = config->Read(wxT("/") + basename + wxT("/positionY"),-1l);
763  if ( y >= 0 && x >= 0 && x < dx && y < dy) {
764  frame->Move(x, y);
765  } else {
766  frame->Move(0, 44);
767  }
768  }
769 #endif
770 }
771 
772 
773 void StoreFramePosition(wxTopLevelWindow * frame, const wxString & basename)
774 {
775  DEBUG_TRACE(basename);
776 
777  wxConfigBase * config = wxConfigBase::Get();
778 
779 #if ( __WXGTK__ )
780 // restoring the splitter positions properly when maximising doesn't work.
781 // Disabling maximise on wxWidgets >= 2.6.0 and gtk
782 
783  wxSize sz = frame->GetClientSize();
784  config->Write(wxT("/") + basename + wxT("/width"), sz.GetWidth());
785  config->Write(wxT("/") + basename + wxT("/height"), sz.GetHeight());
786  wxPoint ps = frame->GetPosition();
787  config->Write(wxT("/") + basename + wxT("/positionX"), ps.x);
788  config->Write(wxT("/") + basename + wxT("/positionY"), ps.y);
789  config->Write(wxT("/") + basename + wxT("/maximized"), 0);
790 #else
791  if ( (! frame->IsMaximized()) && (! frame->IsIconized()) ) {
792  wxSize sz = frame->GetClientSize();
793  config->Write(wxT("/") + basename + wxT("/width"), sz.GetWidth());
794  config->Write(wxT("/") + basename + wxT("/height"), sz.GetHeight());
795  wxPoint ps = frame->GetPosition();
796  config->Write(wxT("/") + basename + wxT("/positionX"), ps.x);
797  config->Write(wxT("/") + basename + wxT("/positionY"), ps.y);
798  config->Write(wxT("/") + basename + wxT("/maximized"), 0);
799  } else if (frame->IsMaximized()){
800  config->Write(wxT("/") + basename + wxT("/maximized"), 1l);
801  }
802 #endif
803 }
wxDEFINE_EVENT(EVT_QUEUE_PROGRESS, wxCommandEvent)
bool checkVersion(wxString v1, wxString v2)
Definition: huginApp.cpp:78
int alphanum_comp(const std::string &l, const std::string &r)
Compare l and r with the same semantics as strcmp(), but with the &quot;Alphanum Algorithm&quot; which produces...
Definition: alphanum.cpp:119
static huginApp * m_this
Definition: huginApp.h:163
The application class for hugin.
Definition: huginApp.h:70
implementation of huginApp Class
virtual bool OnInit()
pseudo constructor.
Definition: huginApp.cpp:188
HuginBase::Panorama pano
Definition: huginApp.h:166
start a new project, reset options to values in preferences
Definition: wxPanoCommand.h:85
center panorama horizontically
Definition: PanoCommand.h:250
declaration of main image tree control
wxIMPLEMENT_APP(huginApp)
#define HUGIN_CONV_FILENAME
Definition: platform.h:40
xrc handler for split button
Definition: SplitButton.h:94
#define DEBUG_TRACE(msg)
Definition: utils.h:67
cmsHPROFILE m_monitorProfile
Definition: huginApp.h:176
xrc handler for handling mask editor panel
void registerPTWXDlgFcn()
Definition: PTWXDlg.cpp:173
#define HUGIN_LANGUAGE
void relayImageLoaded(ImageReadyEvent &event)
Relay image loaded event when the UI thread is ready to process it.
Definition: huginApp.cpp:665
void OnTipOfDay(wxCommandEvent &e)
Definition: MainFrame.cpp:1495
MainFrame * frame
Definition: huginApp.h:160
huginApp()
ctor.
Definition: huginApp.cpp:157
wxString m_DataDir
Definition: huginApp.h:171
#define DEBUG_ASSERT(cond)
Definition: utils.h:80
include file for the hugin project
wxHelpController & GetHelpController()
Definition: MainFrame.h:183
virtual wxEvent * Clone() const
Definition: huginApp.cpp:152
wxString m_monitorProfileName
Definition: huginApp.h:175
std::vector< HuginBase::UIntSet > Components
stores the components of the graph
Definition: ImageGraph.h:50
static void Clean()
cleanup the static LensDB instance, must be called at the end of the program
Definition: LensDB.cpp:2010
static huginApp * Get()
hack.. kind of a pseudo singleton...
Definition: huginApp.cpp:645
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
class to access Hugins camera and lens database
The main window frame.
Definition: MainFrame.h:83
xrc handler for mask editor
wxString m_xrcPrefix
Definition: huginApp.h:169
void LoadProjectFile(const wxString &filename)
Definition: MainFrame.cpp:1078
Definition of dialog and functions to import RAW images to project file.
HuginBase::ImageCache::EntryPtr entry
Definition: huginApp.h:59
std::shared_ptr< Entry > EntryPtr
a shared pointer to the entry
Definition: ImageCache.h:112
PanoCommand::PanoCommand * GetPanoCommand()
return PanoCommand for adding converted raw files to Panorama
Definition: RawImport.cpp:644
void StoreFramePosition(wxTopLevelWindow *frame, const wxString &basename)
Store window size and position in configfile/registry.
Definition: LensCalApp.cpp:210
static MainFrame * getMainFrame()
Definition: huginApp.cpp:656
Definition of dialog for numeric transforms.
std::shared_ptr< Request > RequestPtr
Reference counted request for an image to load.
Definition: ImageCache.h:151
wxString m_utilsBinDir
Definition: huginApp.h:173
wxwindows specific panorama commands
distributes all images above the sphere, for the assistant
Definition: PanoCommand.h:649
void RestoreFramePosition(wxTopLevelWindow *frame, const wxString &basename)
Restore window size and position from configfile/registry.
Definition: LensCalApp.cpp:156
IMPEX double h[25][1024]
Definition: emor.cpp:169
xrc handler for CPImagesComboBox
Definition: CPListFrame.h:94
static GlobalCmdHist & getInstance()
options wxIntPtr item2
void addCommand(PanoCommand *command, bool execute=true)
Adds a command to the history.
void clear()
Erases all the undo/redo history.
#define DEBUG_ERROR(msg)
Definition: utils.h:76
xrc handler for CPImagesComboBox
ImageReadyEvent(HuginBase::ImageCache::RequestPtr request, HuginBase::ImageCache::EntryPtr entry)
Definition: huginApp.cpp:148
wxString m_workDir
temporary working directory
Definition: huginApp.h:158
include file for the hugin project
const GuiLevel GetGuiLevel() const
Definition: MainFrame.h:185
GLPreviewFrame * getGLPreview()
Definition: MainFrame.cpp:2234
virtual ~huginApp()
dtor.
Definition: huginApp.cpp:168
xrc handler
Definition: PanoPanel.h:225
virtual int OnExit()
just for testing purposes
Definition: huginApp.cpp:638
#define DEBUG_DEBUG(msg)
Definition: utils.h:68
bool containsInvalidCharacters(const wxString stringToTest)
returns true, if the given strings contains invalid characters
Definition: platform.cpp:502
add image(s) to a panorama
Definition: wxPanoCommand.h:50
functions for interaction with the hugin configuration file
platform/compiler specific stuff.
xrc handler for HTMLWindow
Definition: HtmlWindow.h:53
bool IsRawExtension(const wxString &testExt)
return true, if given extension is in list of known raw extension (comparision is case insensitive ...
Definition: platform.cpp:103
Definition of HTMLWindow class which supports opening external links in default web browser...
HuginBase::ImageCache::RequestPtr request
Definition: huginApp.h:58
wxString Components2Str(const HuginGraph::ImageGraph::Components &comp)
Definition: huginApp.cpp:83
Resources Definition.
Definition: huginApp.h:55
static void imageLoadedAsync(HuginBase::ImageCache::RequestPtr request, HuginBase::ImageCache::EntryPtr entry)
Queue up an image loaded event when an image has just loaded.
Definition: huginApp.cpp:682
wxLocale locale
locale for internationalisation
Definition: huginApp.h:142
bool CheckRawFiles()
return true, if all raw files are from the same camera
Definition: RawImport.cpp:649
void GetMonitorProfile(wxString &profileName, cmsHPROFILE &profile)
retrieve monitor profile from system
Definition: wxcms.cpp:201
int main(int argc, char *argv[])
Definition: Main.cpp:167