Hugin trunk 0.1
Loading...
Searching...
No Matches
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"
41
44#include "hugin/MainFrame.h"
47#include "hugin/PanoPanel.h"
48#include "hugin/ImagesPanel.h"
50#include "hugin/OptimizePanel.h"
52#include "hugin/PreviewFrame.h"
54#include "hugin/huginApp.h"
55#include "hugin/CPEditorPanel.h"
56#include "hugin/CPListFrame.h"
59#include "hugin/PanoOperation.h"
61
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
88class HuginSplashScreen : public wxFrame
89{
90public:
92 HuginSplashScreen(wxWindow* parent, wxBitmap bitmap) :
94 {
97 bitmap.SetScaleFactor(GetDPIScaleFactor());
101 SetClientSize(bitmap.GetWidth(), bitmap.GetHeight());
103 Show(true);
104 SetFocus();
105#if defined(__WXMSW__) || defined(__WXMAC__)
106 Update();
107#elif defined(__WXGTK20__)
108 //do nothing
109#else
111#endif
112 };
114};
115
117
118
120{
121 DEBUG_TRACE("OnDropFiles");
123 if (!mf) return false;
124
125 if (!m_imageOnly && filenames.GetCount() == 1) {
126 wxFileName file(filenames[0]);
127 if (file.GetExt().CmpNoCase("pto") == 0 ||
128 file.GetExt().CmpNoCase("ptp") == 0 ||
129 file.GetExt().CmpNoCase("pts") == 0 )
130 {
131 // load project
132 if (mf->CloseProject(true, MainFrame::LOAD_NEW_PROJECT))
133 {
134 mf->LoadProjectFile(file.GetFullPath());
135 // remove old images from cache
137 }
138 return true;
139 }
140 }
141
142 // try to add as images
143 std::vector<std::string> filesv;
144 std::vector<std::string> rawFilesv;
146 for (unsigned int i=0; i< filenames.GetCount(); i++) {
147 wxFileName file(filenames[i]);
148 // first check if raw file
149 // vigra::isImage reports also some raw files as image because
150 // technical some of them are tiff files
151 if (IsRawExtension(file.GetExt()))
152 {
154 {
155 invalidFiles.Add(file.GetFullPath());
156 }
157 else
158 {
159 rawFilesv.push_back((const char *)file.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
160 };
161 }
162 else
163 {
164 // now check if drop file is a image
165 if (vigra::isImage(file.GetFullPath().mb_str(HUGIN_CONV_FILENAME)))
166 {
168 {
169 invalidFiles.Add(file.GetFullPath());
170 }
171 else
172 {
173 filesv.push_back((const char *)filenames[i].mb_str(HUGIN_CONV_FILENAME));
174 };
175 };
176 };
177 }
178 // show warning about invalid file names
179 if (!invalidFiles.empty())
180 {
182 }
183 // we got some images to add.
184 if (!filesv.empty())
185 {
186 // use a Command to ensure proper undo and updating of GUI parts
187 wxBusyCursor();
188 if(pano.getNrOfCtrlPoints()>0)
189 {
191 }
192 else
193 {
194 std::vector<PanoCommand::PanoCommand*> cmds;
195 cmds.push_back(new PanoCommand::wxAddImagesCmd(pano, filesv));
196 cmds.push_back(new PanoCommand::DistributeImagesCmd(pano));
197 cmds.push_back(new PanoCommand::CenterPanoCmd(pano));
199 };
200 };
201 if (!rawFilesv.empty())
202 {
203 if (rawFilesv.size() == 1)
204 {
205 hugin_utils::MessageDialog message = hugin_utils::GetMessageDialog(_("You selected only one raw file. This is not recommended.\nAll raw files should be converted at once."),
206 _("Hugin"), wxICON_EXCLAMATION | wxOK | wxCANCEL, mf);
207 message->SetOKLabel(_("Convert anyway."));
208 if (message->ShowModal() != wxID_OK)
209 {
210 return true;
211 };
212 };
214 // check that raw files are from same camera and that all can be read
215 if (dlg.CheckRawFiles())
216 {
217 // now show dialog
218 if (dlg.ShowModal() == wxID_OK)
219 {
221 };
222 };
223 };
224 return true;
225}
226
227enum
228{
233
235 : cp_frame(0), pano(pano)
236{
237 preview_frame = 0;
239
240 bool disableOpenGL=false;
242 {
243 wxDialog dlg;
244 wxXmlResource::Get()->LoadDialog(&dlg, NULL, "disable_opengl_dlg");
245 long noOpenGL=wxConfigBase::Get()->Read("DisableOpenGL", 0l);
246 if(noOpenGL==1)
247 {
248 XRCCTRL(dlg, "disable_dont_ask_checkbox", wxCheckBox)->SetValue(true);
249 };
250 if(dlg.ShowModal()==wxID_OK)
251 {
252 if(XRCCTRL(dlg, "disable_dont_ask_checkbox", wxCheckBox)->IsChecked())
253 {
254 wxConfigBase::Get()->Write("DisableOpenGL", 1l);
255 }
256 else
257 {
258 wxConfigBase::Get()->Write("DisableOpenGL", 0l);
259 };
260 disableOpenGL=true;
261 }
262 else
263 {
264 wxConfigBase::Get()->Write("DisableOpenGL", 0l);
265 };
266 }
267 else
268 {
269 long noOpenGL=wxConfigBase::Get()->Read("DisableOpenGL", 0l);
271 };
272
273 wxBitmap bitmap;
275 wxYield();
276
277 if (bitmap.LoadFile(huginApp::Get()->GetXRCPath() + "data/splash.png", wxBITMAP_TYPE_PNG))
278 {
279 // embed package version into string.
280 {
282 dc.SelectObject(bitmap);
283#ifdef __WXMAC__
285#else
287#endif
288 dc.SetFont(font);
289 dc.SetTextForeground(*wxBLACK);
290 dc.SetTextBackground(*wxWHITE);
291 int tw, th;
294 dc.GetTextExtent(version, &tw, &th);
295 // place text on bitmap.
296 dc.DrawText(version, bitmap.GetWidth() - tw - 3, bitmap.GetHeight() - th - 3);
297 dc.SelectObject(wxNullBitmap);
298 }
299 splash = new HuginSplashScreen(NULL, bitmap);
300 } else {
301 wxLogFatalError(_("Fatal installation error\nThe file data/splash.png was not found at:") + huginApp::Get()->GetXRCPath());
302 abort();
303 }
304 //splash->Refresh();
305 wxYield();
306
307 // save our pointer
308 m_this = this;
309
310 DEBUG_TRACE("");
311 // load our children. some children might need special
312 // initialization. this will be done later.
313 wxXmlResource::Get()->LoadFrame(this, parent, "main_frame");
314 DEBUG_TRACE("");
315
316 // load our menu bar
317#ifdef __WXMAC__
318 wxApp::s_macAboutMenuItemId = XRCID("action_show_about");
319 wxApp::s_macPreferencesMenuItemId = XRCID("action_show_prefs");
320 wxApp::s_macExitMenuItemId = XRCID("action_exit_hugin");
321 wxApp::s_macHelpMenuTitleName = _("&Help");
322#endif
323 wxMenuBar* mainMenu=wxXmlResource::Get()->LoadMenuBar(this, "main_menubar");
324 m_menu_file_simple=wxXmlResource::Get()->LoadMenu("file_menu_simple");
325 m_menu_file_advanced=wxXmlResource::Get()->LoadMenu("file_menu_advanced");
326 mainMenu->Insert(0, m_menu_file_simple, _("&File"));
328 m_optOnlyActiveImages = (wxConfigBase::Get()->Read("/OptimizePanel/OnlyActiveImages", 1l) != 0);
329 m_optIgnoreLineCp = false;
330 // observe the panorama, this should be the first observer
331 pano.addObserver(this);
332
333#ifdef HUGIN_HSI
335 // the plugin menu will be generated dynamically
336 wxMenu *pluginMenu=new wxMenu();
337 // search for all .py files in plugins directory
338 wxDir dir(GetDataPath()+"plugins");
339 if (dir.IsOpened())
340 {
341 wxString filename;
342 bool cont = dir.GetFirst(&filename, "*.py", wxDIR_FILES | wxDIR_HIDDEN);
344 while (cont)
345 {
346 wxFileName file(dir.GetName(), filename);
347 file.MakeAbsolute();
348 PluginItem item(file);
349 if (item.IsAPIValid())
350 {
351 items.push_back(item);
352 };
353 cont = dir.GetNext(&filename);
354 };
356
358 for (PluginItems::const_iterator it = items.begin(); it != items.end(); ++it)
359 {
360 PluginItem item = *it;
361 int categoryID = pluginMenu->FindItem(item.GetCategory());
363 if (categoryID == wxNOT_FOUND)
364 {
365 categoryMenu = new wxMenu();
366 pluginMenu->AppendSubMenu(categoryMenu, item.GetCategory());
367 }
368 else
369 {
370 categoryMenu = pluginMenu->FindItem(categoryID)->GetSubMenu();
371 };
372 categoryMenu->Append(pluginID, item.GetName(), item.GetDescription());
373 m_plugins[pluginID] = item.GetFilename();
374 Bind(wxEVT_MENU, &MainFrame::OnPlugin, this, pluginID);
375 pluginID++;
376 };
377 // show the new menu
378 if (pluginMenu->GetMenuItemCount() > 0)
379 {
380 menubar->Insert(menubar->GetMenuCount() - 2, pluginMenu, _("&Actions"));
381 };
382 };
383#else
384 GetMenuBar()->Enable(XRCID("action_python_script"), false);
385#endif
386
387 // create tool bar
388 SetToolBar(wxXmlResource::Get()->LoadToolBar(this, "main_toolbar"));
389
390 // Disable tools by default
391 enableTools(false);
392
393 // put an "unknown" object in an xrc file and
394 // take as wxObject (second argument) the return value of wxXmlResource::Get
395 // finish the images_panel
396 DEBUG_TRACE("");
397
398 // image_panel
399 images_panel = XRCCTRL(*this, "images_panel_unknown", ImagesPanel);
402 DEBUG_TRACE("");
403
404 m_notebook = XRCCTRL((*this), "controls_notebook", wxNotebook);
405// m_notebook = ((wxNotebook*) ((*this).FindWindow(XRCID("controls_notebook"))));
406// m_notebook = ((wxNotebook*) (FindWindow(XRCID("controls_notebook"))));
408
409 // the mask panel
410 mask_panel = XRCCTRL(*this, "mask_panel_unknown", MaskEditorPanel);
413
414 // the pano_panel
415 DEBUG_TRACE("");
416 pano_panel = XRCCTRL(*this, "panorama_panel_unknown", PanoPanel);
419 pano_panel->panoramaChanged (pano); // initialize from pano
420
421 cpe = XRCCTRL(*this, "cp_editor_panel_unknown", CPEditorPanel);
422 assert(cpe);
423 cpe->Init(&pano);
424
425 opt_panel = XRCCTRL(*this, "optimizer_panel_unknown", OptimizePanel);
428 m_show_opt_panel=true;
429
430 opt_photo_panel = XRCCTRL(*this, "optimizer_photometric_panel_unknown", OptimizePhotometricPanel);
434
435 // generate list of most recently uses files and add it to menu
436 // needs to be initialized before the fast preview, there we call AddFilesToMenu()
437 wxConfigBase * config=wxConfigBase::Get();
438 m_mruFiles.Load(*config);
439 m_mruFiles.UseMenu(m_menu_file_advanced->FindItem(XRCID("menu_mru"))->GetSubMenu());
440
441 preview_frame = new PreviewFrame(this, pano);
442 if(disableOpenGL)
443 {
446 m_mruFiles.AddFilesToMenu();
447 }
448 else
449 {
451 };
452
453 // add saved user defined output sequences
454 {
455 wxArrayString files;
456 // search all .executor files, do not follow links
457 wxDir::GetAllFiles(GetDataPath()+"output", &files, "*.executor", wxDIR_FILES | wxDIR_HIDDEN | wxDIR_NO_FOLLOW);
458 const size_t nrAllUserSequences = files.size();
459 wxDir::GetAllFiles(hugin_utils::GetUserAppDataDir(), &files, "*.executor", wxDIR_FILES | wxDIR_HIDDEN | wxDIR_NO_FOLLOW);
460 if (!files.IsEmpty())
461 {
462 // we found some files
464 int outputMenuId=mainMenu->FindMenu(_("&Output"));
466 {
468 size_t i = 0;
469 for (auto file : files)
470 {
471 if (i > 0 && i == nrAllUserSequences && outputSequencesMenu->GetMenuItemCount() > 0)
472 {
473 outputSequencesMenu->AppendSeparator();
475 {
476 // add assistant to context menu on align button
478 };
479
480 };
482 if (inputStream.IsOk())
483 {
484 // read descriptions from file
488 if (help.IsEmpty())
489 {
490 help = wxString::Format(_("User defined sequence: %s"), file);
491 };
492 // add menu
493 if (!desc.IsEmpty())
494 {
495 outputSequencesMenu->Append(outputId, desc, help);
497 m_userOutput[outputId] = file;
499 {
500 // add output sequence to context menu on create button
502 };
503 ++outputId;
504 };
505 };
506 i++;
507 };
508 if ((outputSequencesMenu->GetMenuItemCount() == 1 && !(outputSequencesMenu->FindItemByPosition(0)->IsSeparator())) ||
509 outputSequencesMenu->GetMenuItemCount() > 1)
510 {
511 m_outputUserMenu = mainMenu->GetMenu(outputMenuId)->AppendSubMenu(outputSequencesMenu, _("User defined output sequences"));
512 }
513 else
514 {
515 delete outputSequencesMenu;
516 };
517 };
518 };
519 };
520 // add saved user defined assistants
521 {
522 wxArrayString files;
523 // search all .assistant files, do not follow links
524 wxDir::GetAllFiles(GetDataPath() + "assistant", &files, "*.assistant", wxDIR_FILES | wxDIR_HIDDEN | wxDIR_NO_FOLLOW);
525 const size_t nrAllUserSequences = files.size();
526 wxDir::GetAllFiles(hugin_utils::GetUserAppDataDir(), &files, "*.assistant", wxDIR_FILES | wxDIR_HIDDEN | wxDIR_NO_FOLLOW);
527 if (!files.IsEmpty())
528 {
529 // we found some files
531 const int editMenuId = mainMenu->FindMenu(_("&Edit"));
532 if (editMenuId != wxNOT_FOUND)
533 {
535 size_t i = 0;
536 for (auto file : files)
537 {
538 if (i > 0 && i == nrAllUserSequences && userAssistantMenu->GetMenuItemCount() > 0)
539 {
540 userAssistantMenu->AppendSeparator();
542 {
543 // add assistant to context menu on align button
545 };
546 };
548 if (inputStream.IsOk())
549 {
550 // read descriptions from file
554 help = help.Trim(true).Trim(false);
555 if (help.IsEmpty())
556 {
557 help = wxString::Format(_("User defined assistant: %s"), file);
558 };
559 // add menu
560 if (!desc.IsEmpty())
561 {
562 userAssistantMenu->Append(assistantId, desc, help);
566 {
567 // add assistant to context menu on align button
569 };
570 ++assistantId;
571 };
572 };
573 i++;
574 };
575 if (userAssistantMenu->GetMenuItemCount() > 0)
576 {
577 m_assistantUserMenu = mainMenu->GetMenu(editMenuId)->Insert(5, wxID_ANY, _("User defined assistant"), userAssistantMenu);
578 }
579 else
580 {
581 delete userAssistantMenu;
582 };
583 };
584 };
585 };
586
587
588 // set the minimize icon
589#ifdef __WXMSW__
590 wxIconBundle myIcons(GetXRCPath() + "data/hugin.ico", wxBITMAP_TYPE_ICO);
592#else
593 wxIcon myIcon(GetXRCPath() + "data/hugin.png",wxBITMAP_TYPE_PNG);
595#endif
596
597 // create a new drop handler. wxwindows deletes the automaticall
599 DEBUG_TRACE("");
600
602
603 // create a status bar
604 const int fields (2);
606 int widths[fields] = {-1, 85};
608 SetStatusText(_("Started"), 0);
609 wxYield();
610 DEBUG_TRACE("");
611
612 // Set sizing characteristics
613 //set minumum size
614#if defined __WXMAC__ || defined __WXMSW__
615 // a minimum nice looking size; smaller than this would clutter the layout.
616 SetSizeHints(900, 675);
617#else
618 // For ASUS eeePc
619 SetSizeHints(780, 455); //set minumum size
620#endif
621
622 // set progress display for image cache.
623 ImageCache::getInstance().setProgressDisplay(this);
624
625 if(splash) {
626 splash->Close();
627 delete splash;
628 }
629 wxYield();
630
631 // disable automatic Layout() calls, to it by hand
632 SetAutoLayout(false);
634
635// By using /SUBSYSTEM:CONSOLE /ENTRY:"WinMainCRTStartup" in the linker
636// options for the debug build, a console window will be used for stdout
637// and stderr. No need to redirect to a file. Better security since we can't
638// guarantee that c: exists and writing a file to the root directory is
639// never a good idea. release build still uses /SUBSYSTEM:WINDOWS
640
641#if 0
642#ifdef DEBUG
643#ifdef __WXMSW__
644
645 freopen("c:\\hugin_stdout.txt", "w", stdout); // redirect stdout to file
646 freopen("c:\\hugin_stderr.txt", "w", stderr); // redirect stderr to file
647#endif
648#endif
649#endif
650 //reload gui level
652 long guiLevel=config->Read("/GuiLevel",(long)0);
653 guiLevel = std::max<long>(0, std::min<long>(2, guiLevel));
655 {
657 };
658 SetGuiLevel(static_cast<GuiLevel>(guiLevel));
659
660#ifndef __WXMSW__
661 // check settings of help window and fix when needed
663#endif
664 // bind handler for menu items
665 Bind(wxEVT_MENU, &MainFrame::OnNewProject, this, XRCID("action_new_project"));
666 Bind(wxEVT_MENU, &MainFrame::OnLoadProject, this, XRCID("action_load_project"));
667 Bind(wxEVT_MENU, &MainFrame::OnBrowseProjects, this, XRCID("action_browse_projects"));
668 Bind(wxEVT_MENU, &MainFrame::OnSaveProject, this, XRCID("action_save_project"));
669 Bind(wxEVT_MENU, &MainFrame::OnSaveProjectAs, this, XRCID("action_save_as_project"));
670 Bind(wxEVT_MENU, &MainFrame::OnSavePTStitcherAs, this, XRCID("action_save_as_ptstitcher"));
671 Bind(wxEVT_MENU, &MainFrame::OnOpenPTBatcher, this, XRCID("action_open_batch_processor"));
672 Bind(wxEVT_MENU, &MainFrame::OnMergeProject, this, XRCID("action_import_project"));
673 Bind(wxEVT_MENU, &MainFrame::OnReadPapywizard, this, XRCID("action_import_papywizard"));
674 Bind(wxEVT_MENU, &MainFrame::OnApplyTemplate, this, XRCID("action_apply_template"));
675 Bind(wxEVT_MENU, &MainFrame::OnUserQuit, this, XRCID("action_exit_hugin"));
676 for (int i = 0; i < 9; ++i)
677 {
679 }
680 Bind(wxEVT_MENU, &MainFrame::OnAbout, this, XRCID("action_show_about"));
681 Bind(wxEVT_MENU, &MainFrame::OnHelp, this, XRCID("action_show_help"));
682 Bind(wxEVT_MENU, &MainFrame::OnTipOfDay, this, XRCID("action_show_tip"));
683 Bind(wxEVT_MENU, &MainFrame::OnKeyboardHelp, this, XRCID("action_show_shortcuts"));
684 Bind(wxEVT_MENU, &MainFrame::OnFAQ, this, XRCID("action_show_faq"));
685 Bind(wxEVT_MENU, &MainFrame::OnShowPrefs, this, XRCID("action_show_prefs"));
686 Bind(wxEVT_MENU, &MainFrame::OnRunAssistant, this, XRCID("action_assistant"));
687 Bind(wxEVT_MENU, &MainFrame::OnSendToAssistantQueue, this, XRCID("action_batch_assistant"));
688 Bind(wxEVT_MENU, &MainFrame::OnSetGuiSimple, this, XRCID("action_gui_simple"));
689 Bind(wxEVT_MENU, &MainFrame::OnSetGuiAdvanced, this, XRCID("action_gui_advanced"));
690 Bind(wxEVT_MENU, &MainFrame::OnSetGuiExpert, this, XRCID("action_gui_expert"));
691#ifdef HUGIN_HSI
692 Bind(wxEVT_MENU, &MainFrame::OnPythonScript, this, XRCID("action_python_script"));
693#endif
694 Bind(wxEVT_MENU, &MainFrame::OnUndo, this, XRCID("ID_EDITUNDO"));
695 Bind(wxEVT_MENU, &MainFrame::OnRedo, this, XRCID("ID_EDITREDO"));
696 Bind(wxEVT_MENU, &MainFrame::OnFullScreen, this, XRCID("ID_SHOW_FULL_SCREEN"));
697 Bind(wxEVT_MENU, &MainFrame::OnTogglePreviewFrame, this, XRCID("ID_SHOW_PREVIEW_FRAME"));
698 Bind(wxEVT_MENU, &MainFrame::OnToggleGLPreviewFrame, this, XRCID("ID_SHOW_GL_PREVIEW_FRAME"));
699 Bind(wxEVT_BUTTON, &MainFrame::OnTogglePreviewFrame, this, XRCID("ID_SHOW_PREVIEW_FRAME"));
700 Bind(wxEVT_BUTTON, &MainFrame::OnToggleGLPreviewFrame, this, XRCID("ID_SHOW_GL_PREVIEW_FRAME"));
701
702 Bind(wxEVT_MENU, &MainFrame::OnOptimize, this, XRCID("action_optimize"));
703 Bind(wxEVT_MENU, &MainFrame::OnOnlyActiveImages, this, XRCID("action_optimize_only_active"));
704 Bind(wxEVT_MENU, &MainFrame::OnIgnoreLineCp, this, XRCID("action_optimize_ignore_line_cp"));
705 Bind(wxEVT_BUTTON, &MainFrame::OnOptimize, this, XRCID("action_optimize"));
706 Bind(wxEVT_MENU, &MainFrame::OnFineTuneAll, this, XRCID("action_finetune_all_cp"));
707 Bind(wxEVT_MENU, &MainFrame::OnRemoveCPinMasks, this, XRCID("action_remove_cp_in_masks"));
708
709 Bind(wxEVT_MENU, &MainFrame::OnShowCPFrame, this, XRCID("ID_CP_TABLE"));
710 Bind(wxEVT_BUTTON, &MainFrame::OnShowCPFrame, this, XRCID("ID_CP_TABLE"));
711
712 Bind(wxEVT_MENU, &MainFrame::OnShowPanel, this, XRCID("ID_SHOW_PANEL_IMAGES"));
713 Bind(wxEVT_MENU, &MainFrame::OnShowPanel, this, XRCID("ID_SHOW_PANEL_MASK"));
714 Bind(wxEVT_MENU, &MainFrame::OnShowPanel, this, XRCID("ID_SHOW_PANEL_CP_EDITOR"));
715 Bind(wxEVT_MENU, &MainFrame::OnShowPanel, this, XRCID("ID_SHOW_PANEL_OPTIMIZER"));
716 Bind(wxEVT_MENU, &MainFrame::OnShowPanel, this, XRCID("ID_SHOW_PANEL_OPTIMIZER_PHOTOMETRIC"));
717 Bind(wxEVT_MENU, &MainFrame::OnShowPanel, this, XRCID("ID_SHOW_PANEL_PANORAMA"));
718 Bind(wxEVT_MENU, &MainFrame::OnDoStitch, this, XRCID("action_stitch"));
719 Bind(wxEVT_MENU, &MainFrame::OnUserDefinedStitch, this, XRCID("action_stitch_userdefined"));
720 Bind(wxEVT_MENU, &MainFrame::OnAddImages, this, XRCID("action_add_images"));
721 Bind(wxEVT_BUTTON, &MainFrame::OnAddImages, this, XRCID("action_add_images"));
722 Bind(wxEVT_MENU, &MainFrame::OnAddTimeImages, this, XRCID("action_add_time_images"));
723 Bind(wxEVT_BUTTON, &MainFrame::OnAddTimeImages, this, XRCID("action_add_time_images"));
725 Bind(wxEVT_SIZE, &MainFrame::OnSize, this);
727
728 DEBUG_TRACE("");
729}
730
732{
733 DEBUG_TRACE("dtor");
735 {
737 }
738 else
739 {
740 delete m_menu_file_simple;
741 };
742 ImageCache::getInstance().setProgressDisplay(NULL);
743 delete & ImageCache::getInstance();
745// delete cpe;
746// delete images_panel;
747 DEBUG_DEBUG("removing observer");
748 pano.removeObserver(this);
749
750 // get the global config object
751 wxConfigBase* config = wxConfigBase::Get();
752
753 hugin_utils::StoreFramePosition(this, "MainFrame");
754
755 //store most recently used files
756 m_mruFiles.Save(*config);
757 //store gui level
758 config->Write("/GuiLevel",(long)m_guiLevel);
759 // store optimize only active images
760 config->Write("/OptimizePanel/OnlyActiveImages", m_optOnlyActiveImages ? 1l : 0l);
761
762 config->Flush();
763 if(svmModel!=NULL)
764 {
766 };
768
769 DEBUG_TRACE("dtor end");
770}
771
773{
774 // set flag to indicate list should show correlation instead of error
775 if (m_showCorrelation == 2)
776 {
778 if (!(lastCommand == "remove control point" || lastCommand == "remove control points"))
779 {
781 };
782 };
783 if (m_showCorrelation == 1)
784 {
786 };
790 theMenuBar->Enable (XRCID("ID_EDITUNDO"), can_undo);
791 theToolBar->EnableTool(XRCID("ID_EDITUNDO"), can_undo);
793 theMenuBar->Enable (XRCID("ID_EDITREDO"), can_redo);
794 theToolBar->EnableTool(XRCID("ID_EDITREDO"), can_redo);
795
796 //show or hide optimizer and exposure optimizer tab depending on optimizer master switches
798 {
799 m_notebook->InsertPage(3, opt_panel, _("Optimizer"));
800 m_show_opt_panel=true;
801 };
803 {
804 m_notebook->RemovePage(3);
805 m_show_opt_panel=false;
806 };
808 {
810 {
811 m_notebook->InsertPage(4, opt_photo_panel, _("Exposure"));
812 }
813 else
814 {
815 m_notebook->InsertPage(3, opt_photo_panel, _("Exposure"));
816 }
818 };
820 {
822 {
823 m_notebook->RemovePage(4);
824 }
825 else
826 {
827 m_notebook->RemovePage(3);
828 };
830 };
831 theMenuBar->Enable(XRCID("ID_SHOW_PANEL_OPTIMIZER"), m_show_opt_panel);
832 theMenuBar->Enable(XRCID("ID_SHOW_PANEL_OPTIMIZER_PHOTOMETRIC"), m_show_opt_photo_panel);
833}
834
835//void MainFrame::panoramaChanged(HuginBase::Panorama &panorama)
842
843void MainFrame::OnUserQuit(wxCommandEvent & e)
844{
845 Close();
846}
847
849{
850 if (pano.isDirty()) {
852 switch (reason)
853 {
854 case LOAD_NEW_PROJECT:
855 messageString = _("Save changes to the project file before opening another project?");
856 break;
857 case NEW_PROJECT:
858 messageString = _("Save changes to the project file before starting a new project?");
859 break;
860 case CLOSE_PROGRAM:
861 default:
862 messageString = _("Save changes to the project file before closing?");
863 break;
864 };
866 switch(reason)
867 {
868 case LOAD_NEW_PROJECT:
869 message->SetExtendedMessage(_("If you load another project without saving, your changes since last save will be discarded."));
870 break;
871 case NEW_PROJECT:
872 message->SetExtendedMessage(_("If you start a new project without saving, your changes since last save will be discarded."));
873 break;
874 case CLOSE_PROGRAM:
875 default:
876 message->SetExtendedMessage(_("If you close without saving, your changes since your last save will be discarded."));
877 break;
878 };
879 #if defined __WXMAC__ || defined __WXMSW__
880 // Apple human interface guidelines and Windows user experience interaction guidelines
881 message->SetYesNoLabels(wxID_SAVE, _("Do&n't Save"));
882 #else
883 // Gnome human interface guidelines:
884 message->SetYesNoLabels(wxID_SAVE, _("&Close without saving"));
885 #endif
886 const int answer = message->ShowModal();
887 switch (answer)
888 {
889 case wxID_YES:
890 {
891 wxCommandEvent dummy;
893 return !pano.isDirty();
894 }
895 case wxID_CANCEL:
896 return false;
897 default: //no save
898 return true;
899 }
900 }
901 else return true;
902}
903
905{
906 DEBUG_TRACE("");
908 {
909 if(!CloseProject(e.CanVeto(), CLOSE_PROGRAM))
910 {
911 if (e.CanVeto())
912 {
913 e.Veto();
914 return;
915 }
916 wxLogError(_("forced close"));
917 }
918 }
919 else
920 {
921 if(e.CanVeto())
922 {
923 Hide();
924 e.Veto();
925 return;
926 };
927 };
928
929 if(preview_frame)
930 {
931 preview_frame->Close(true);
932 }
934 {
936 {
938 }
939 else
940 {
941 gl_preview_frame->Close(true);
942 };
943 }
944
945 ImageCache::getInstance().flush();
946 Destroy();
947 DEBUG_TRACE("");
948}
949
950void MainFrame::OnSaveProject(wxCommandEvent & e)
951{
952 DEBUG_TRACE("");
953 try {
955 if (m_filename == wxEmptyString) {
958 } else {
959 // the project file is just a PTOptimizer script...
960 DEBUG_DEBUG("stripping " << path << " from image filenames");
961 const std::string script(scriptName.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
963
964 SetStatusText(wxString::Format(_("saved project %s"), m_filename.c_str()),0);
966 {
968 {
969 gl_preview_frame->SetTitle(scriptName.GetName() + "." + scriptName.GetExt() + " - " + _("Hugin - Panorama Creator"));
970 };
971 SetTitle(scriptName.GetName() + "." + scriptName.GetExt() + " - " + _("Panorama editor"));
972 }
973 else
974 {
975 SetTitle(scriptName.GetName() + "." + scriptName.GetExt() + " - " + _("Hugin - Panorama Creator"));
976 };
977
979 }
980 } catch (std::exception & e) {
981 wxString err(e.what(), wxConvLocal);
982 hugin_utils::HuginMessageBox(wxString::Format(_("Could not save project file \"%s\".\nMaybe the file or the folder is read-only.\n\n(Error code: %s)"),m_filename,err),
983 _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
984 }
985}
986
987void MainFrame::OnSaveProjectAs(wxCommandEvent & e)
988{
989 DEBUG_TRACE("");
991 if (m_filename.IsEmpty())
992 {
993 scriptName.Assign(getDefaultProjectName(pano) + ".pto");
994 }
995 else
996 {
998 };
1001 _("Save project file"),
1002 scriptName.GetPath(), scriptName.GetFullName(),
1003 _("Project files (*.pto)|*.pto|All files (*)|*"),
1005 if (dlg.ShowModal() == wxID_OK) {
1006 wxConfig::Get()->Write("/actualPath", dlg.GetDirectory()); // remember for later
1007 wxString fn = dlg.GetPath();
1008 if (fn.Right(4).CmpNoCase(".pto")!=0)
1009 {
1010 fn.Append(".pto");
1011 if (wxFile::Exists(fn)) {
1013 {
1014 return;
1015 }
1016 }
1017 }
1018 m_filename = fn;
1019 m_mruFiles.AddFileToHistory(m_filename);
1020 OnSaveProject(e);
1021 }
1022}
1023
1024void MainFrame::OnSavePTStitcherAs(wxCommandEvent & e)
1025{
1026 DEBUG_TRACE("");
1028 if (m_filename == wxEmptyString) {
1030 }
1032 wxString fn = scriptNameFN.GetName() + ".txt";
1034 _("Save PTmender script file"),
1035 wxConfigBase::Get()->Read("/actualPath",wxEmptyString), fn,
1036 _("PTmender files (*.txt)|*.txt"),
1038 if (dlg.ShowModal() == wxID_OK) {
1039 wxString fname = dlg.GetPath();
1040 // the project file is just a PTStitcher script...
1043 if (pano.getNrOfImages() > 0) {
1044 fill_set(all, 0, pano.getNrOfImages()-1);
1045 }
1046 std::ofstream script(scriptName.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
1048 script.close();
1049 }
1050
1051}
1052
1054{
1055 DEBUG_TRACE("");
1056
1057 // remove old images from cache
1058 // hmm probably not a good idea, if the project is reloaded..
1059 // ImageCache::getInstance().flush();
1060
1061 SetStatusText( _("Open project: ") + filename);
1062
1063 wxFileName fname(filename);
1065 if (fname.IsOk() && fname.FileExists())
1066 {
1067 m_filename = filename;
1071 new PanoCommand::wxLoadPTProjectCmd(pano, (const char *)filename.mb_str(HUGIN_CONV_FILENAME), (const char *)path.mb_str(HUGIN_CONV_FILENAME), true)
1072 );
1073 if (!PanoCommand::GlobalCmdHist::getInstance().getLastCommand()->wasSuccessful())
1074 {
1075 hugin_utils::HuginMessageBox(wxString::Format(_("Could not load project file \"%s\".\nIt is not a valid pto file."), filename), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
1079 return;
1080 };
1083 DEBUG_DEBUG("project contains " << pano.getNrOfImages() << " after load");
1086 {
1088 };
1089 if (pano.getNrOfImages() > 0)
1090 {
1091 SetStatusText(_("Project opened"));
1092 m_mruFiles.AddFileToHistory(fname.GetFullPath());
1093 if (m_guiLevel == GUI_SIMPLE)
1094 {
1095 if (gl_preview_frame)
1096 {
1097 gl_preview_frame->SetTitle(fname.GetName() + "." + fname.GetExt() + " - " + _("Hugin - Panorama Stitcher"));
1098 };
1099 SetTitle(fname.GetName() + "." + fname.GetExt() + " - " + _("Panorama editor"));
1100 }
1101 else
1102 {
1103 SetTitle(fname.GetName() + "." + fname.GetExt() + " - " + _("Hugin - Panorama Stitcher"));
1104 };
1105 }
1106 else
1107 {
1108 SetStatusText(_("Loading canceled"));
1109 m_filename = "";
1110 if (m_guiLevel == GUI_SIMPLE)
1111 {
1112 if (gl_preview_frame)
1113 {
1114 gl_preview_frame->SetTitle(_("Hugin - Panorama Stitcher"));
1115 };
1116 SetTitle(_("Panorama editor"));
1117 }
1118 else
1119 {
1120 SetTitle(_("Hugin - Panorama Stitcher"));
1121 };
1122 };
1123 if (! (fname.GetExt() == "pto")) {
1124 // do not remember filename if its not a hugin project
1125 // to avoid overwriting the original project with an
1126 // incompatible one
1128 }
1129 // get the global config object
1130 wxConfigBase* config = wxConfigBase::Get();
1131 config->Write("/actualPath", path); // remember for later
1132 } else {
1133 SetStatusText( _("Error opening project: ") + filename);
1134 DEBUG_ERROR("Could not open file " << filename);
1135 }
1136
1137 // force update of preview window
1138 if ( !(preview_frame->IsIconized() ||(! preview_frame->IsShown()) ) ) {
1139 wxCommandEvent dummy;
1141 };
1142 if (gl_preview_frame)
1143 {
1145 };
1146}
1147
1148#ifdef __WXMAC__
1149void MainFrame::MacOnOpenFile(const wxString & filename)
1150{
1151 if(!CloseProject(true, LOAD_NEW_PROJECT)) return; //if closing old project is canceled do nothing.
1152
1153 ImageCache::getInstance().flush();
1154 LoadProjectFile(filename);
1155}
1156#endif
1157
1158void MainFrame::OnLoadProject(wxCommandEvent & e)
1159{
1160 DEBUG_TRACE("");
1161
1162 if(CloseProject(true, LOAD_NEW_PROJECT)) //if closing old project is canceled do nothing.
1163 {
1164 // get the global config object
1165 wxConfigBase* config = wxConfigBase::Get();
1166
1167 wxString defaultdir = config->Read("/actualPath",wxEmptyString);
1169 _("Open project file"),
1171 _("Project files (*.pto)|*.pto|All files (*)|*"),
1173 dlg.SetDirectory(defaultdir);
1174 if (dlg.ShowModal() == wxID_OK)
1175 {
1176 wxString filename = dlg.GetPath();
1177 if(vigra::isImage(filename.mb_str(HUGIN_CONV_FILENAME)))
1178 {
1179 if (hugin_utils::HuginMessageBox(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()),
1181 {
1183 filenameArray.Add(filename);
1185 };
1186 return;
1187 }
1188 else
1189 {
1190 // remove old images from cache
1191 ImageCache::getInstance().flush();
1192
1193 LoadProjectFile(filename);
1194 return;
1195 };
1196 }
1197 }
1198 // do not close old project
1199 // nothing to open
1200 SetStatusText( _("Open project: cancel"));
1201}
1202
1203void MainFrame::OnBrowseProjects(wxCommandEvent& e)
1204{
1205 // first check if there are unsaved changes
1206 if (CloseProject(true, LOAD_NEW_PROJECT))
1207 {
1208 // remove old images from cache
1209 ImageCache::getInstance().flush();
1210 // get the global config object
1211 wxConfigBase* config = wxConfigBase::Get();
1212 // show dialog
1213 BrowsePTOFilesDialog dialog(this, config->Read("/actualPath", ""));
1214 if (dialog.ShowModal() == wxID_OK)
1215 {
1216 // open newly selected file
1217 LoadProjectFile(dialog.GetSelectedProject());
1218 // remember path for later
1219 config->Write("/actualPath", dialog.GetSelectedPath());
1220 };
1221 };
1222}
1223
1224void MainFrame::OnNewProject(wxCommandEvent & e)
1225{
1226 if(!CloseProject(true, NEW_PROJECT)) return; //if closing current project is canceled
1227
1231 // remove old images from cache
1232 ImageCache::getInstance().flush();
1234 {
1236 {
1237 gl_preview_frame->SetTitle(_("Hugin - Panorama Stitcher"));
1238 };
1239 SetTitle(_("Panorama editor"));
1240 }
1241 else
1242 {
1243 SetTitle(_("Hugin - Panorama Stitcher"));
1244 };
1245
1246 wxCommandEvent dummy;
1248 if (gl_preview_frame)
1249 {
1251 };
1252}
1253
1254void MainFrame::OnAddImages( wxCommandEvent& event )
1255{
1256 DEBUG_TRACE("");
1258 HuginBase::UIntSet images;
1260 if(cmd!=NULL)
1261 {
1263 };
1264
1265 DEBUG_TRACE("");
1266}
1267
1269{
1271 for(unsigned int i=0;i<filenameArray.GetCount(); i++)
1272 {
1274 {
1276 };
1277 };
1278 if(!invalidFiles.empty())
1279 {
1281 }
1282 else
1283 {
1284 std::vector<std::string> filesv;
1285 for (unsigned int i=0; i< filenameArray.GetCount(); i++) {
1286 filesv.push_back((const char *)filenameArray[i].mb_str(HUGIN_CONV_FILENAME));
1287 }
1288
1289 // we got some images to add.
1290 if (!filesv.empty()) {
1291 // use a Command to ensure proper undo and updating of GUI
1292 // parts
1293 wxBusyCursor();
1296 );
1297 };
1298 };
1299};
1300
1311
1312void MainFrame::OnShowPanel(wxCommandEvent & e)
1313{
1314 if(e.GetId()==XRCID("ID_SHOW_PANEL_MASK"))
1315 m_notebook->SetSelection(1);
1316 else
1317 if(e.GetId()==XRCID("ID_SHOW_PANEL_CP_EDITOR"))
1318 m_notebook->SetSelection(2);
1319 else
1320 if(e.GetId()==XRCID("ID_SHOW_PANEL_OPTIMIZER"))
1321 m_notebook->SetSelection(3);
1322 else
1323 if(e.GetId()==XRCID("ID_SHOW_PANEL_OPTIMIZER_PHOTOMETRIC"))
1324 {
1326 {
1327 m_notebook->SetSelection(4);
1328 }
1329 else
1330 {
1331 m_notebook->SetSelection(3);
1332 };
1333 }
1334 else
1335 if(e.GetId()==XRCID("ID_SHOW_PANEL_PANORAMA"))
1336 {
1338 {
1339 m_notebook->SetSelection(5);
1340 }
1341 else
1342 {
1344 {
1345 m_notebook->SetSelection(4);
1346 }
1347 else
1348 {
1349 m_notebook->SetSelection(3);
1350 };
1351 };
1352 }
1353 else
1354 m_notebook->SetSelection(0);
1355}
1356
1357void MainFrame::OnLoadingFailed(wxCommandEvent & e)
1358{
1359 // check if file exists
1360 if (wxFileExists(e.GetString()))
1361 {
1362 // file exists, but could not loaded
1363 hugin_utils::HuginMessageBox(wxString::Format(_("Could not load image \"%s\".\nThis file is not a valid image.\nThis file will be removed from the project."), e.GetString()),
1364 _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
1365 }
1366 else
1367 {
1368 // file does not exists
1369 hugin_utils::HuginMessageBox(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()),
1370 _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
1371 };
1372 // now remove the file from the pano
1373 const std::string filename(e.GetString().mb_str(HUGIN_CONV_FILENAME));
1375 for (size_t i = 0; i < pano.getNrOfImages(); ++i)
1376 {
1377 if (pano.getImage(i).getFilename() == filename)
1378 {
1379 imagesToRemove.insert(i);
1380 };
1381 };
1382 if (!imagesToRemove.empty())
1383 {
1385 };
1386}
1387
1388
1389void MainFrame::OnAbout(wxCommandEvent & e)
1390{
1392 dlg.ShowModal();
1393}
1394
1395/*
1396void MainFrame::OnAbout(wxCommandEvent & e)
1397{
1398 DEBUG_TRACE("");
1399 wxDialog dlg;
1400 wxString strFile;
1401 wxString langCode;
1402
1403 wxXmlResource::Get()->LoadDialog(&dlg, this, "about_dlg");
1404
1405#if __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
1406 //rely on the system's locale choice
1407 strFile = MacGetPathToBundledResourceFile(CFSTR("about.htm"));
1408 if(strFile!=wxEmptyString) XRCCTRL(dlg,"about_html",wxHtmlWindow)->LoadPage(strFile);
1409#else
1410 //if the language is not default, load custom About file (if exists)
1411 langCode = huginApp::Get()->GetLocale().GetName().Left(2).Lower();
1412 DEBUG_INFO("Lang Code: " << langCode.mb_str(wxConvLocal));
1413 if(langCode != wxString("en"))
1414 {
1415 strFile = GetXRCPath() + "data/about_" + langCode + ".htm";
1416 if(wxFile::Exists(strFile))
1417 {
1418 DEBUG_TRACE("Using About: " << strFile.mb_str(wxConvLocal));
1419 XRCCTRL(dlg,"about_html",wxHtmlWindow)->LoadPage(strFile);
1420 }
1421 }
1422#endif
1423 dlg.ShowModal();
1424}
1425*/
1426
1427void MainFrame::OnHelp(wxCommandEvent & e)
1428{
1429 DisplayHelp();
1430}
1431
1432void MainFrame::OnKeyboardHelp(wxCommandEvent & e)
1433{
1434 DisplayHelp("Hugin_Keyboard_shortcuts.html");
1435}
1436
1437void MainFrame::OnFAQ(wxCommandEvent & e)
1438{
1439 DisplayHelp("Hugin_FAQ.html");
1440}
1441
1442
1444{
1445 if (section.IsEmpty())
1446 {
1447 GetHelpController().DisplayContents();
1448 }
1449 else
1450 {
1451 GetHelpController().DisplaySection(section);
1452 };
1453}
1454
1455void MainFrame::OnTipOfDay(wxCommandEvent& WXUNUSED(e))
1456{
1458 bool bShowAtStartup;
1459// DGSW FIXME - Unreferenced
1460// bool bTipsExist = false;
1461 int nValue;
1462
1463 wxConfigBase * config = wxConfigBase::Get();
1464 nValue = config->Read("/MainFrame/ShowStartTip",1l);
1465
1466 //TODO: tips not localisable
1467 DEBUG_INFO("Tip index: " << nValue);
1468 strFile = GetXRCPath() + "data/tips.txt"; //load default file
1469
1470 DEBUG_INFO("Reading tips from " << strFile.mb_str(wxConvLocal));
1471 wxTipProvider *tipProvider = new LocalizedFileTipProvider(strFile, nValue);
1473
1474 //store startup preferences
1475 nValue = (bShowAtStartup ? tipProvider->GetCurrentTip() : 0);
1476 DEBUG_INFO("Writing tip index: " << nValue);
1477 config->Write("/MainFrame/ShowStartTip", nValue);
1478 delete tipProvider;
1479}
1480
1481
1482void MainFrame::OnShowPrefs(wxCommandEvent & e)
1483{
1484 DEBUG_TRACE("");
1486 pref_dlg.ShowModal();
1487 //update image cache size
1488 wxConfigBase* cfg=wxConfigBase::Get();
1492 {
1493 gl_preview_frame->SetShowProjectionHints(cfg->Read("/GLPreviewFrame/ShowProjectionHints",HUGIN_SHOW_PROJECTION_HINTS)!=0);
1494 };
1495}
1496
1497void MainFrame::OnTogglePreviewFrame(wxCommandEvent & e)
1498{
1499 DEBUG_TRACE("");
1500 if (preview_frame->IsIconized()) {
1501 preview_frame->Iconize(false);
1502 }
1503 preview_frame->Show();
1504 preview_frame->Raise();
1505
1506 // we need to force an update since autoupdate fires
1507 // before the preview frame is shown
1508 wxCommandEvent dummy;
1510}
1511
1513{
1515 {
1516 return;
1517 };
1518#if defined __WXMSW__ || defined __WXMAC__
1520#endif
1521 if (gl_preview_frame->IsIconized()) {
1522 gl_preview_frame->Iconize(false);
1523 }
1524 gl_preview_frame->Show();
1525#if defined __WXMSW__
1526 // on wxMSW Show() does not send OnShowEvent needed to update the
1527 // visibility state of the fast preview windows
1528 // so explicit calling this event handler
1530 se.SetShow(true);
1532#elif defined __WXGTK__
1534#endif
1535 gl_preview_frame->Raise();
1536}
1537
1538void MainFrame::OnShowCPFrame(wxCommandEvent & e)
1539{
1540 DEBUG_TRACE("");
1541 if (cp_frame) {
1542 if (cp_frame->IsIconized()) {
1543 cp_frame->Iconize(false);
1544 }
1545 cp_frame->Show();
1546 cp_frame->Raise();
1547 } else {
1548 cp_frame = new CPListFrame(this, pano);
1549 cp_frame->Show();
1550 }
1551}
1552
1554{
1555 cp_frame = 0;
1556}
1557
1558void MainFrame::OnOptimize(wxCommandEvent & e)
1559{
1560 DEBUG_TRACE("");
1561 wxCommandEvent dummy;
1563}
1564
1565void MainFrame::OnOnlyActiveImages(wxCommandEvent &e)
1566{
1567 SetOptimizeOnlyActiveImages(GetMenuBar()->IsChecked(XRCID("action_optimize_only_active")));
1568};
1569
1571{
1574 if (menubar)
1575 {
1576 menubar->Check(XRCID("action_optimize_only_active"), onlyActive);
1577 };
1580 // notify all observer so they can update their display
1582};
1583
1585{
1586 return m_optOnlyActiveImages;
1587};
1588
1589void MainFrame::OnIgnoreLineCp(wxCommandEvent &e)
1590{
1591 m_optIgnoreLineCp = GetMenuBar()->IsChecked(XRCID("action_optimize_ignore_line_cp"));
1593 // notify all observer so they can update their display
1595};
1596
1598{
1601 if (menubar)
1602 {
1603 menubar->Check(XRCID("action_optimize_ignore_line_cp"), ignoreLineCP);
1604 // notify all observer so they can update their display
1606 };
1607};
1608
1610{
1611 return m_optIgnoreLineCp;
1612};
1613
1614void MainFrame::OnPhotometricOptimize(wxCommandEvent & e)
1615{
1616 wxCommandEvent dummy;
1618};
1619
1620void MainFrame::OnDoStitch(wxCommandEvent & e)
1621{
1622 DEBUG_TRACE("");
1624 wxCommandEvent cmdEvt(wxEVT_BUTTON, stitchButton->GetId());
1625 stitchButton->GetEventHandler()->AddPendingEvent(cmdEvt);
1626}
1627
1628void MainFrame::OnUserDefinedStitch(wxCommandEvent & e)
1629{
1631}
1632
1634{
1635 auto filename = m_userOutput.find(e.GetId());
1636 if (filename != m_userOutput.end())
1637 {
1638 pano_panel->DoUserDefinedStitch(filename->second);
1639 }
1640 else
1641 {
1642 wxBell();
1643 };
1644}
1645
1646void MainFrame::OnMergeProject(wxCommandEvent & e)
1647{
1648 // get the global config object
1649 wxConfigBase* config = wxConfigBase::Get();
1650
1651 wxString defaultdir = config->Read("/actualPath",wxEmptyString);
1653 _("Open project file"),
1655 _("Project files (*.pto)|*.pto|All files (*)|*"),
1657 dlg.SetDirectory(defaultdir);
1658 if (dlg.ShowModal() == wxID_OK)
1659 {
1660 wxString filename = dlg.GetPath();
1661 wxFileName fname(filename);
1663 if (fname.IsOk() && fname.FileExists())
1664 {
1667 std::ifstream in((const char *)fname.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
1668 int ptoversion=0;
1669 if (newPano.loadPTScript(in, ptoversion, (const char *)path.mb_str(HUGIN_CONV_FILENAME)))
1670 {
1672 new_pano.setMemento(newPano);
1675 );
1676 m_mruFiles.AddFileToHistory(fname.GetFullPath());
1677 // force update of preview window
1678 if ( !(preview_frame->IsIconized() ||(! preview_frame->IsShown()) ) )
1679 {
1680 wxCommandEvent dummy;
1682 };
1683 }
1684 else
1685 {
1686 hugin_utils::HuginMessageBox(wxString::Format(_("Could not read project file %s."), fname.GetFullPath()), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
1687 };
1688 };
1689 }
1690}
1691
1692void MainFrame::OnReadPapywizard(wxCommandEvent & e)
1693{
1694 wxString currentDir = wxConfigBase::Get()->Read("/actualPath", wxEmptyString);
1695 wxFileDialog dlg(wxGetActiveWindow(), _("Open Papywizard xml file"),
1696 currentDir, wxEmptyString, _("Papywizard xml files (*.xml)|*.xml|All files (*)|*"),
1698 dlg.SetDirectory(currentDir);
1699 if (dlg.ShowModal() == wxID_OK)
1700 {
1701 wxConfigBase::Get()->Write("/actualPath", dlg.GetDirectory());
1703 };
1704};
1705
1706void MainFrame::OnApplyTemplate(wxCommandEvent & e)
1707{
1708 // get the global config object
1709 wxConfigBase* config = wxConfigBase::Get();
1710
1712 _("Choose template project"),
1713 config->Read("/templatePath",wxEmptyString), wxEmptyString,
1714 _("Project files (*.pto)|*.pto|All files (*)|*"),
1716 dlg.SetDirectory(wxConfigBase::Get()->Read("/templatePath",wxEmptyString));
1717 if (dlg.ShowModal() == wxID_OK) {
1718 wxString filename = dlg.GetPath();
1719 wxConfig::Get()->Write("/templatePath", dlg.GetDirectory()); // remember for later
1720
1721 std::ifstream file((const char *)filename.mb_str(HUGIN_CONV_FILENAME));
1722
1725
1726 }
1727}
1728
1729void MainFrame::OnOpenPTBatcher(wxCommandEvent & e)
1730{
1731#if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
1732 // Original patch for OSX by Charlie Reiman dd. 18 June 2011
1733 // Slightly modified by HvdW. Errors in here are mine, not Charlie's.
1734 FSRef appRef;
1736 OSStatus err;
1737 FSRef documentArray[1]; // Don't really need an array if we only have 1 item
1739 Boolean isDir;
1740
1742 CFSTR("net.sourceforge.hugin.PTBatcherGUI"),
1743 NULL,
1744 &appRef,
1745 NULL);
1746 if (err != noErr) {
1747 // error, can't find PTBatcherGUI
1748 hugin_utils::HuginMessageBox(wxString::Format(_("External program %s not found in the bundle, reverting to system path"), "open"), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
1749 // Possibly a silly attempt otherwise the previous would have worked as well, but just try it.
1750 wxExecute(_T("open -b net.sourceforge.hugin.PTBatcherGUI"));
1751 }
1752 else {
1753 wxExecute(_T("open -b net.sourceforge.hugin.PTBatcherGUI"));
1754 }
1755#else
1756 const wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
1757 wxExecute(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + _T("PTBatcherGUI"));
1758#endif
1759}
1760
1761void MainFrame::OnFineTuneAll(wxCommandEvent & e)
1762{
1763 DEBUG_TRACE("");
1764 // fine-tune all points
1765
1767
1768 // create a map of all control points.
1769 std::set<unsigned int> unoptimized;
1770 for (unsigned int i=0; i < cps.size(); i++) {
1771 // create all control points.
1772 unoptimized.insert(i);
1773 }
1774
1775 unsigned int nGood=0;
1776 unsigned int nBad=0;
1777
1778 wxConfigBase *cfg = wxConfigBase::Get();
1779 double corrThresh=HUGIN_FT_CORR_THRESHOLD;
1780 cfg->Read("/Finetune/CorrThreshold", &corrThresh, HUGIN_FT_CORR_THRESHOLD);
1782 cfg->Read("/Finetune/CurvThreshold",&curvThresh, HUGIN_FT_CURV_THRESHOLD);
1783 // load parameters
1784 const long templWidth = cfg->Read("/Finetune/TemplateSize", HUGIN_FT_TEMPLATE_SIZE);
1785 const long sWidth = templWidth + cfg->Read("/Finetune/LocalSearchWidth", HUGIN_FT_LOCAL_SEARCH_WIDTH);
1786
1787 {
1788 ProgressReporterDialog progress(unoptimized.size(), _("Fine-tuning all points"), _("Fine-tuning"), wxGetActiveWindow());
1789
1790 ImageCache & imgCache = ImageCache::getInstance();
1791
1792 // do not process the control points in random order,
1793 // but walk from image to image, to reduce image reloading
1794 // in low mem situations.
1795 for (unsigned int imgNr = 0 ; imgNr < pano.getNrOfImages(); imgNr++) {
1796 std::set<unsigned int>::iterator it=unoptimized.begin();
1797
1798 imgCache.softFlush();
1799
1800 while (it != unoptimized.end()) {
1801 if (cps[*it].image1Nr == imgNr || cps[*it].image2Nr == imgNr) {
1802 if (!progress.updateDisplayValue())
1803 {
1804 return;
1805 };
1806 if (cps[*it].mode == HuginBase::ControlPoint::X_Y) {
1807 // finetune only normal points
1808 DEBUG_DEBUG("fine tuning point: " << *it);
1810 ImageCache::ImageCacheRGB8Ptr searchImg = imgCache.getImage(
1811 pano.getImage(cps[*it].image2Nr).getFilename())->get8BitImage();
1812
1813 ImageCache::ImageCacheRGB8Ptr templImg = imgCache.getImage(
1814 pano.getImage(cps[*it].image1Nr).getFilename())->get8BitImage();
1815
1817 vigra::Diff2D roundP1(hugin_utils::roundi(cps[*it].x1), hugin_utils::roundi(cps[*it].y1));
1818 vigra::Diff2D roundP2(hugin_utils::roundi(cps[*it].x2), hugin_utils::roundi(cps[*it].y2));
1819
1821 pano.getImage(cps[*it].image2Nr), *searchImg, roundP2, sWidth);
1822
1823 // invert curvature. we always assume its a maxima, the curvature there is negative
1824 // however, we allow the user to specify a positive threshold, so we need to
1825 // invert it
1826 res.curv.x = - res.curv.x;
1827 res.curv.y = - res.curv.y;
1828
1829 if (res.maxi < corrThresh || res.curv.x < curvThresh || res.curv.y < curvThresh ||
1830 res.maxpos.x < 0 || res.maxpos.y < 0 || res.corrPos.x < 0 || res.corrPos.y < 0)
1831 {
1832 // Bad correlation result.
1833 nBad++;
1834 if (res.maxi >= corrThresh) {
1835 cps[*it].error = 0;
1836 }
1837 cps[*it].error = res.maxi;
1838 DEBUG_DEBUG("low correlation: " << res.maxi << " curv: " << res.curv);
1839 } else {
1840 nGood++;
1841 // only update if a good correlation was found
1842 cps[*it].x1 = res.corrPos.x;
1843 cps[*it].y1 = res.corrPos.y;
1844 cps[*it].x2 = res.maxpos.x;
1845 cps[*it].y2 = res.maxpos.y;
1846 cps[*it].error = res.maxi;
1847 }
1848 }
1849 else
1850 {
1851 // for line control points set error = correlation to 1
1852 cps[*it].error = 1.0;
1853 };
1854 unsigned int rm = *it;
1855 ++it;
1856 unoptimized.erase(rm);
1857 } else {
1858 ++it;
1859 }
1860 }
1861 }
1862 }
1864 wxString result;
1865 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"),
1866 nGood, nBad, corrThresh);
1867 hugin_utils::HuginMessageBox(result, _("Hugin"), wxOK, this);
1868 // set newly optimized points
1870 new PanoCommand::UpdateCPsCmd(pano, cps, false)
1871 );
1872}
1873
1874void MainFrame::OnRemoveCPinMasks(wxCommandEvent & e)
1875{
1876 if(pano.getCtrlPoints().size()<2)
1877 return;
1878 HuginBase::UIntSet cps=getCPinMasks(pano);
1879 if(!cps.empty())
1880 {
1883 );
1884 hugin_utils::HuginMessageBox(wxString::Format(_("Removed %lu control points"), static_cast<unsigned long>(cps.size())),
1885 _("Hugin"), wxOK | wxICON_INFORMATION, this);
1886 };
1887}
1888
1889#ifdef HUGIN_HSI
1890void MainFrame::OnPythonScript(wxCommandEvent & e)
1891{
1894 _("Select python script"),
1895 wxConfigBase::Get()->Read("/lensPath",wxEmptyString), wxEmptyString,
1896 _("Python script (*.py)|*.py|All files (*.*)|*.*"),
1898 dlg.SetDirectory(wxConfigBase::Get()->Read("/pythonScriptPath",wxEmptyString));
1899
1900 if (dlg.ShowModal() == wxID_OK)
1901 {
1902 wxString filename = dlg.GetPath();
1903 wxConfig::Get()->Write("/pythonScriptPath", dlg.GetDirectory());
1904 std::string scriptfile((const char *)filename.mb_str(HUGIN_CONV_FILENAME));
1906 new PanoCommand::PythonScriptPanoCmd(pano,scriptfile)
1907 );
1908 }
1909}
1910
1911void MainFrame::OnPlugin(wxCommandEvent & e)
1912{
1913 wxFileName file=m_plugins[e.GetId()];
1914 if(file.FileExists())
1915 {
1916 std::string scriptfile((const char *)file.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
1918 new PanoCommand::PythonScriptPanoCmd(pano,scriptfile)
1919 );
1920 }
1921 else
1922 {
1923 hugin_utils::HuginMessageBox(wxString::Format("Python-Script %s not found.\nStopping processing.", file.GetFullPath()), _("Hugin"), wxOK | wxICON_INFORMATION, wxGetActiveWindow());
1924 };
1925}
1926
1927#endif
1928
1929void MainFrame::OnUndo(wxCommandEvent & e)
1930{
1931 DEBUG_TRACE("OnUndo");
1933 {
1935 }
1936 else
1937 {
1938 wxBell();
1939 };
1940}
1941
1942void MainFrame::OnRedo(wxCommandEvent & e)
1943{
1944 DEBUG_TRACE("OnRedo");
1946 {
1948 };
1949}
1950
1952{
1953 DEBUG_DEBUG("Showing control point " << cpNr);
1954 m_notebook->SetSelection(2);
1956}
1957
1958void MainFrame::ShowCtrlPointEditor(unsigned int img1, unsigned int img2)
1959{
1960 if(!IsShown())
1961 {
1962 Show();
1963 Raise();
1964 };
1965 m_notebook->SetSelection(2);
1966 cpe->setLeftImage(img1);
1967 cpe->setRightImage(img2);
1968}
1969
1971{
1972 if(!IsShown())
1973 {
1974 Show();
1975 Raise();
1976 };
1977 m_notebook->SetSelection(1);
1978 mask_panel->setImage(imgNr, true);
1979 if (switchToCropMode)
1980 {
1982 };
1983};
1984
1986{
1989 {
1990 m_notebook->SetSelection(5);
1991 }
1992 else
1993 {
1995 {
1996 m_notebook->SetSelection(4);
1997 }
1998 else
1999 {
2000 m_notebook->SetSelection(3);
2001 };
2002 };
2003}
2004
2007{
2008 wxString msg;
2009 if (!m_message.empty())
2010 {
2012 if (!m_filename.empty())
2013 {
2014 msg.Append(" ");
2015 msg.Append(wxString(ProgressDisplay::m_filename.c_str(), HUGIN_CONV_FILENAME));
2016 };
2017 };
2018 GetStatusBar()->SetStatusText(msg, 0);
2019
2020#ifdef __WXMSW__
2022#endif
2023}
2024
2025void MainFrame::enableTools(bool option)
2026{
2028 theToolBar->EnableTool(XRCID("action_optimize"), option);
2029 theToolBar->EnableTool(XRCID("ID_SHOW_PREVIEW_FRAME"), option);
2030 //theToolBar->EnableTool(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), option);
2032 theMenuBar->Enable(XRCID("action_optimize"), option);
2033 theMenuBar->Enable(XRCID("action_finetune_all_cp"), option);
2034 theMenuBar->Enable(XRCID("action_remove_cp_in_masks"), option);
2035 theMenuBar->Enable(XRCID("ID_SHOW_PREVIEW_FRAME"), option);
2036 theMenuBar->Enable(XRCID("action_stitch"), option);
2037 theMenuBar->Enable(XRCID("action_stitch_userdefined"), option);
2038 if (m_outputUserMenu != nullptr)
2039 {
2040 m_outputUserMenu->Enable(option);
2041 };
2042 if (m_assistantUserMenu != nullptr)
2043 {
2044 m_assistantUserMenu->Enable(option);
2045 };
2046 theMenuBar->Enable(XRCID("action_assistant"), option);
2047 theMenuBar->Enable(XRCID("action_batch_assistant"), option);
2048 m_menu_file_advanced->Enable(XRCID("action_import_papywizard"), option);
2049 //theMenuBar->Enable(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), option);
2050}
2051
2052
2054{
2055#ifdef DEBUG
2056 wxSize sz = this->GetSize();
2057 wxSize csz = this->GetClientSize();
2058 wxSize vsz = this->GetVirtualSize();
2059 DEBUG_TRACE(" size:" << sz.x << "," << sz.y <<
2060 " client: "<< csz.x << "," << csz.y <<
2061 " virtual: "<< vsz.x << "," << vsz.y);
2062#endif
2063
2064 Layout();
2065 e.Skip();
2066}
2067
2072
2077
2082
2087
2089{
2090 return huginApp::Get()->GetXRCPath();
2091};
2092
2094{
2095 return wxGetApp().GetDataPath();
2096};
2097
2100{
2101 if (m_this) {
2102 return m_this;
2103 } else {
2104 DEBUG_FATAL("MainFrame not yet created");
2106 return 0;
2107 }
2108}
2109
2114
2116{
2117 return m_showCorrelation > 0;
2118}
2119
2120void MainFrame::OnMRUFiles(wxCommandEvent &e)
2121{
2122 size_t index = e.GetId() - wxID_FILE1;
2123 wxString f(m_mruFiles.GetHistoryFile(index));
2124 if (!f.empty())
2125 {
2126 wxFileName fn(f);
2127 if (fn.FileExists())
2128 {
2129 // if closing old project was canceled do nothing
2130 if (CloseProject(true, LOAD_NEW_PROJECT))
2131 {
2132 // remove old images from cache
2133 ImageCache::getInstance().flush();
2134 // finally load project
2135 LoadProjectFile(f);
2136 };
2137 }
2138 else
2139 {
2140 m_mruFiles.RemoveFileFromHistory(index);
2141 hugin_utils::HuginMessageBox(wxString::Format(_("File \"%s\" not found.\nMaybe file was renamed, moved or deleted."),f.c_str()),
2143 };
2144 };
2145}
2146
2147void MainFrame::OnFullScreen(wxCommandEvent & e)
2148{
2150#ifdef __WXGTK__
2151 //workaround a wxGTK bug that also the toolbar is hidden, but not requested to hide
2152 GetToolBar()->Show(true);
2153#endif
2154};
2155
2157{
2158 if(svmModel==NULL)
2159 {
2160 // determine file name of SVM model file
2161 // get XRC path from application
2163 // convert wxString to string
2165
2166 // SVM model file
2167 if (! wxFile::Exists(wxstrModelFileName) ) {
2168 hugin_utils::HuginMessageBox(wxString::Format(_("Celeste model expected in %s not found, Hugin needs to be properly installed."), wxstrModelFileName), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
2169 return NULL;
2170 }
2172 {
2173 hugin_utils::HuginMessageBox(wxString::Format(_("Could not load Celeste model file %s"), wxstrModelFileName), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
2174 svmModel=NULL;
2175 };
2176 }
2177 return svmModel;
2178};
2179
2184
2186{
2188 {
2190 return;
2191 };
2193 {
2194 bool needsUpdateOptimizerVar=false;
2196 for(size_t i=0; i<optVec.size(); i++)
2197 {
2198 bool hasTrX=optVec[i].erase("TrX")>0;
2199 bool hasTrY=optVec[i].erase("TrY")>0;
2200 bool hasTrZ=optVec[i].erase("TrZ")>0;
2201 bool hasTpy=optVec[i].erase("Tpy")>0;
2202 bool hasTpp=optVec[i].erase("Tpp")>0;
2203 bool hasg=optVec[i].erase("g")>0;
2204 bool hast=optVec[i].erase("t")>0;
2206 };
2208 {
2211 );
2212 };
2213 };
2215 {
2216 bool needsUpdateOptimizerVar=false;
2218 for(size_t i=0; i<optVec.size(); i++)
2219 {
2220 bool hasVx=optVec[i].erase("Vx")>0;
2221 bool hasVy=optVec[i].erase("Vy")>0;
2223 };
2225 {
2228 );
2229 };
2230 };
2237 {
2239 };
2240 switch(m_guiLevel)
2241 {
2242 case GUI_SIMPLE:
2243 GetMenuBar()->FindItem(XRCID("action_gui_simple"))->Check();
2244 break;
2245 case GUI_ADVANCED:
2246 GetMenuBar()->FindItem(XRCID("action_gui_advanced"))->Check();
2247 break;
2248 case GUI_EXPERT:
2249 GetMenuBar()->FindItem(XRCID("action_gui_expert"))->Check();
2250 break;
2251 };
2253 {
2254 if(!gl_preview_frame->IsShown())
2255 {
2256 wxCommandEvent dummy;
2258 };
2259 wxGetApp().SetTopWindow(gl_preview_frame);
2260 GetMenuBar()->Remove(0);
2261 GetMenuBar()->Insert(0, m_menu_file_simple, _("&File"));
2262 if(m_filename.IsEmpty())
2263 {
2264 gl_preview_frame->SetTitle(_("Hugin - Panorama Stitcher"));
2265 SetTitle(_("Panorama editor"));
2266 }
2267 else
2268 {
2270 gl_preview_frame->SetTitle(scriptName.GetName() + "." + scriptName.GetExt() + " - " + _("Hugin - Panorama Stitcher"));
2271 SetTitle(scriptName.GetName() + "." + scriptName.GetExt() + " - " + _("Panorama editor"));
2272 };
2273 Hide();
2274 }
2275 else
2276 {
2277 wxGetApp().SetTopWindow(this);
2278 GetMenuBar()->Remove(0);
2279 GetMenuBar()->Insert(0, m_menu_file_advanced, _("&File"));
2280 if(m_filename.IsEmpty())
2281 {
2282 SetTitle(_("Hugin - Panorama Stitcher"));
2283 }
2284 else
2285 {
2287 SetTitle(scriptName.GetName() + "." + scriptName.GetExt() + " - " + _("Hugin - Panorama Stitcher"));
2288 };
2289 if(!IsShown())
2290 {
2291 Show();
2292 };
2293 };
2294};
2295
2296void MainFrame::OnSetGuiSimple(wxCommandEvent & e)
2297{
2300 {
2302 }
2303 else
2304 {
2306 {
2307 hugin_utils::HuginMessageBox(_("Can't switch to simple interface. The project is using stacks and/or vignetting center shift.\nThese features are not supported in simple interface."),
2309 }
2310 else
2311 {
2312 hugin_utils::HuginMessageBox(_("Can't switch to simple interface. The project is using translation or shear parameters.\nThese parameters are not supported in simple interface."),
2314 }
2316 };
2317};
2318
2319void MainFrame::OnSetGuiAdvanced(wxCommandEvent & e)
2320{
2323 {
2325 }
2326 else
2327 {
2328 hugin_utils::HuginMessageBox(_("Can't switch to advanced interface. The project is using translation or shear parameters.\nThese parameters are not supported in advanced interface."),
2331 };
2332};
2333
2334void MainFrame::OnSetGuiExpert(wxCommandEvent & e)
2335{
2337};
2338
2340{
2341 GetMenuBar()->Enable(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), false);
2342 GetMenuBar()->Enable(XRCID("action_gui_simple"), false);
2343 GetToolBar()->EnableTool(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), false);
2344};
2345
2347{
2348 //save project into temp directory
2349 wxString tempDir= wxConfig::Get()->Read("tempDir",wxEmptyString);
2350 if(!tempDir.IsEmpty())
2351 {
2352 if(tempDir.Last()!=wxFileName::GetPathSeparator())
2353 {
2354 tempDir.Append(wxFileName::GetPathSeparator());
2355 }
2356 };
2357 wxFileName scriptFileName(wxFileName::CreateTempFileName(tempDir+"ha"));
2358 const std::string script(scriptFileName.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
2360
2361 // get assistant queue
2362 const wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
2364 HuginQueue::CommandQueue* commands;
2365 if (userdefinedAssistant.IsEmpty())
2366 {
2368 }
2369 else
2370 {
2371 std::stringstream errors;
2373 if (commands->empty())
2374 {
2375 hugin_utils::HuginMessageBox(_("The assistant queue is empty. This indicates an error in the user defined assistant file.") + "\n\n" + wxString(errors.str()),
2376 _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
2377 //delete temporary files
2378 wxRemoveFile(scriptFileName.GetFullPath());
2379 return;
2380 };
2381 };
2382 //execute queue
2383 int ret = MyExecuteCommandQueue(commands, mainWin, _("Running assistant"));
2384
2385 //read back panofile
2387 (const char *)scriptFileName.GetFullPath().mb_str(HUGIN_CONV_FILENAME), "",
2388 ret==0, false));
2389
2390 //delete temporary files
2391 wxRemoveFile(scriptFileName.GetFullPath());
2392 if (!tempfiles.IsEmpty())
2393 {
2394 for (auto& f : tempfiles)
2395 {
2396 wxRemoveFile(f);
2397 };
2398 };
2399 // check that GUI level is still approbiate
2401 if (reqGuiLevel > m_guiLevel)
2402 {
2403 // output of assistant requires higher GUI level
2405 };
2406 //if return value is non-zero, an error occurred in the assistant
2407 if(ret!=0)
2408 {
2409 if (userdefinedAssistant.IsEmpty())
2410 {
2411 if (pano.getNrOfImages() == 1)
2412 {
2413 hugin_utils::HuginMessageBox(_("The assistant could not find vertical lines. Please add vertical lines in the panorama editor and optimize project manually."),
2415 }
2416 else
2417 {
2418 //check for unconnected images
2420 const HuginGraph::ImageGraph::Components comps = graph.GetComponents();
2421 if (comps.size() > 1)
2422 {
2423 // switch to images panel.
2424 unsigned i1 = *(comps[0].rbegin());
2425 unsigned i2 = *(comps[1].begin());
2426 ShowCtrlPointEditor(i1, i2);
2427 // display message box with
2428 hugin_utils::HuginMessageBox(wxString::Format(_("Warning %d unconnected image groups found:"), static_cast<int>(comps.size())) + Components2Str(comps) + "\n"
2429 + _("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);
2430 return;
2431 };
2432 hugin_utils::HuginMessageBox(_("The assistant did not complete successfully. Please check the resulting project file."),
2434 };
2435 }
2436 else
2437 {
2438 hugin_utils::HuginMessageBox(_("The assistant did not complete successfully. Please check the resulting project file."),
2440 };
2441 };
2442};
2443
2444void MainFrame::OnRunAssistant(wxCommandEvent & e)
2445{
2446 RunAssistant(this);
2447};
2448
2450{
2451 const auto filename = m_userAssistant.find(e.GetId());
2452 if (filename != m_userAssistant.end())
2453 {
2454 RunAssistant(this, filename->second);
2455 }
2456 else
2457 {
2458 wxBell();
2459 };
2460};
2461
2463{
2464 wxCommandEvent dummy;
2467 if(wxFileName::FileExists(projectFile))
2468 {
2469#if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
2470 // Original patch for OSX by Charlie Reiman dd. 18 June 2011
2471 // Slightly modified by HvdW. Errors in here are mine, not Charlie's.
2472 FSRef appRef;
2474 OSStatus err;
2475 FSRef documentArray[1]; // Don't really need an array if we only have 1 item
2477 Boolean isDir;
2478
2480 CFSTR("net.sourceforge.hugin.PTBatcherGUI"),
2481 NULL,
2482 &appRef,
2483 NULL);
2484 if (err != noErr)
2485 {
2486 // error, can't find PTBatcherGUI
2487 hugin_utils::HuginMessageBox(wxString::Format(_("External program %s not found in the bundle, reverting to system path"), "open"), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
2488 // Possibly a silly attempt otherwise the previous would have worked as well, but just try it.
2489 wxExecute(_T("open -b net.sourceforge.hugin.PTBatcherGUI ")+hugin_utils::wxQuoteFilename(projectFile));
2490 return;
2491 }
2492
2494 // Point to document
2495 err = FSPathMakeRef((unsigned char*) projectFilebuffer.data(), &documentArray[0], &isDir);
2496 if (err != noErr || isDir)
2497 {
2498 // Something went wrong.
2499 hugin_utils::HuginMessageBox(wxString::Format(_("Project file not found"), "open"), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
2500 return;
2501 }
2502 launchSpec.appRef = &appRef;
2503 launchSpec.numDocs = sizeof(documentArray)/sizeof(documentArray[0]);
2504 launchSpec.itemRefs = documentArray;
2505 launchSpec.passThruParams = NULL;
2507 launchSpec.asyncRefCon = NULL;
2508
2510 if (err != noErr && err != kLSLaunchInProgressErr)
2511 {
2512 // Should be ok if it's in progress... I think.
2513 // Launch failed.
2514 hugin_utils::HuginMessageBox(wxString::Format(_("Can't launch PTBatcherGui"), "open"), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
2515 return;
2516 }
2517
2518 // Should verify that actuallyLaunched and appRef are the same.
2520 {
2521 // error, lauched the wrong thing.
2522 hugin_utils::HuginMessageBox(wxString::Format(_("Launched incorrect programme"), "open"), _("Hugin"), wxOK | wxICON_ERROR, wxGetActiveWindow());
2523 return;
2524 }
2525#else
2526 const wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
2528#endif
2529 }
2530};
2531
2536
Definition of dialog for numeric transforms.
create a CommandQueue for running the assistant using CLI tools
Definition of dialog to browse directory with pto files.
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
image1Nr
image2Nr
algorithms for remove control points by statistic method
GuiLevel GetMinimumGuiLevel(HuginBase::PanoramaData &pano)
returns the requiered GuiLevel for the given panorama to work correctly
Definition GuiLevel.cpp:29
GuiLevel
Definition GuiLevel.h:32
@ GUI_EXPERT
Definition GuiLevel.h:35
@ GUI_ADVANCED
Definition GuiLevel.h:34
@ GUI_SIMPLE
Definition GuiLevel.h:33
@ wxIDUSERASSISTANT
@ wxIDPYTHONSCRIPTS
@ wxIDUSEROUTPUTSEQUENCE
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 ...
void registerPTWXDlgFcn()
Definition PTWXDlg.cpp:178
void deregisterPTWXDlgFcn()
Definition PTWXDlg.cpp:185
Definition of PanoOperation class.
read settings from papywizard xml file
bool comparePluginItem(PluginItem item1, PluginItem item2)
compares 2 plugin with category and name
Reading python plugins metadata.
std::list< PluginItem > PluginItems
Definition PluginItems.h:61
Definition of dialog and functions to import RAW images to project file.
Dialog for about window.
Definition AboutDialog.h:41
Dialog for browsing pto files.
class, which stores all settings of one cp detector
control point editor panel.
void setRightImage(unsigned int imgNr)
set right image
void Init(HuginBase::Panorama *pano)
void setLeftImage(unsigned int imgNr)
set left image
void ShowControlPoint(unsigned int cpNr)
show a control point
The OpenGL preview frame.
void InitPreviews()
init previews
void OnShowEvent(wxShowEvent &e)
void SetGuiLevel(GuiLevel newLevel)
sets the gui level
void LoadOpenGLLayout()
loads the layout of the OpenGL windows and restores it
void StorePositionAndSize()
store position and size of window in wxConfig
void AddUserDefinedSequence(int id, const wxString &desc, const wxString &help)
adds the given user defined output sequence to SplitButton menu
void AddUserDefinedAssistant(int id, const wxString &desc, const wxString &help)
adds the given user defined assistant to SplitButton menu
void ResetPreviewZoom()
reset zoom level for preview window
void SetShowProjectionHints(bool new_value)
set status if projection hints should be shown or not
This is a cache for all the images we use.
Definition ImageCache.h:53
static ImageCache & getInstance()
get the global ImageCache object
void flush()
release all images in the cache.
Memento class for a Panorama object.
Definition Panorama.h:50
bool loadPTScript(std::istream &i, int &ptoVersion, const std::string &prefix="")
load a Hugin file
Model for a panorama.
Definition Panorama.h:153
void changeFinished(bool keepDirty)
notify observers about changes in this class
Definition Panorama.cpp:831
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition Panorama.h:211
const PanoramaOptions & getOptions() const
returns the options for this panorama
Definition Panorama.h:481
virtual void clearDirty()
clear dirty flag.
Definition Panorama.h:645
bool isDirty() const
true if there are unsaved changes
Definition Panorama.h:636
void setMemento(const PanoramaMemento &memento)
set the internal state
void addObserver(PanoramaObserver *o)
add a panorama observer.
const int getPhotometricOptimizerSwitch() const
return the photometric optimizer master switch
Definition Panorama.h:467
const CPVector & getCtrlPoints() const
get all control point of this Panorama
Definition Panorama.h:319
bool removeObserver(PanoramaObserver *observer)
remove a panorama observer.
const OptimizeVector & getOptimizeVector() const
return the optimize settings stored inside panorama
Definition Panorama.h:454
bool WritePTOFile(const std::string &filename, const std::string &prefix="")
write data to given pto file
void printStitcherScript(std::ostream &o, const PanoramaOptions &target, const UIntSet &imgs) const
create the stitcher script
Definition Panorama.cpp:778
const int getOptimizerSwitch() const
returns optimizer master switch
Definition Panorama.h:461
std::size_t getNrOfImages() const
number of images.
Definition Panorama.h:205
class to work with images graphs created from a HuginBase::Panorama class it creates a graph based on...
Definition ImageGraph.h:45
std::vector< HuginBase::UIntSet > Components
stores the components of the graph
Definition ImageGraph.h:50
class for showing splash screen the class wxSplashScreen from wxWidgets does not work correctly for o...
Definition MainFrame.cpp:89
HuginSplashScreen(wxWindow *parent, wxBitmap bitmap)
Definition MainFrame.cpp:92
Hugin's first panel.
Definition ImagesPanel.h:41
wxString GetCurrentOptimizerString()
return the currently selected optimizer setting as string from the drop down list box
void RunCPGenerator(CPDetectorSetting &setting, const HuginBase::UIntSet &img)
run the cp generator with the given setting on selected images
void SetGuiLevel(GuiLevel newGuiLevel)
sets the GuiLevel for all controls on this panel
void ReloadCPDetectorSettings()
Reloads the cp detector settings from config, necessary after edit preferences.
const wxString GetSelectedCPGenerator()
return the currently selected cp generator description
void Init(HuginBase::Panorama *pano)
CPDetectorSetting & GetDefaultSetting()
returns the default cp detector settings
Definition ImagesPanel.h:74
A tip file provider that uses gettext to translate the tips.
The main window frame.
Definition MainFrame.h:84
void OnTogglePreviewFrame(wxCommandEvent &e)
PanoPanel * pano_panel
Definition MainFrame.h:258
bool m_show_opt_panel
Definition MainFrame.h:255
void ShowCtrlPoint(unsigned int cpNr)
void OnFAQ(wxCommandEvent &e)
void OnLoadingFailed(wxCommandEvent &e)
event handler called when loading of image file failed
bool m_optIgnoreLineCp
Definition MainFrame.h:290
void OnMRUFiles(wxCommandEvent &e)
event handler for recently used files
static MainFrame * Get()
hack.. kind of a pseudo singleton...
void OnSaveProject(wxCommandEvent &e)
virtual ~MainFrame()
dtor.
void AddImages(wxArrayString &filenameArray)
adds the given files to the projects, with checking for invalid filenames
void SetGuiLevel(GuiLevel newLevel)
bool m_optOnlyActiveImages
Definition MainFrame.h:289
bool m_show_opt_photo_panel
Definition MainFrame.h:257
void updateProgressDisplay()
receive notification about progress.
void OnShowPrefs(wxCommandEvent &e)
void LoadProjectFile(const wxString &filename)
void OnTipOfDay(wxCommandEvent &e)
void OnDoStitch(wxCommandEvent &e)
void OnRunAssistantUserdefined(wxCommandEvent &e)
void OnShowCPFrame(wxCommandEvent &e)
std::map< int, wxString > m_userOutput
Definition MainFrame.h:299
void DisableOpenGLTools()
disables all OpenGL related menu items and toobar buttons
void ShowCtrlPointEditor(unsigned int img1, unsigned int img2)
opens the control points tab with the both images selected
void OnKeyboardHelp(wxCommandEvent &e)
GLPreviewFrame * gl_preview_frame
Definition MainFrame.h:263
const wxString & GetXRCPath()
get the path to the xrc directory
HuginBase::Panorama & pano
Definition MainFrame.h:274
void OnPhotometricOptimize(wxCommandEvent &e)
void OnOpenPTBatcher(wxCommandEvent &e)
void OnSendToAssistantQueue(wxCommandEvent &e)
PreviewFrame * preview_frame
Definition MainFrame.h:262
void OnAbout(wxCommandEvent &e)
void OnAddImages(wxCommandEvent &e)
struct celeste::svm_model * svmModel
Definition MainFrame.h:259
GuiLevel m_guiLevel
Definition MainFrame.h:265
void OnToggleGLPreviewFrame(wxCommandEvent &e)
wxMenu * m_menu_file_simple
Definition MainFrame.h:284
void OnRemoveCPinMasks(wxCommandEvent &e)
std::map< int, wxString > m_userAssistant
Definition MainFrame.h:300
void OnHelp(wxCommandEvent &e)
wxHelpController & GetHelpController()
Definition MainFrame.h:183
wxString m_filename
Definition MainFrame.h:277
void OnUserQuit(wxCommandEvent &e)
void RunCPGenerator(CPDetectorSetting &setting, const HuginBase::UIntSet &img)
run the cp generator with the given setting on selected images
void OnOnlyActiveImages(wxCommandEvent &e)
void OnSetGuiSimple(wxCommandEvent &e)
void RunAssistant(wxWindow *mainWin, const wxString &userdefinedAssistant=wxEmptyString)
void ShowMaskEditor(size_t imgNr, bool switchToCropMode=false)
opens the mask/crop editor with the given image selected
void OnSetGuiAdvanced(wxCommandEvent &e)
wxString getProjectName()
void OnNewProject(wxCommandEvent &e)
static MainFrame * m_this
Definition MainFrame.h:282
void OnMergeProject(wxCommandEvent &e)
void OnReadPapywizard(wxCommandEvent &e)
void OnOptimize(wxCommandEvent &e)
const bool GetOptimizeIgnoreLineCp() const
wxMenuItem * m_assistantUserMenu
Definition MainFrame.h:287
CPListFrame * cp_frame
Definition MainFrame.h:264
OptimizePanel * opt_panel
Definition MainFrame.h:254
wxMenuItem * m_outputUserMenu
Definition MainFrame.h:286
bool IsShowingCorrelation() const
void OnFullScreen(wxCommandEvent &e)
event handler for full screen
MaskEditorPanel * mask_panel
Definition MainFrame.h:252
void OnLoadProject(wxCommandEvent &e)
virtual void panoramaChanged(HuginBase::Panorama &pano)
Enable or disable undo and redo.
wxString GetCurrentOptimizerString()
returns the string which describes the current selected optimizer setting
void DisplayHelp(wxString section=wxEmptyString)
call help browser with given file
void OnRunAssistant(wxCommandEvent &e)
void OnCPListFrameClosed()
void OnUndo(wxCommandEvent &e)
bool CloseProject(bool cancelable, CloseReason reason)
void enableTools(bool option)
wxFileHistory m_mruFiles
Definition MainFrame.h:248
const wxString GetSelectedCPGenerator()
return the currently selected cp generator description
void OnFineTuneAll(wxCommandEvent &e)
void OnUserDefinedStitch(wxCommandEvent &e)
wxNotebook * m_notebook
Definition MainFrame.h:249
void SetOptimizeIgnoreLineCp(const bool ignoreLineCP)
sets the status of the "ignore line cp" menu item
void OnRedo(wxCommandEvent &e)
const wxString & GetDataPath()
get the path to data directory
void OnIgnoreLineCp(wxCommandEvent &e)
struct celeste::svm_model * GetSVMModel()
MainFrame(wxWindow *parent, HuginBase::Panorama &pano)
ctor.
void OnSavePTStitcherAs(wxCommandEvent &e)
void panoramaImagesChanged(HuginBase::Panorama &pano, const HuginBase::UIntSet &imgNr)
notifies about changes to images
GLPreviewFrame * getGLPreview()
void OnSetGuiExpert(wxCommandEvent &e)
void OnAddTimeImages(wxCommandEvent &e)
ImagesPanel * images_panel
Definition MainFrame.h:251
const bool GetOptimizeOnlyActiveImages() const
void OnSize(wxSizeEvent &e)
OptimizePhotometricPanel * opt_photo_panel
Definition MainFrame.h:256
void OnBrowseProjects(wxCommandEvent &e)
CPEditorPanel * cpe
Definition MainFrame.h:253
void OnShowPanel(wxCommandEvent &e)
CPDetectorSetting & GetDefaultSetting()
returns default cp detector setting
void ShowStitcherTab()
opens the stitcher tab
void OnUserDefinedStitchSaved(wxCommandEvent &e)
@ CLOSE_PROGRAM
Definition MainFrame.h:134
@ LOAD_NEW_PROJECT
Definition MainFrame.h:135
int m_showCorrelation
Definition MainFrame.h:279
void OnApplyTemplate(wxCommandEvent &e)
void SetOptimizeOnlyActiveImages(const bool onlyActive)
sets the status of the "optimize only active images" menu item
void OnExit(wxCloseEvent &e)
wxMenu * m_menu_file_advanced
Definition MainFrame.h:285
void OnSaveProjectAs(wxCommandEvent &e)
mask editor panel.
void Init(HuginBase::Panorama *pano)
void SwitchToCropMode()
switches the controls to crop mode
void setImage(unsigned int imgNr, bool updateListSelection=false)
sets the image, which is currently edited
run the optimizer.
void SetGuiLevel(GuiLevel newGuiLevel)
void SetOnlyActiveImages(const bool onlyActive)
for external setting of "only active image" checkbox
void OnOptimizeButton(wxCommandEvent &e)
run the optimizer
void Init(HuginBase::Panorama *pano)
void SetIgnoreLineCP(const bool noLineCp)
for external setting of "ignore line cp" checkbox
void Init(HuginBase::Panorama *pano)
void SetGuiLevel(GuiLevel newGuiLevel)
void SetOnlyActiveImages(const bool onlyActive)
for external setting of "only active image" checkbox
void OnOptimizeButton(wxCommandEvent &e)
run the optimizer
center panorama horizontically
PanoCommand to combine other PanoCommands.
Definition PanoCommand.h:40
bool canRedo() const
Return true iff there is a command to redo.
std::string getLastCommandName() const
returns the name of the last command
void clearRedoQueue()
clear all commands in the redo queue
virtual void redo()
Redoes the last undone action.
void addCommand(PanoCommand *command, bool execute=true)
Adds a command to the history.
virtual void undo()
Undoes the last action.
void clear()
Erases all the undo/redo history.
bool canUndo() const
Return true iff there is a command to undo.
distributes all images above the sphere, for the assistant
static GlobalCmdHist & getInstance()
merge two project files
Base class for all panorama commands.
Definition Command.h:39
remove several control points
remove multiple images from a panorama
Definition PanoCommand.h:95
update all control points
updates the optimize vector, aka all variables which should be optimized
add image(s) to a panorama
apply a template to a panorama object
dump the current project and load a new one.
start a new project, reset options to values in preferences
simple class that forward the drop to the mainframe
Definition MainFrame.h:62
PanoOperation to add several user selected images to the panorama.
PanoOperation to add all image in a defined timeinterval to the panorama.
virtual PanoCommand::PanoCommand * GetCommand(wxWindow *parent, HuginBase::Panorama &pano, HuginBase::UIntSet images, GuiLevel guiLevel)
returns the appropriate PanoCommand::PanoCommand to be inserted into GlobalCmdHistory,...
Define the pano edit panel.
Definition PanoPanel.h:44
virtual void panoramaChanged(HuginBase::Panorama &pano)
this is called whenever the panorama has changed.
wxButton * GetStitchButton() const
Definition PanoPanel.h:85
void Init(HuginBase::Panorama *pano)
void SetGuiLevel(GuiLevel newGuiLevel)
void DoUserDefinedStitch(const wxString &settings=wxString())
stitching with user defined file
class for generating plugin menu items
Definition PluginItems.h:36
hugin preferences dialog
The image preview frame.
void OnUpdate(wxCommandEvent &event)
Dialog for raw import.
Definition RawImport.h:35
const wxString & GetDataPath()
return the current data path
Definition huginApp.h:83
const wxString & GetXRCPath()
return the current xrc path
Definition huginApp.h:77
static huginApp * Get()
hack.. kind of a pseudo singleton...
Definition huginApp.cpp:639
#define HUGIN_FT_TEMPLATE_SIZE
#define HUGIN_CELESTE_MODEL
#define HUGIN_FT_CURV_THRESHOLD
#define HUGIN_FT_LOCAL_SEARCH_WIDTH
#define HUGIN_SHOW_PROJECTION_HINTS
#define HUGIN_FT_CORR_THRESHOLD
implementation of huginApp Class
#define HUGIN_CONV_FILENAME
Definition platform.h:40
wxString Components2Str(const HuginGraph::ImageGraph::Components &comp)
Definition huginApp.cpp:84
wxString getDefaultProjectName(const HuginBase::Panorama &pano, const wxString filenameTemplate)
gets the default project name, as defined in the preferences
functions for interaction with the hugin configuration file
#define DEBUG_ERROR(msg)
Definition utils.h:76
#define DEBUG_ASSERT(cond)
Definition utils.h:80
#define DEBUG_DEBUG(msg)
Definition utils.h:68
#define DEBUG_FATAL(msg)
Definition utils.h:78
#define DEBUG_TRACE(msg)
Definition utils.h:67
#define DEBUG_INFO(msg)
Definition utils.h:69
std::vector< ControlPoint > CPVector
std::vector< std::set< std::string > > OptimizeVector
std::set< unsigned int > UIntSet
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
std::vector< NormalCommand * > CommandQueue
Definition Executor.h:61
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
CommandQueue * GetAssistantCommandQueue(const HuginBase::Panorama &pano, const wxString &ExePath, const wxString &project)
generates the command queue for running the assistant
void GeneratePanoOperationVector()
generates the PanoOperationVector for context menu
void CleanPanoOperationVector()
clears the PanoOperationVector
bool ImportPapywizardFile(const wxString &filename, HuginBase::Panorama &pano)
import the settings from given filename into pano
void destroySVMmodel(struct svm_model *&model)
frees the resource of model
Definition Celeste.cpp:60
bool loadSVMmodel(struct svm_model *&model, std::string &model_file)
loads the SVM model from file
Definition Celeste.cpp:45
str wxQuoteFilename(const str &arg)
Quote a filename, so that it is surrounded by "".
Definition wxPlatform.h:82
bool AskUserOverwrite(const wxString &filename, const wxString &caption, wxWindow *parent)
ask user if the given file should be overwritten, return true if the user confirmed the overwritting
Definition wxutils.cpp:198
int HuginMessageBox(const wxString &message, const wxString &caption, int style, wxWindow *parent)
Definition wxutils.cpp:176
std::unique_ptr< wxMessageDialogBase > MessageDialog
Definition wxutils.h:90
std::string GetUserAppDataDir()
returns the directory for user specific Hugin settings, e.g.
Definition utils.cpp:497
int roundi(T x)
Definition hugin_math.h:73
std::string GetHuginVersion()
return a string with version numbers
Definition utils.cpp:907
void StoreFramePosition(wxTopLevelWindow *frame, const wxString &basename, const bool ignoreMaximize)
Definition wxutils.cpp:106
std::string getPathPrefix(const std::string &filename)
Get the path to a filename.
Definition utils.cpp:184
MessageDialog GetMessageDialog(const wxString &message, const wxString &caption, int style, wxWindow *parent)
Definition wxutils.cpp:187
IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow, wxWindow)
include file for the hugin project
include file for the hugin project
bool IsRawExtension(const wxString &testExt)
return true, if given extension is in list of known raw extension (comparision is case insensitive
Definition platform.cpp:112
bool containsInvalidCharacters(const wxString stringToTest)
returns true, if the given strings contains invalid characters
Definition platform.cpp:511
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:524
void fill_set(_Container &c, typename _Container::key_type begin, typename _Container::key_type end)
Definition stl_utils.h:81
Maximum of correlation, position and value.
Definition Correlation.h:57
hugin_utils::FDiff2D corrPos
Definition Correlation.h:66
hugin_utils::FDiff2D curv
Definition Correlation.h:68
hugin_utils::FDiff2D maxpos
Definition Correlation.h:64
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.
Definition threshold.h:41
void UpdateImageCacheSize()
update the image cache size from the settings in wxConfig
wxwindows specific panorama commands
WXIMPEX void FixHelpSettings()
helper function to check window position settings of help window
platform/compiler specific stuff.