MainFrame.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00027 #include "hugin_config.h"
00028 
00029 #include <wx/dir.h>
00030 #include <wx/stdpaths.h>
00031 #include <wx/wfstream.h>
00032 #include "panoinc_WX.h"
00033 #include "panoinc.h"
00034 
00035 #include "base_wx/platform.h"
00036 #include "base_wx/wxPlatform.h"
00037 
00038 #include "vigra/imageinfo.hxx"
00039 #include "vigra_ext/Correlation.h"
00040 
00041 #include "hugin/config_defaults.h"
00042 #include "hugin/PreferencesDialog.h"
00043 #include "hugin/MainFrame.h"
00044 #include "base_wx/wxPanoCommand.h"
00045 #include "base_wx/CommandHistory.h"
00046 #include "hugin/PanoPanel.h"
00047 #include "hugin/ImagesPanel.h"
00048 #include "hugin/MaskEditorPanel.h"
00049 #include "hugin/OptimizePanel.h"
00050 #include "hugin/OptimizePhotometricPanel.h"
00051 #include "hugin/PreviewFrame.h"
00052 #include "hugin/GLPreviewFrame.h"
00053 #include "hugin/huginApp.h"
00054 #include "hugin/CPEditorPanel.h"
00055 #include "hugin/CPListFrame.h"
00056 #include "hugin/LocalizedFileTipProvider.h"
00057 #include "algorithms/control_points/CleanCP.h"
00058 #include "hugin/PanoOperation.h"
00059 #include "hugin/PapywizardImport.h"
00060 
00061 #include "base_wx/MyProgressDialog.h"
00062 #include "base_wx/RunStitchPanel.h"
00063 #include "base_wx/wxImageCache.h"
00064 #include "base_wx/PTWXDlg.h"
00065 #include "base_wx/MyExternalCmdExecDialog.h"
00066 #include "base_wx/AssistantExecutor.h"
00067 #include "algorithms/optimizer/ImageGraph.h"
00068 
00069 #include "base_wx/huginConfig.h"
00070 #include "hugin/AboutDialog.h"
00071 
00072 #if HUGIN_HSI
00073 #include "PluginItems.h"
00074 #endif
00075 
00076 #ifdef __MINGW32__
00077 // fixes for mingw compilation...
00078 #undef FindWindow
00079 #endif
00080 
00085 class HuginSplashScreen : public wxFrame
00086 {
00087 public:
00088     HuginSplashScreen() {};
00089     HuginSplashScreen(wxWindow* parent, wxBitmap bitmap) : 
00090         wxFrame(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxFRAME_TOOL_WINDOW | wxFRAME_NO_TASKBAR | wxSTAY_ON_TOP)
00091     {
00092         SetExtraStyle(GetExtraStyle() | wxWS_EX_TRANSIENT);
00093         wxSizer* topSizer=new wxBoxSizer(wxVERTICAL);
00094         wxStaticBitmap* staticBitmap=new wxStaticBitmap(this,wxID_ANY,bitmap);
00095         topSizer->Add(staticBitmap,1,wxEXPAND);
00096         SetSizerAndFit(topSizer);
00097         SetClientSize(bitmap.GetWidth(), bitmap.GetHeight());
00098         CenterOnScreen();
00099         Show(true);
00100         SetFocus();
00101 #if defined(__WXMSW__) || defined(__WXMAC__)
00102         Update();
00103 #elif defined(__WXGTK20__)
00104         //do nothing
00105 #else
00106         wxYieldIfNeeded();
00107 #endif
00108     };
00109     DECLARE_DYNAMIC_CLASS(HuginSplashScreen)
00110     DECLARE_EVENT_TABLE()
00111 };
00112 
00113 IMPLEMENT_DYNAMIC_CLASS(HuginSplashScreen, wxFrame)
00114 BEGIN_EVENT_TABLE(HuginSplashScreen, wxFrame)
00115 END_EVENT_TABLE()
00116 
00118 bool PanoDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
00119 {
00120     DEBUG_TRACE("OnDropFiles");
00121     MainFrame * mf = MainFrame::Get();
00122     if (!mf) return false;
00123 
00124     if (!m_imageOnly && filenames.GetCount() == 1) {
00125         wxFileName file(filenames[0]);
00126         if (file.GetExt().CmpNoCase(wxT("pto")) == 0 ||
00127             file.GetExt().CmpNoCase(wxT("ptp")) == 0 ||
00128             file.GetExt().CmpNoCase(wxT("pts")) == 0 )
00129         {
00130             // load project
00131             if (mf->CloseProject(true)) {
00132                 mf->LoadProjectFile(file.GetFullPath());
00133                 // remove old images from cache
00134                 ImageCache::getInstance().flush();
00135             }
00136             return true;
00137         }
00138     }
00139 
00140     // try to add as images
00141     std::vector<std::string> filesv;
00142     wxArrayString invalidFiles;
00143     for (unsigned int i=0; i< filenames.GetCount(); i++) {
00144         wxFileName file(filenames[i]);
00145 
00146         if (file.GetExt().CmpNoCase(wxT("jpg")) == 0 ||
00147             file.GetExt().CmpNoCase(wxT("jpeg")) == 0 ||
00148             file.GetExt().CmpNoCase(wxT("tif")) == 0 ||
00149             file.GetExt().CmpNoCase(wxT("tiff")) == 0 ||
00150             file.GetExt().CmpNoCase(wxT("png")) == 0 ||
00151             file.GetExt().CmpNoCase(wxT("bmp")) == 0 ||
00152             file.GetExt().CmpNoCase(wxT("gif")) == 0 ||
00153             file.GetExt().CmpNoCase(wxT("pnm")) == 0 ||
00154             file.GetExt().CmpNoCase(wxT("sun")) == 0 ||
00155             file.GetExt().CmpNoCase(wxT("hdr")) == 0 ||
00156             file.GetExt().CmpNoCase(wxT("viff")) == 0 )
00157         {
00158             if(containsInvalidCharacters(filenames[i]))
00159             {
00160                 invalidFiles.Add(file.GetFullPath());
00161             }
00162             else
00163             {
00164                 filesv.push_back((const char *)filenames[i].mb_str(HUGIN_CONV_FILENAME));
00165             };
00166         }
00167     }
00168     // we got some images to add.
00169     if (filesv.size() > 0)
00170     {
00171         // use a Command to ensure proper undo and updating of GUI parts
00172         wxBusyCursor();
00173         if(pano.getNrOfCtrlPoints()>0)
00174         {
00175             PanoCommand::GlobalCmdHist::getInstance().addCommand(new PanoCommand::wxAddImagesCmd(pano, filesv));
00176         }
00177         else
00178         {
00179             std::vector<PanoCommand::PanoCommand*> cmds;
00180             cmds.push_back(new PanoCommand::wxAddImagesCmd(pano, filesv));
00181             cmds.push_back(new PanoCommand::DistributeImagesCmd(pano));
00182             cmds.push_back(new PanoCommand::CenterPanoCmd(pano));
00183             PanoCommand::GlobalCmdHist::getInstance().addCommand(new PanoCommand::CombinedPanoCommand(pano, cmds));
00184         };
00185 
00186     }
00187     if(invalidFiles.size()>0)
00188     {
00189         ShowFilenameWarning(mf, invalidFiles);
00190     }
00191 
00192     return true;
00193 }
00194 
00195 
00196 #if defined _WIN32 && defined Hugin_shared
00197 DEFINE_LOCAL_EVENT_TYPE(EVT_LOADING_FAILED)
00198 #else
00199 DEFINE_EVENT_TYPE(EVT_LOADING_FAILED)
00200 #endif
00201 
00202 // event table. this frame will recieve mostly global commands.
00203 BEGIN_EVENT_TABLE(MainFrame, wxFrame)
00204     EVT_MENU(XRCID("action_new_project"),  MainFrame::OnNewProject)
00205     EVT_MENU(XRCID("action_load_project"),  MainFrame::OnLoadProject)
00206     EVT_MENU(XRCID("action_save_project"),  MainFrame::OnSaveProject)
00207     EVT_MENU(XRCID("action_save_as_project"),  MainFrame::OnSaveProjectAs)
00208     EVT_MENU(XRCID("action_save_as_ptstitcher"),  MainFrame::OnSavePTStitcherAs)
00209     EVT_MENU(XRCID("action_open_batch_processor"),  MainFrame::OnOpenPTBatcher)
00210     EVT_MENU(XRCID("action_import_project"), MainFrame::OnMergeProject)
00211     EVT_MENU(XRCID("action_import_papywizard"), MainFrame::OnReadPapywizard)
00212     EVT_MENU(XRCID("action_apply_template"),  MainFrame::OnApplyTemplate)
00213     EVT_MENU(XRCID("action_exit_hugin"),  MainFrame::OnUserQuit)
00214     EVT_MENU_RANGE(wxID_FILE1, wxID_FILE9, MainFrame::OnMRUFiles)
00215     EVT_MENU(XRCID("action_show_about"),  MainFrame::OnAbout)
00216     EVT_MENU(XRCID("action_show_help"),  MainFrame::OnHelp)
00217     EVT_MENU(XRCID("action_show_tip"),  MainFrame::OnTipOfDay)
00218     EVT_MENU(XRCID("action_show_shortcuts"),  MainFrame::OnKeyboardHelp)
00219     EVT_MENU(XRCID("action_show_faq"),  MainFrame::OnFAQ)
00220     EVT_MENU(XRCID("action_show_donate"),  MainFrame::OnShowDonate)
00221     EVT_MENU(XRCID("action_show_prefs"), MainFrame::OnShowPrefs)
00222     EVT_MENU(XRCID("action_assistant"), MainFrame::OnRunAssistant)
00223     EVT_MENU(XRCID("action_batch_assistant"), MainFrame::OnSendToAssistantQueue)
00224     EVT_MENU(XRCID("action_gui_simple"), MainFrame::OnSetGuiSimple)
00225     EVT_MENU(XRCID("action_gui_advanced"), MainFrame::OnSetGuiAdvanced)
00226     EVT_MENU(XRCID("action_gui_expert"), MainFrame::OnSetGuiExpert)
00227 #ifdef HUGIN_HSI
00228     EVT_MENU(XRCID("action_python_script"), MainFrame::OnPythonScript)
00229 #endif
00230     EVT_MENU(XRCID("ID_EDITUNDO"), MainFrame::OnUndo)
00231     EVT_MENU(XRCID("ID_EDITREDO"), MainFrame::OnRedo)
00232     EVT_MENU(XRCID("ID_SHOW_FULL_SCREEN"), MainFrame::OnFullScreen)
00233     EVT_MENU(XRCID("ID_SHOW_PREVIEW_FRAME"), MainFrame::OnTogglePreviewFrame)
00234     EVT_MENU(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), MainFrame::OnToggleGLPreviewFrame)
00235     EVT_BUTTON(XRCID("ID_SHOW_PREVIEW_FRAME"),MainFrame::OnTogglePreviewFrame)
00236     EVT_BUTTON(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), MainFrame::OnToggleGLPreviewFrame)
00237 
00238     EVT_MENU(XRCID("action_optimize"),  MainFrame::OnOptimize)
00239     EVT_MENU(XRCID("action_optimize_only_active"), MainFrame::OnOnlyActiveImages)
00240     EVT_BUTTON(XRCID("action_optimize"),  MainFrame::OnOptimize)
00241     EVT_MENU(XRCID("action_finetune_all_cp"), MainFrame::OnFineTuneAll)
00242 //    EVT_BUTTON(XRCID("action_finetune_all_cp"), MainFrame::OnFineTuneAll)
00243     EVT_MENU(XRCID("action_remove_cp_in_masks"), MainFrame::OnRemoveCPinMasks)
00244 
00245     EVT_MENU(XRCID("ID_CP_TABLE"), MainFrame::OnShowCPFrame)
00246     EVT_BUTTON(XRCID("ID_CP_TABLE"),MainFrame::OnShowCPFrame)
00247 
00248     EVT_MENU(XRCID("ID_SHOW_PANEL_IMAGES"), MainFrame::OnShowPanel)
00249     EVT_MENU(XRCID("ID_SHOW_PANEL_MASK"), MainFrame::OnShowPanel)
00250     EVT_MENU(XRCID("ID_SHOW_PANEL_CP_EDITOR"), MainFrame::OnShowPanel)
00251     EVT_MENU(XRCID("ID_SHOW_PANEL_OPTIMIZER"), MainFrame::OnShowPanel)
00252     EVT_MENU(XRCID("ID_SHOW_PANEL_OPTIMIZER_PHOTOMETRIC"), MainFrame::OnShowPanel)
00253     EVT_MENU(XRCID("ID_SHOW_PANEL_PANORAMA"), MainFrame::OnShowPanel)
00254     EVT_MENU(XRCID("action_stitch"), MainFrame::OnDoStitch)
00255     EVT_MENU(XRCID("action_stitch_userdefined"), MainFrame::OnUserDefinedStitch)
00256     EVT_MENU(XRCID("action_add_images"),  MainFrame::OnAddImages)
00257     EVT_BUTTON(XRCID("action_add_images"),  MainFrame::OnAddImages)
00258     EVT_MENU(XRCID("action_add_time_images"),  MainFrame::OnAddTimeImages)
00259     EVT_BUTTON(XRCID("action_add_time_images"),  MainFrame::OnAddTimeImages)
00260     EVT_CLOSE(  MainFrame::OnExit)
00261     EVT_SIZE(MainFrame::OnSize)
00262     EVT_COMMAND(wxID_ANY, EVT_LOADING_FAILED, MainFrame::OnLoadingFailed)
00263 END_EVENT_TABLE()
00264 
00265 // change this variable definition
00266 //wxTextCtrl *itemProjTextMemo;
00267 // image preview
00268 //wxBitmap *p_img = (wxBitmap *) NULL;
00269 //WX_DEFINE_ARRAY()
00270 
00271 enum
00272 {
00273     wxIDPYTHONSCRIPTS = wxID_HIGHEST + 2000,
00274     wxIDUSEROUTPUTSEQUENCE = wxID_HIGHEST + 2500
00275 };
00276 
00277 MainFrame::MainFrame(wxWindow* parent, HuginBase::Panorama & pano)
00278     : cp_frame(0), pano(pano)
00279 {
00280     preview_frame = 0;
00281     svmModel=NULL;
00282 
00283     bool disableOpenGL=false;
00284     if(wxGetKeyState(WXK_COMMAND))
00285     {
00286         wxDialog dlg;
00287         wxXmlResource::Get()->LoadDialog(&dlg, NULL, wxT("disable_opengl_dlg"));
00288         long noOpenGL=wxConfigBase::Get()->Read(wxT("DisableOpenGL"), 0l);
00289         if(noOpenGL==1)
00290         {
00291             XRCCTRL(dlg, "disable_dont_ask_checkbox", wxCheckBox)->SetValue(true);
00292         };
00293         if(dlg.ShowModal()==wxID_OK)
00294         {
00295             if(XRCCTRL(dlg, "disable_dont_ask_checkbox", wxCheckBox)->IsChecked())
00296             {
00297                 wxConfigBase::Get()->Write(wxT("DisableOpenGL"), 1l);
00298             }
00299             else
00300             {
00301                 wxConfigBase::Get()->Write(wxT("DisableOpenGL"), 0l);
00302             };
00303             disableOpenGL=true;
00304         }
00305         else
00306         {
00307             wxConfigBase::Get()->Write(wxT("DisableOpenGL"), 0l);
00308         };
00309     }
00310     else
00311     {
00312         long noOpenGL=wxConfigBase::Get()->Read(wxT("DisableOpenGL"), 0l);
00313         disableOpenGL=(noOpenGL==1);
00314     };
00315 
00316     wxBitmap bitmap;
00317     HuginSplashScreen* splash = 0;
00318     wxYield();
00319 
00320     if (bitmap.LoadFile(huginApp::Get()->GetXRCPath() + wxT("data/splash.png"), wxBITMAP_TYPE_PNG))
00321     {
00322         // embed package version into string.
00323         {
00324             wxMemoryDC dc;
00325             dc.SelectObject(bitmap);
00326 #ifdef __WXMAC__
00327             wxFont font(9, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
00328 #else
00329             wxFont font(8, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
00330 #endif
00331             dc.SetFont(font);
00332             dc.SetTextForeground(*wxBLACK);
00333             dc.SetTextBackground(*wxWHITE);
00334             int tw, th;
00335             wxString version;
00336             version.Printf(_("Version %s"), wxString(hugin_utils::GetHuginVersion().c_str(), wxConvLocal).c_str());
00337             dc.GetTextExtent(version, &tw, &th);
00338             // place text on bitmap.
00339             dc.DrawText(version, bitmap.GetWidth() - tw - 3, bitmap.GetHeight() - th - 3);
00340             dc.SelectObject(wxNullBitmap);
00341         }
00342 
00343         splash = new HuginSplashScreen(NULL, bitmap);
00344     } else {
00345         wxLogFatalError(_("Fatal installation error\nThe file data/splash.png was not found at:") + huginApp::Get()->GetXRCPath());
00346         abort();
00347     }
00348     //splash->Refresh();
00349     wxYield();
00350 
00351     // save our pointer
00352     m_this = this;
00353 
00354     DEBUG_TRACE("");
00355     // load our children. some children might need special
00356     // initialization. this will be done later.
00357     wxXmlResource::Get()->LoadFrame(this, parent, wxT("main_frame"));
00358     DEBUG_TRACE("");
00359 
00360     // load our menu bar
00361 #ifdef __WXMAC__
00362     wxApp::s_macAboutMenuItemId = XRCID("action_show_about");
00363     wxApp::s_macPreferencesMenuItemId = XRCID("action_show_prefs");
00364     wxApp::s_macExitMenuItemId = XRCID("action_exit_hugin");
00365     wxApp::s_macHelpMenuTitleName = _("&Help");
00366 #endif
00367     wxMenuBar* mainMenu=wxXmlResource::Get()->LoadMenuBar(this, wxT("main_menubar"));
00368     m_menu_file_simple=wxXmlResource::Get()->LoadMenu(wxT("file_menu_simple"));
00369     m_menu_file_advanced=wxXmlResource::Get()->LoadMenu(wxT("file_menu_advanced"));
00370     mainMenu->Insert(0, m_menu_file_simple, _("&File"));
00371     SetMenuBar(mainMenu);
00372     SetOptimizeOnlyActiveImages(m_optOnlyActiveImages);
00373 
00374 #ifdef HUGIN_HSI
00375     wxMenuBar* menubar=GetMenuBar();
00376     // the plugin menu will be generated dynamically
00377     wxMenu *pluginMenu=new wxMenu();
00378     // search for all .py files in plugins directory
00379     wxDir dir(GetDataPath()+wxT("plugins"));
00380     if (dir.IsOpened())
00381     {
00382         wxString filename;
00383         bool cont = dir.GetFirst(&filename, wxT("*.py"), wxDIR_FILES | wxDIR_HIDDEN);
00384         PluginItems items;
00385         while (cont)
00386         {
00387             wxFileName file(dir.GetName(), filename);
00388             file.MakeAbsolute();
00389             PluginItem item(file);
00390             if (item.IsAPIValid())
00391             {
00392                 items.push_back(item);
00393             };
00394             cont = dir.GetNext(&filename);
00395         };
00396         items.sort(comparePluginItem);
00397 
00398         int pluginID = wxIDPYTHONSCRIPTS;
00399         for (PluginItems::const_iterator it = items.begin(); it != items.end(); ++it)
00400         {
00401             PluginItem item = *it;
00402             int categoryID = pluginMenu->FindItem(item.GetCategory());
00403             wxMenu* categoryMenu;
00404             if (categoryID == wxNOT_FOUND)
00405             {
00406                 categoryMenu = new wxMenu();
00407                 pluginMenu->AppendSubMenu(categoryMenu, item.GetCategory());
00408             }
00409             else
00410             {
00411                 categoryMenu = pluginMenu->FindItem(categoryID)->GetSubMenu();
00412             };
00413             categoryMenu->Append(pluginID, item.GetName(), item.GetDescription());
00414             m_plugins[pluginID] = item.GetFilename();
00415             Connect(pluginID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnPlugin));
00416             pluginID++;
00417         };
00418         // show the new menu
00419         if (pluginMenu->GetMenuItemCount() > 0)
00420         {
00421             menubar->Insert(menubar->GetMenuCount() - 2, pluginMenu, _("&Actions"));
00422         };
00423     };
00424 #else
00425     GetMenuBar()->Enable(XRCID("action_python_script"), false);
00426 #endif
00427 
00428     // add saved user defined output sequences
00429     {
00430         wxArrayString files;
00431         // search all .executor files, do not follow links
00432         wxDir::GetAllFiles(GetDataPath(), &files, wxT("*.executor"), wxDIR_FILES | wxDIR_HIDDEN | wxDIR_NO_FOLLOW);
00433         if (!files.IsEmpty())
00434         {
00435             // we found some files
00436             long outputId = wxIDUSEROUTPUTSEQUENCE;
00437             int outputMenuId=mainMenu->FindMenu(_("Output"));
00438             if (outputMenuId != wxNOT_FOUND)
00439             {
00440                 wxMenu* outputSequencesMenu = new wxMenu;
00441                 for (auto file : files)
00442                 {
00443                     wxFileInputStream inputStream(file);
00444                     if (inputStream.IsOk())
00445                     {
00446                         // read descriptions from file
00447                         wxFileConfig executorFile(inputStream);
00448                         wxString desc = executorFile.Read(wxT("/General/Description"), wxEmptyString);
00449                         desc = desc.Trim(true).Trim(false);
00450                         wxString help = executorFile.Read(wxT("/General/Help"), wxEmptyString);
00451                         help = help.Trim(true).Trim(false);
00452                         if (help.IsEmpty())
00453                         {
00454                             help = wxString::Format(_("User defined sequence: %s"), file);
00455                         };
00456                         // add menu
00457                         if (!desc.IsEmpty())
00458                         {
00459                             outputSequencesMenu->Append(outputId, desc, help);
00460                             Bind(wxEVT_MENU, &MainFrame::OnUserDefinedStitchSaved, this, outputId);
00461                             m_userOutput[outputId] = file;
00462                             ++outputId;
00463                         };
00464                     };
00465                 };
00466                 if (outputSequencesMenu->GetMenuItemCount() > 0)
00467                 {
00468                     mainMenu->GetMenu(outputMenuId)->AppendSubMenu(outputSequencesMenu, _("User defined output sequences"));
00469                 }
00470                 else
00471                 {
00472                     delete outputSequencesMenu;
00473                 };
00474             };
00475         };
00476     };
00477     // create tool bar
00478     SetToolBar(wxXmlResource::Get()->LoadToolBar(this, wxT("main_toolbar")));
00479 
00480     // Disable tools by default
00481     enableTools(false);
00482 
00483     // put an "unknown" object in an xrc file and
00484     // take as wxObject (second argument) the return value of wxXmlResource::Get
00485     // finish the images_panel
00486     DEBUG_TRACE("");
00487 
00488     // image_panel
00489     images_panel = XRCCTRL(*this, "images_panel_unknown", ImagesPanel);
00490     assert(images_panel);
00491     images_panel->Init(&pano);
00492     DEBUG_TRACE("");
00493 
00494     m_notebook = XRCCTRL((*this), "controls_notebook", wxNotebook);
00495 //    m_notebook = ((wxNotebook*) ((*this).FindWindow(XRCID("controls_notebook"))));
00496 //    m_notebook = ((wxNotebook*) (FindWindow(XRCID("controls_notebook"))));
00497     DEBUG_ASSERT(m_notebook);
00498 
00499     // the mask panel
00500     mask_panel = XRCCTRL(*this, "mask_panel_unknown", MaskEditorPanel);
00501     assert(mask_panel);
00502     mask_panel->Init(&pano);
00503 
00504     // the pano_panel
00505     DEBUG_TRACE("");
00506     pano_panel = XRCCTRL(*this, "panorama_panel_unknown", PanoPanel);
00507     assert(pano_panel);
00508     pano_panel->Init(&pano);
00509     pano_panel->panoramaChanged (pano); // initialize from pano
00510 
00511     cpe = XRCCTRL(*this, "cp_editor_panel_unknown", CPEditorPanel);
00512     assert(cpe);
00513     cpe->Init(&pano);
00514 
00515     opt_panel = XRCCTRL(*this, "optimizer_panel_unknown", OptimizePanel);
00516     assert(opt_panel);
00517     opt_panel->Init(&pano);
00518     m_show_opt_panel=true;
00519 
00520     opt_photo_panel = XRCCTRL(*this, "optimizer_photometric_panel_unknown", OptimizePhotometricPanel);
00521     assert(opt_photo_panel);
00522     opt_photo_panel->Init(&pano);
00523     m_show_opt_photo_panel=true;
00524 
00525     // generate list of most recently uses files and add it to menu
00526     // needs to be initialized before the fast preview, there we call AddFilesToMenu()
00527     wxConfigBase * config=wxConfigBase::Get();
00528     m_mruFiles.Load(*config);
00529     m_mruFiles.UseMenu(m_menu_file_advanced->FindItem(XRCID("menu_mru"))->GetSubMenu());
00530 
00531     preview_frame = new PreviewFrame(this, pano);
00532     if(disableOpenGL)
00533     {
00534         gl_preview_frame=NULL;
00535         DisableOpenGLTools();
00536         m_mruFiles.AddFilesToMenu();
00537     }
00538     else
00539     {
00540         gl_preview_frame = new GLPreviewFrame(this, pano);
00541     };
00542 
00543     // set the minimize icon
00544 #ifdef __WXMSW__
00545     wxIcon myIcon(GetXRCPath() + wxT("data/hugin.ico"),wxBITMAP_TYPE_ICO);
00546 #else
00547     wxIcon myIcon(GetXRCPath() + wxT("data/hugin.png"),wxBITMAP_TYPE_PNG);
00548 #endif
00549     SetIcon(myIcon);
00550 
00551     // create a new drop handler. wxwindows deletes the automaticall
00552     SetDropTarget(new PanoDropTarget(pano));
00553     DEBUG_TRACE("");
00554 
00555     PanoOperation::GeneratePanoOperationVector();
00556 
00557     // create a status bar
00558     const int fields (2);
00559     CreateStatusBar(fields);
00560     int widths[fields] = {-1, 85};
00561     SetStatusWidths( fields, &widths[0]);
00562     SetStatusText(_("Started"), 0);
00563     wxYield();
00564     DEBUG_TRACE("");
00565 
00566     // observe the panorama
00567     pano.addObserver(this);
00568 
00569     // Set sizing characteristics
00570     //set minumum size
00571 #if defined __WXMAC__ || defined __WXMSW__
00572     // a minimum nice looking size; smaller than this would clutter the layout.
00573     SetSizeHints(900, 675);
00574 #else
00575     // For ASUS eeePc
00576     SetSizeHints(780, 455); //set minumum size
00577 #endif
00578 
00579     // set progress display for image cache.
00580     ImageCache::getInstance().setProgressDisplay(this);
00581 #if defined __WXMSW__
00582     unsigned long long mem = HUGIN_IMGCACHE_UPPERBOUND;
00583     unsigned long mem_low = wxConfigBase::Get()->Read(wxT("/ImageCache/UpperBound"), HUGIN_IMGCACHE_UPPERBOUND);
00584     unsigned long mem_high = wxConfigBase::Get()->Read(wxT("/ImageCache/UpperBoundHigh"), (long) 0);
00585     if (mem_high > 0) {
00586       mem = ((unsigned long long) mem_high << 32) + mem_low;
00587     }
00588     else {
00589       mem = mem_low;
00590     }
00591     ImageCache::getInstance().SetUpperLimit(mem);
00592 #else
00593     ImageCache::getInstance().SetUpperLimit(wxConfigBase::Get()->Read(wxT("/ImageCache/UpperBound"), HUGIN_IMGCACHE_UPPERBOUND));
00594 #endif
00595 
00596     if(splash) {
00597         splash->Close();
00598         delete splash;
00599     }
00600     wxYield();
00601 
00602     // disable automatic Layout() calls, to it by hand
00603     SetAutoLayout(false);
00604 
00605 
00606 #ifdef __WXMSW__
00607     // wxFrame does have a strange background color on Windows, copy color from a child widget
00608     this->SetBackgroundColour(images_panel->GetBackgroundColour());
00609 #endif
00610 
00611 // By using /SUBSYSTEM:CONSOLE /ENTRY:"WinMainCRTStartup" in the linker
00612 // options for the debug build, a console window will be used for stdout
00613 // and stderr. No need to redirect to a file. Better security since we can't
00614 // guarantee that c: exists and writing a file to the root directory is
00615 // never a good idea. release build still uses /SUBSYSTEM:WINDOWS
00616 
00617 #if 0
00618 #ifdef DEBUG
00619 #ifdef __WXMSW__
00620 
00621     freopen("c:\\hugin_stdout.txt", "w", stdout);    // redirect stdout to file
00622     freopen("c:\\hugin_stderr.txt", "w", stderr);    // redirect stderr to file
00623 #endif
00624 #endif
00625 #endif
00626     //reload gui level
00627     m_guiLevel=GUI_ADVANCED;
00628     long guiLevel=config->Read(wxT("/GuiLevel"),(long)0);
00629     guiLevel = std::max<long>(0, std::min<long>(2, guiLevel));
00630     if(guiLevel==GUI_SIMPLE && disableOpenGL)
00631     {
00632         guiLevel=GUI_ADVANCED;
00633     };
00634     SetGuiLevel((GuiLevel)guiLevel);
00635 
00636     DEBUG_TRACE("");
00637 #ifdef __WXGTK__
00638     // set explicit focus to assistant panel for better processing key presses
00639     images_panel->SetFocus();
00640 #endif
00641 }
00642 
00643 MainFrame::~MainFrame()
00644 {
00645     DEBUG_TRACE("dtor");
00646     if(m_guiLevel==GUI_SIMPLE)
00647     {
00648         delete m_menu_file_advanced;
00649     }
00650     else
00651     {
00652         delete m_menu_file_simple;
00653     };
00654     ImageCache::getInstance().setProgressDisplay(NULL);
00655         delete & ImageCache::getInstance();
00656     delete & PanoCommand::GlobalCmdHist::getInstance();
00657 //    delete cpe;
00658 //    delete images_panel;
00659     DEBUG_DEBUG("removing observer");
00660     pano.removeObserver(this);
00661 
00662     // get the global config object
00663     wxConfigBase* config = wxConfigBase::Get();
00664 
00665     StoreFramePosition(this, wxT("MainFrame"));
00666 
00667     //store most recently used files
00668     m_mruFiles.Save(*config);
00669     //store gui level
00670     config->Write(wxT("/GuiLevel"),(long)m_guiLevel);
00671     config->Flush();
00672     if(svmModel!=NULL)
00673     {
00674         celeste::destroySVMmodel(svmModel);
00675     };
00676     PanoOperation::CleanPanoOperationVector();
00677 
00678     DEBUG_TRACE("dtor end");
00679 }
00680 
00681 void MainFrame::panoramaChanged(HuginBase::Panorama &pano)
00682 {
00683     wxToolBar* theToolBar = GetToolBar();
00684     wxMenuBar* theMenuBar = GetMenuBar();
00685     bool can_undo = PanoCommand::GlobalCmdHist::getInstance().canUndo();
00686     theMenuBar->Enable    (XRCID("ID_EDITUNDO"), can_undo);
00687     theToolBar->EnableTool(XRCID("ID_EDITUNDO"), can_undo);
00688     bool can_redo = PanoCommand::GlobalCmdHist::getInstance().canRedo();
00689     theMenuBar->Enable    (XRCID("ID_EDITREDO"), can_redo);
00690     theToolBar->EnableTool(XRCID("ID_EDITREDO"), can_redo);
00691 
00692     //show or hide optimizer and exposure optimizer tab depending on optimizer master switches
00693     if(pano.getOptimizerSwitch()==0 && !m_show_opt_panel)
00694     {
00695         m_notebook->InsertPage(3, opt_panel, _("Optimizer"));
00696         m_show_opt_panel=true;
00697     };
00698     if(pano.getOptimizerSwitch()!=0 && m_show_opt_panel)
00699     {
00700         m_notebook->RemovePage(3);
00701         m_show_opt_panel=false;
00702     };
00703     if(pano.getPhotometricOptimizerSwitch()==0 && !m_show_opt_photo_panel)
00704     {
00705         if(m_show_opt_panel)
00706         {
00707             m_notebook->InsertPage(4, opt_photo_panel, _("Exposure"));
00708         }
00709         else
00710         {
00711             m_notebook->InsertPage(3, opt_photo_panel, _("Exposure"));
00712         }
00713         m_show_opt_photo_panel=true;
00714     };
00715     if(pano.getPhotometricOptimizerSwitch()!=0 && m_show_opt_photo_panel)
00716     {
00717         if(m_show_opt_panel)
00718         {
00719             m_notebook->RemovePage(4);
00720         }
00721         else
00722         {
00723             m_notebook->RemovePage(3);
00724         };
00725         m_show_opt_photo_panel=false;
00726     };
00727     theMenuBar->Enable(XRCID("ID_SHOW_PANEL_OPTIMIZER"), m_show_opt_panel);
00728     theMenuBar->Enable(XRCID("ID_SHOW_PANEL_OPTIMIZER_PHOTOMETRIC"), m_show_opt_photo_panel);
00729 }
00730 
00731 //void MainFrame::panoramaChanged(HuginBase::Panorama &panorama)
00732 void MainFrame::panoramaImagesChanged(HuginBase::Panorama &panorama, const HuginBase::UIntSet & changed)
00733 {
00734     DEBUG_TRACE("");
00735     assert(&pano == &panorama);
00736     if (pano.getNrOfImages() == 0) {
00737           enableTools(false);
00738         } else {
00739           enableTools(true);
00740         }
00741     GetMenuBar()->Enable(XRCID("action_assistant"), pano.getNrOfImages()>=2);
00742     GetMenuBar()->Enable(XRCID("action_batch_assistant"), pano.getNrOfImages()>=2);
00743 }
00744 
00745 void MainFrame::OnUserQuit(wxCommandEvent & e)
00746 {
00747     Close();
00748 }
00749 
00750 bool MainFrame::CloseProject(bool cancelable)
00751 {
00752     if (pano.isDirty()) {
00753         wxMessageDialog message(wxGetActiveWindow(),
00754                                 _("Save changes to the panorama before closing?"),
00755 #ifdef _WIN32
00756                                 _("Hugin"),
00757 #else
00758                                 wxT(""),
00759 #endif
00760                                 wxICON_EXCLAMATION | wxYES_NO | (cancelable? (wxCANCEL):0));
00761     message.SetExtendedMessage(_("If you close without saving, changes since your last save will be discarded"));
00762     #if defined __WXMAC__ || defined __WXMSW__
00763         // Apple human interface guidelines and Windows user experience interaction guidelines
00764         message.SetYesNoLabels(wxID_SAVE, _("Don't Save"));
00765     #else
00766         // Gnome human interface guidelines:
00767         message.SetYesNoLabels(wxID_SAVE, _("Close without saving"));
00768     #endif
00769         int answer = message.ShowModal();
00770         switch (answer){
00771             case wxID_YES:
00772             {
00773                 wxCommandEvent dummy;
00774                 OnSaveProject(dummy);
00775                 return !pano.isDirty();
00776             }
00777             case wxID_CANCEL:
00778                 return false;
00779             default: //no save
00780                 return true;
00781         }
00782     }
00783     else return true;
00784 }
00785 
00786 void MainFrame::OnExit(wxCloseEvent & e)
00787 {
00788     DEBUG_TRACE("");
00789     if(m_guiLevel!=GUI_SIMPLE)
00790     {
00791         if(!CloseProject(e.CanVeto()))
00792         {
00793            if (e.CanVeto())
00794            {
00795                 e.Veto();
00796                 return;
00797            }
00798            wxLogError(_("forced close"));
00799         }
00800     }
00801     else
00802     {
00803         if(e.CanVeto())
00804         {
00805             Hide();
00806             e.Veto();
00807             return;
00808         };
00809     };
00810 
00811     if(preview_frame)
00812     {
00813        preview_frame->Close(true);
00814     }
00815 
00816     ImageCache::getInstance().flush();
00817     Destroy();
00818     DEBUG_TRACE("");
00819 }
00820 
00821 void MainFrame::OnSaveProject(wxCommandEvent & e)
00822 {
00823     DEBUG_TRACE("");
00824     try {
00825     wxFileName scriptName = m_filename;
00826     if (m_filename == wxT("")) {
00827         OnSaveProjectAs(e);
00828         scriptName = m_filename;
00829     } else {
00830         // the project file is just a PTOptimizer script...
00831         std::string path = hugin_utils::getPathPrefix(std::string(scriptName.GetFullPath().mb_str(HUGIN_CONV_FILENAME)));
00832         DEBUG_DEBUG("stripping " << path << " from image filenames");
00833         std::ofstream script(scriptName.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
00834         script.exceptions ( std::ofstream::eofbit | std::ofstream::failbit | std::ofstream::badbit );
00835         HuginBase::UIntSet all;
00836         if (pano.getNrOfImages() > 0) {
00837            fill_set(all, 0, pano.getNrOfImages()-1);
00838         }
00839         pano.printPanoramaScript(script, pano.getOptimizeVector(), pano.getOptions(), all, false, path);
00840         script.close();
00841 
00842         SetStatusText(wxString::Format(_("saved project %s"), m_filename.c_str()),0);
00843         if(m_guiLevel==GUI_SIMPLE)
00844         {
00845             if(gl_preview_frame)
00846             {
00847                 gl_preview_frame->SetTitle(scriptName.GetName() + wxT(".") + scriptName.GetExt() + wxT(" - ") + _("Hugin - Panorama Stitcher"));
00848             };
00849             SetTitle(scriptName.GetName() + wxT(".") + scriptName.GetExt() + wxT(" - ") + _("Panorama editor"));
00850         }
00851         else
00852         {
00853             SetTitle(scriptName.GetName() + wxT(".") + scriptName.GetExt() + wxT(" - ") + _("Hugin - Panorama Stitcher"));
00854         };
00855 
00856         pano.clearDirty();
00857     }
00858     } catch (std::exception & e) {
00859         wxString err(e.what(), wxConvLocal);
00860             wxMessageBox(wxString::Format(_("Could not save project file \"%s\".\nMaybe the file or the folder is read-only.\n\n(Error code: %s)"),m_filename.c_str(),err.c_str()),_("Error"),wxOK|wxICON_ERROR);
00861     }
00862 }
00863 
00864 void MainFrame::OnSaveProjectAs(wxCommandEvent & e)
00865 {
00866     DEBUG_TRACE("");
00867     wxFileName scriptName;
00868     if (m_filename.IsEmpty())
00869     {
00870         scriptName.Assign(getDefaultProjectName(pano) + wxT(".pto"));
00871     }
00872     else
00873     {
00874         scriptName=m_filename;
00875     };
00876     scriptName.Normalize();
00877     wxFileDialog dlg(wxGetActiveWindow(),
00878                      _("Save project file"),
00879                      scriptName.GetPath(), scriptName.GetFullName(),
00880                      _("Project files (*.pto)|*.pto|All files (*)|*"),
00881                      wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
00882     if (dlg.ShowModal() == wxID_OK) {
00883         wxConfig::Get()->Write(wxT("/actualPath"), dlg.GetDirectory());  // remember for later
00884         wxString fn = dlg.GetPath();
00885         if (fn.Right(4).CmpNoCase(wxT(".pto"))!=0)
00886         {
00887             fn.Append(wxT(".pto"));
00888             if (wxFile::Exists(fn)) {
00889                 int d = wxMessageBox(wxString::Format(_("File %s exists. Overwrite?"), fn.c_str()),
00890                     _("Save project"), wxYES_NO | wxICON_QUESTION);
00891                 if (d != wxYES) {
00892                     return;
00893                 }
00894             }
00895         }
00896         m_filename = fn;
00897         m_mruFiles.AddFileToHistory(m_filename);
00898         OnSaveProject(e);
00899     }
00900 }
00901 
00902 void MainFrame::OnSavePTStitcherAs(wxCommandEvent & e)
00903 {
00904     DEBUG_TRACE("");
00905     wxString scriptName = m_filename;
00906     if (m_filename == wxT("")) {
00907         scriptName = getDefaultProjectName(pano);
00908     }
00909     wxFileName scriptNameFN(scriptName);
00910     wxString fn = scriptNameFN.GetName() + wxT(".txt");
00911     wxFileDialog dlg(wxGetActiveWindow(),
00912                      _("Save PTmender script file"),
00913                      wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")), fn,
00914                      _("PTmender files (*.txt)|*.txt"),
00915                      wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
00916     if (dlg.ShowModal() == wxID_OK) {
00917         wxString fname = dlg.GetPath();
00918         // the project file is just a PTStitcher script...
00919         wxFileName scriptName = fname;
00920         HuginBase::UIntSet all;
00921         if (pano.getNrOfImages() > 0) {
00922             fill_set(all, 0, pano.getNrOfImages()-1);
00923         }
00924         std::ofstream script(scriptName.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
00925         pano.printStitcherScript(script, pano.getOptions(), all);
00926         script.close();
00927     }
00928 
00929 }
00930 
00931 void MainFrame::LoadProjectFile(const wxString & filename)
00932 {
00933     DEBUG_TRACE("");
00934     m_filename = filename;
00935 
00936     // remove old images from cache
00937     // hmm probably not a good idea, if the project is reloaded..
00938     // ImageCache::getInstance().flush();
00939 
00940     SetStatusText( _("Open project:   ") + filename);
00941 
00942     wxFileName fname(filename);
00943     wxString path = fname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
00944     if (fname.IsOk() && fname.FileExists()) {
00945         wxBusyCursor wait;
00946         deregisterPTWXDlgFcn();
00947         PanoCommand::GlobalCmdHist::getInstance().addCommand(
00948             new PanoCommand::wxLoadPTProjectCmd(pano, (const char *)filename.mb_str(HUGIN_CONV_FILENAME), (const char *)path.mb_str(HUGIN_CONV_FILENAME), true)
00949            );
00950         PanoCommand::GlobalCmdHist::getInstance().clear();
00951         registerPTWXDlgFcn();
00952         DEBUG_DEBUG("project contains " << pano.getNrOfImages() << " after load");
00953         GuiLevel reqGuiLevel=GetMinimumGuiLevel(pano);
00954         if(reqGuiLevel>m_guiLevel)
00955         {
00956             SetGuiLevel(reqGuiLevel);
00957         };
00958         SetStatusText(_("Project opened"));
00959         m_mruFiles.AddFileToHistory(fname.GetFullPath());
00960         if(m_guiLevel==GUI_SIMPLE)
00961         {
00962             if(gl_preview_frame)
00963             {
00964                 gl_preview_frame->SetTitle(fname.GetName() + wxT(".") + fname.GetExt() + wxT(" - ") + _("Hugin - Panorama Stitcher"));
00965             };
00966             SetTitle(fname.GetName() + wxT(".") + fname.GetExt() + wxT(" - ") + _("Panorama editor"));
00967         }
00968         else
00969         {
00970             SetTitle(fname.GetName() + wxT(".") + fname.GetExt() + wxT(" - ") + _("Hugin - Panorama Stitcher"));
00971         };
00972         if (! (fname.GetExt() == wxT("pto"))) {
00973             // do not remember filename if its not a hugin project
00974             // to avoid overwriting the original project with an
00975             // incompatible one
00976             m_filename = wxT("");
00977         }
00978         // get the global config object
00979         wxConfigBase* config = wxConfigBase::Get();
00980         config->Write(wxT("/actualPath"), path);  // remember for later
00981     } else {
00982         SetStatusText( _("Error opening project:   ") + filename);
00983         DEBUG_ERROR("Could not open file " << filename);
00984     }
00985 
00986     // force update of preview window
00987     if ( !(preview_frame->IsIconized() ||(! preview_frame->IsShown()) ) ) {
00988         wxCommandEvent dummy;
00989         preview_frame->OnUpdate(dummy);
00990     }
00991 }
00992 
00993 #ifdef __WXMAC__
00994 void MainFrame::MacOnOpenFile(const wxString & filename)
00995 {
00996     if(!CloseProject(true)) return; //if closing old project is canceled do nothing.
00997 
00998     ImageCache::getInstance().flush();
00999     LoadProjectFile(filename);
01000 }
01001 #endif
01002 
01003 void MainFrame::OnLoadProject(wxCommandEvent & e)
01004 {
01005     DEBUG_TRACE("");
01006 
01007     if(CloseProject(true)) //if closing old project is canceled do nothing.
01008     {
01009         // get the global config object
01010         wxConfigBase* config = wxConfigBase::Get();
01011 
01012         wxString defaultdir = config->Read(wxT("/actualPath"),wxT(""));
01013         wxFileDialog dlg(wxGetActiveWindow(),
01014                          _("Open project file"),
01015                          defaultdir, wxT(""),
01016                          _("Project files (*.pto)|*.pto|All files (*)|*"),
01017                          wxFD_OPEN, wxDefaultPosition);
01018         dlg.SetDirectory(defaultdir);
01019         if (dlg.ShowModal() == wxID_OK)
01020         {
01021             wxString filename = dlg.GetPath();
01022             if(vigra::isImage(filename.mb_str(HUGIN_CONV_FILENAME)))
01023             {
01024                 if(wxMessageBox(wxString::Format(_("File %s is an image file and not a project file.\nThis file can't be open with File, Open.\nDo you want to add this image file to the current project?"),filename.c_str()),
01025 #ifdef __WXMSW__
01026                     _("Hugin"),
01027 #else
01028                     wxT(""),
01029 #endif
01030                     wxYES_NO | wxICON_QUESTION)==wxYES)
01031                 {
01032                     wxArrayString filenameArray;
01033                     filenameArray.Add(filename);
01034                     AddImages(filenameArray);
01035                 };
01036                 return;
01037             }
01038             else
01039             {
01040                 // remove old images from cache
01041                 ImageCache::getInstance().flush();
01042 
01043                 LoadProjectFile(filename);
01044                 return;
01045             };
01046         }
01047     }
01048     // do not close old project
01049     // nothing to open
01050     SetStatusText( _("Open project: cancel"));
01051 }
01052 
01053 void MainFrame::OnNewProject(wxCommandEvent & e)
01054 {
01055     if(!CloseProject(true)) return; //if closing current project is canceled
01056 
01057     m_filename = wxT("");
01058     PanoCommand::GlobalCmdHist::getInstance().addCommand(new PanoCommand::wxNewProjectCmd(pano));
01059     PanoCommand::GlobalCmdHist::getInstance().clear();
01060     // remove old images from cache
01061     ImageCache::getInstance().flush();
01062     if(m_guiLevel==GUI_SIMPLE)
01063     {
01064         if(gl_preview_frame)
01065         {
01066             gl_preview_frame->SetTitle(_("Hugin - Panorama Stitcher"));
01067         };
01068         SetTitle(_("Panorama editor"));
01069     }
01070     else
01071     {
01072         SetTitle(_("Hugin - Panorama Stitcher"));
01073     };
01074 
01075     wxCommandEvent dummy;
01076     preview_frame->OnUpdate(dummy);
01077 }
01078 
01079 void MainFrame::OnAddImages( wxCommandEvent& event )
01080 {
01081     DEBUG_TRACE("");
01082     PanoOperation::AddImageOperation addImage;
01083     HuginBase::UIntSet images;
01084     PanoCommand::PanoCommand* cmd = addImage.GetCommand(wxGetActiveWindow(), pano, images, m_guiLevel);
01085     if(cmd!=NULL)
01086     {
01087         PanoCommand::GlobalCmdHist::getInstance().addCommand(cmd);
01088     }
01089     else
01090     {
01091         // nothing to open
01092         SetStatusText( _("Add Image: cancel"));
01093     }
01094 
01095     DEBUG_TRACE("");
01096 }
01097 
01098 void MainFrame::AddImages(wxArrayString& filenameArray)
01099 {
01100     wxArrayString invalidFiles;
01101     for(unsigned int i=0;i<filenameArray.GetCount(); i++)
01102     {
01103         if(containsInvalidCharacters(filenameArray[i]))
01104         {
01105             invalidFiles.Add(filenameArray[i]);
01106         };
01107     };
01108     if(invalidFiles.size()>0)
01109     {
01110         ShowFilenameWarning(this, invalidFiles);
01111     }
01112     else
01113     {
01114         std::vector<std::string> filesv;
01115         for (unsigned int i=0; i< filenameArray.GetCount(); i++) {
01116             filesv.push_back((const char *)filenameArray[i].mb_str(HUGIN_CONV_FILENAME));
01117         }
01118 
01119         // we got some images to add.
01120         if (filesv.size() > 0) {
01121             // use a Command to ensure proper undo and updating of GUI
01122             // parts
01123             wxBusyCursor();
01124             PanoCommand::GlobalCmdHist::getInstance().addCommand(
01125                 new PanoCommand::wxAddImagesCmd(pano, filesv)
01126                 );
01127         };
01128     };
01129 };
01130 
01131 void MainFrame::OnAddTimeImages( wxCommandEvent& event )
01132 {
01133     PanoOperation::AddImagesSeriesOperation imageSeriesOp;
01134     HuginBase::UIntSet images;
01135     PanoCommand::PanoCommand* cmd = imageSeriesOp.GetCommand(wxGetActiveWindow(), pano, images, m_guiLevel);
01136     if(cmd!=NULL)
01137     {
01138         PanoCommand::GlobalCmdHist::getInstance().addCommand(cmd);
01139     };
01140 };
01141 
01142 void MainFrame::OnShowDonate(wxCommandEvent & e)
01143 {
01144     wxLaunchDefaultBrowser(wxT("http://sourceforge.net/project/project_donations.php?group_id=77506"));
01145 }
01146 
01147 
01148 void MainFrame::OnShowPanel(wxCommandEvent & e)
01149 {
01150     if(e.GetId()==XRCID("ID_SHOW_PANEL_MASK"))
01151         m_notebook->SetSelection(1);
01152     else
01153         if(e.GetId()==XRCID("ID_SHOW_PANEL_CP_EDITOR"))
01154             m_notebook->SetSelection(2);
01155         else
01156             if(e.GetId()==XRCID("ID_SHOW_PANEL_OPTIMIZER"))
01157                 m_notebook->SetSelection(3);
01158             else
01159                 if(e.GetId()==XRCID("ID_SHOW_PANEL_OPTIMIZER_PHOTOMETRIC"))
01160                 {
01161                     if(m_show_opt_panel)
01162                     {
01163                         m_notebook->SetSelection(4);
01164                     }
01165                     else
01166                     {
01167                         m_notebook->SetSelection(3);
01168                     };
01169                 }
01170                 else
01171                     if(e.GetId()==XRCID("ID_SHOW_PANEL_PANORAMA"))
01172                     {
01173                         if(m_show_opt_panel && m_show_opt_photo_panel)
01174                         {
01175                             m_notebook->SetSelection(5);
01176                         }
01177                         else
01178                         {
01179                             if(m_show_opt_panel || m_show_opt_photo_panel)
01180                             {
01181                                 m_notebook->SetSelection(4);
01182                             }
01183                             else
01184                             {
01185                                 m_notebook->SetSelection(3);
01186                             };
01187                         };
01188                     }
01189                     else
01190                         m_notebook->SetSelection(0);
01191 }
01192 
01193 void MainFrame::OnLoadingFailed(wxCommandEvent & e)
01194 {
01195     // check if file exists
01196     if (wxFileExists(e.GetString()))
01197     {
01198         // file exists, but could not loaded
01199         wxMessageBox(wxString::Format(_("Could not load image \"%s\".\nThis file is not a valid image.\nThis file will be removed from the project."), e.GetString()),
01200 #ifdef _WIN32
01201             _("Hugin"),
01202 #else
01203             wxT(""),
01204 #endif
01205             wxOK | wxICON_ERROR);
01206     }
01207     else
01208     {
01209         // file does not exists
01210         wxMessageBox(wxString::Format(_("Could not load image \"%s\".\nThis file was renamed, deleted or is on a non-accessible drive.\nThis file will be removed from the project."), e.GetString()),
01211 #ifdef _WIN32
01212             _("Hugin"),
01213 #else
01214             wxT(""),
01215 #endif
01216             wxOK | wxICON_ERROR);
01217     };
01218     // now remove the file from the pano
01219     const std::string filename(e.GetString().mb_str(HUGIN_CONV_FILENAME));
01220     HuginBase::UIntSet imagesToRemove;
01221     for (size_t i = 0; i < pano.getNrOfImages(); ++i)
01222     {
01223         if (pano.getImage(i).getFilename() == filename)
01224         {
01225             imagesToRemove.insert(i);
01226         };
01227     };
01228     if (!imagesToRemove.empty())
01229     {
01230         PanoCommand::GlobalCmdHist::getInstance().addCommand(new PanoCommand::RemoveImagesCmd(pano, imagesToRemove));
01231     };
01232 }
01233 
01234 
01235 void MainFrame::OnAbout(wxCommandEvent & e)
01236 {
01237     AboutDialog dlg(wxGetActiveWindow());
01238     dlg.ShowModal();
01239 }
01240 
01241 /*
01242 void MainFrame::OnAbout(wxCommandEvent & e)
01243 {
01244     DEBUG_TRACE("");
01245     wxDialog dlg;
01246         wxString strFile;
01247         wxString langCode;
01248 
01249     wxXmlResource::Get()->LoadDialog(&dlg, this, wxT("about_dlg"));
01250 
01251 #if __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
01252     //rely on the system's locale choice
01253     strFile = MacGetPathToBundledResourceFile(CFSTR("about.htm"));
01254     if(strFile!=wxT("")) XRCCTRL(dlg,"about_html",wxHtmlWindow)->LoadPage(strFile);
01255 #else
01256     //if the language is not default, load custom About file (if exists)
01257     langCode = huginApp::Get()->GetLocale().GetName().Left(2).Lower();
01258     DEBUG_INFO("Lang Code: " << langCode.mb_str(wxConvLocal));
01259     if(langCode != wxString(wxT("en")))
01260     {
01261         strFile = GetXRCPath() + wxT("data/about_") + langCode + wxT(".htm");
01262         if(wxFile::Exists(strFile))
01263         {
01264             DEBUG_TRACE("Using About: " << strFile.mb_str(wxConvLocal));
01265             XRCCTRL(dlg,"about_html",wxHtmlWindow)->LoadPage(strFile);
01266         }
01267     }
01268 #endif
01269     dlg.ShowModal();
01270 }
01271 */
01272 
01273 void MainFrame::OnHelp(wxCommandEvent & e)
01274 {
01275     DisplayHelp();
01276 }
01277 
01278 void MainFrame::OnKeyboardHelp(wxCommandEvent & e)
01279 {
01280     DisplayHelp(wxT("Hugin_Keyboard_shortcuts.html"));
01281 }
01282 
01283 void MainFrame::OnFAQ(wxCommandEvent & e)
01284 {
01285     DisplayHelp(wxT("Hugin_FAQ.html"));
01286 }
01287 
01288 
01289 void MainFrame::DisplayHelp(wxString section)
01290 {
01291     if (section.IsEmpty())
01292     {
01293         GetHelpController().DisplayContents();
01294     }
01295     else
01296     {
01297 #if defined __wxMSW__ && !(wxCHECK_VERSION(3,1,1))
01298         // wxWidgets 3.x has a bug, that prevents DisplaySection to work on Win8/10 64 bit
01299         // see: http://trac.wxwidgets.org/ticket/14888
01300         // so using DisplayContents() and our own implementation of HuginCHMHelpController
01301         GetHelpController().DisplayHelpPage(section);
01302 #else
01303         GetHelpController().DisplaySection(section);
01304 #endif
01305     };
01306 }
01307 
01308 void MainFrame::OnTipOfDay(wxCommandEvent& WXUNUSED(e))
01309 {
01310     wxString strFile;
01311     bool bShowAtStartup;
01312 // DGSW FIXME - Unreferenced
01313 //      bool bTipsExist = false;
01314     int nValue;
01315 
01316     wxConfigBase * config = wxConfigBase::Get();
01317     nValue = config->Read(wxT("/MainFrame/ShowStartTip"),1l);
01318 
01319     //TODO: tips not localisable
01320     DEBUG_INFO("Tip index: " << nValue);
01321     strFile = GetXRCPath() + wxT("data/tips.txt");  //load default file
01322 
01323     DEBUG_INFO("Reading tips from " << strFile.mb_str(wxConvLocal));
01324     wxTipProvider *tipProvider = new LocalizedFileTipProvider(strFile, nValue);
01325     bShowAtStartup = wxShowTip(wxGetActiveWindow(), tipProvider, (nValue ? true : false));
01326 
01327     //store startup preferences
01328     nValue = (bShowAtStartup ? tipProvider->GetCurrentTip() : 0);
01329     DEBUG_INFO("Writing tip index: " << nValue);
01330     config->Write(wxT("/MainFrame/ShowStartTip"), nValue);
01331     delete tipProvider;
01332 }
01333 
01334 
01335 void MainFrame::OnShowPrefs(wxCommandEvent & e)
01336 {
01337     DEBUG_TRACE("");
01338     PreferencesDialog pref_dlg(wxGetActiveWindow());
01339     pref_dlg.ShowModal();
01340     //update image cache size
01341     wxConfigBase* cfg=wxConfigBase::Get();
01342 #if defined __WXMSW__
01343     unsigned long long mem = HUGIN_IMGCACHE_UPPERBOUND;
01344     unsigned long mem_low = cfg->Read(wxT("/ImageCache/UpperBound"), HUGIN_IMGCACHE_UPPERBOUND);
01345     unsigned long mem_high = cfg->Read(wxT("/ImageCache/UpperBoundHigh"), (long) 0);
01346     if (mem_high > 0)
01347     {
01348       mem = ((unsigned long long) mem_high << 32) + mem_low;
01349     }
01350     else
01351     {
01352       mem = mem_low;
01353     }
01354     ImageCache::getInstance().SetUpperLimit(mem);
01355 #else
01356     ImageCache::getInstance().SetUpperLimit(cfg->Read(wxT("/ImageCache/UpperBound"), HUGIN_IMGCACHE_UPPERBOUND));
01357 #endif
01358     images_panel->ReloadCPDetectorSettings();
01359     if(gl_preview_frame)
01360     {
01361         gl_preview_frame->SetShowProjectionHints(cfg->Read(wxT("/GLPreviewFrame/ShowProjectionHints"),HUGIN_SHOW_PROJECTION_HINTS)!=0);
01362     };
01363 }
01364 
01365 void MainFrame::UpdatePanels( wxCommandEvent& WXUNUSED(event) )
01366 {   // Maybe this can be invoced by the Panorama::Changed() or
01367     // something like this. So no everytime update would be needed.
01368     DEBUG_TRACE("");
01369 }
01370 
01371 void MainFrame::OnTogglePreviewFrame(wxCommandEvent & e)
01372 {
01373     DEBUG_TRACE("");
01374     if (preview_frame->IsIconized()) {
01375         preview_frame->Iconize(false);
01376     }
01377     preview_frame->Show();
01378     preview_frame->Raise();
01379 
01380         // we need to force an update since autoupdate fires
01381         // before the preview frame is shown
01382     wxCommandEvent dummy;
01383         preview_frame->OnUpdate(dummy);
01384 }
01385 
01386 void MainFrame::OnToggleGLPreviewFrame(wxCommandEvent & e)
01387 {
01388     if(gl_preview_frame==NULL)
01389     {
01390         return;
01391     };
01392 #if defined __WXMSW__ || defined __WXMAC__
01393     gl_preview_frame->InitPreviews();
01394 #endif
01395     if (gl_preview_frame->IsIconized()) {
01396         gl_preview_frame->Iconize(false);
01397     }
01398     gl_preview_frame->Show();
01399 #if defined __WXMSW__
01400     // on wxMSW Show() does not send OnShowEvent needed to update the
01401     // visibility state of the fast preview windows
01402     // so explicit calling this event handler
01403     wxShowEvent se;
01404     se.SetShow(true);
01405     gl_preview_frame->OnShowEvent(se);
01406 #elif defined __WXGTK__
01407     gl_preview_frame->LoadOpenGLLayout();
01408 #endif
01409     gl_preview_frame->Raise();
01410 }
01411 
01412 void MainFrame::OnShowCPFrame(wxCommandEvent & e)
01413 {
01414     DEBUG_TRACE("");
01415     if (cp_frame) {
01416         if (cp_frame->IsIconized()) {
01417             cp_frame->Iconize(false);
01418         }
01419         cp_frame->Show();
01420         cp_frame->Raise();
01421     } else {
01422         cp_frame = new CPListFrame(this, pano);
01423         cp_frame->Show();
01424     }
01425 }
01426 
01427 void MainFrame::OnCPListFrameClosed()
01428 {
01429     cp_frame = 0;
01430 }
01431 
01432 void MainFrame::OnOptimize(wxCommandEvent & e)
01433 {
01434     DEBUG_TRACE("");
01435     wxCommandEvent dummy;
01436     opt_panel->OnOptimizeButton(dummy);
01437 }
01438 
01439 void MainFrame::OnOnlyActiveImages(wxCommandEvent &e)
01440 {
01441     m_optOnlyActiveImages = GetMenuBar()->IsChecked(XRCID("action_optimize_only_active"));
01442     opt_panel->SetOnlyActiveImages(m_optOnlyActiveImages);
01443     // notify all observer so they can update their display
01444     pano.changeFinished();
01445 };
01446 
01447 void MainFrame::SetOptimizeOnlyActiveImages(const bool onlyActive)
01448 {
01449     m_optOnlyActiveImages = onlyActive;
01450     wxMenuBar* menubar = GetMenuBar();
01451     if (menubar)
01452     {
01453         menubar->Check(XRCID("action_optimize_only_active"), onlyActive);
01454         // notify all observer so they can update their display
01455         pano.changeFinished();
01456     };
01457 };
01458 
01459 const bool MainFrame::GetOptimizeOnlyActiveImages() const
01460 {
01461     return m_optOnlyActiveImages;
01462 };
01463 
01464 void MainFrame::OnPhotometricOptimize(wxCommandEvent & e)
01465 {
01466     wxCommandEvent dummy;
01467     opt_photo_panel->OnOptimizeButton(dummy);
01468 };
01469 
01470 void MainFrame::OnDoStitch(wxCommandEvent & e)
01471 {
01472     DEBUG_TRACE("");
01473     wxCommandEvent cmdEvt(wxEVT_COMMAND_BUTTON_CLICKED,XRCID("pano_button_stitch"));
01474     pano_panel->GetEventHandler()->AddPendingEvent(cmdEvt);
01475 }
01476 
01477 void MainFrame::OnUserDefinedStitch(wxCommandEvent & e)
01478 {
01479     pano_panel->DoUserDefinedStitch();
01480 }
01481 
01482 void MainFrame::OnUserDefinedStitchSaved(wxCommandEvent & e)
01483 {
01484     auto filename = m_userOutput.find(e.GetId());
01485     if (filename != m_userOutput.end())
01486     {
01487         pano_panel->DoUserDefinedStitch(filename->second);
01488     }
01489     else
01490     {
01491         wxBell();
01492     };
01493 }
01494 
01495 void MainFrame::OnMergeProject(wxCommandEvent & e)
01496 {
01497     // get the global config object
01498     wxConfigBase* config = wxConfigBase::Get();
01499 
01500     wxString defaultdir = config->Read(wxT("/actualPath"),wxT(""));
01501     wxFileDialog dlg(wxGetActiveWindow(),
01502                      _("Open project file"),
01503                      defaultdir, wxT(""),
01504                      _("Project files (*.pto)|*.pto|All files (*)|*"),
01505                      wxFD_OPEN, wxDefaultPosition);
01506     dlg.SetDirectory(defaultdir);
01507     if (dlg.ShowModal() == wxID_OK)
01508     {
01509         wxString filename = dlg.GetPath();
01510         wxFileName fname(filename);
01511         wxString path = fname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
01512         if (fname.IsOk() && fname.FileExists())
01513         {
01514             wxBusyCursor wait;
01515             HuginBase::PanoramaMemento newPano;
01516             std::ifstream in((const char *)fname.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
01517             int ptoversion=0;
01518             if (newPano.loadPTScript(in, ptoversion, (const char *)path.mb_str(HUGIN_CONV_FILENAME)))
01519             {
01520                 HuginBase::Panorama new_pano;
01521                 new_pano.setMemento(newPano);
01522                 PanoCommand::GlobalCmdHist::getInstance().addCommand(
01523                     new PanoCommand::MergePanoCmd(pano, new_pano)
01524                 );
01525                 m_mruFiles.AddFileToHistory(fname.GetFullPath());
01526                 // force update of preview window
01527                 if ( !(preview_frame->IsIconized() ||(! preview_frame->IsShown()) ) )
01528                 {
01529                     wxCommandEvent dummy;
01530                     preview_frame->OnUpdate(dummy);
01531                 };
01532             }
01533             else
01534             {
01535                 wxMessageBox(wxString::Format(_("Could not read project file %s."),fname.GetFullPath().c_str()),_("Error"),wxOK|wxICON_ERROR);
01536             };
01537         };
01538     }
01539 }
01540 
01541 void MainFrame::OnReadPapywizard(wxCommandEvent & e)
01542 {
01543     wxString currentDir = wxConfigBase::Get()->Read(wxT("/actualPath"), wxT(""));
01544     wxFileDialog dlg(wxGetActiveWindow(), _("Open Papywizard xml file"),
01545         currentDir, wxT(""), _("Papywizard xml files (*.xml)|*.xml|All files (*)|*"),
01546         wxFD_OPEN, wxDefaultPosition);
01547     dlg.SetDirectory(currentDir);
01548     if (dlg.ShowModal() == wxID_OK)
01549     {
01550         wxConfigBase::Get()->Write(wxT("/actualPath"), dlg.GetDirectory());
01551         Papywizard::ImportPapywizardFile(dlg.GetPath(), pano);
01552     };
01553 };
01554 
01555 void MainFrame::OnApplyTemplate(wxCommandEvent & e)
01556 {
01557     // get the global config object
01558     wxConfigBase* config = wxConfigBase::Get();
01559 
01560     wxFileDialog dlg(wxGetActiveWindow(),
01561                      _("Choose template project"),
01562                      config->Read(wxT("/templatePath"),wxT("")), wxT(""),
01563                      _("Project files (*.pto)|*.pto|All files (*)|*"),
01564                      wxFD_OPEN, wxDefaultPosition);
01565     dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/templatePath"),wxT("")));
01566     if (dlg.ShowModal() == wxID_OK) {
01567         wxString filename = dlg.GetPath();
01568         wxConfig::Get()->Write(wxT("/templatePath"), dlg.GetDirectory());  // remember for later
01569 
01570         std::ifstream file((const char *)filename.mb_str(HUGIN_CONV_FILENAME));
01571 
01572         PanoCommand::GlobalCmdHist::getInstance().addCommand(
01573             new PanoCommand::wxApplyTemplateCmd(pano, file));
01574 
01575     }
01576 }
01577 
01578 void MainFrame::OnOpenPTBatcher(wxCommandEvent & e)
01579 {
01580 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
01581         // Original patch for OSX by Charlie Reiman dd. 18 June 2011
01582         // Slightly modified by HvdW. Errors in here are mine, not Charlie's. 
01583         FSRef appRef;
01584         FSRef actuallyLaunched;
01585         OSStatus err;
01586         FSRef documentArray[1]; // Don't really need an array if we only have 1 item
01587         LSLaunchFSRefSpec launchSpec;
01588         Boolean  isDir;
01589         
01590         err = LSFindApplicationForInfo(kLSUnknownCreator,
01591                                                                    CFSTR("net.sourceforge.hugin.PTBatcherGUI"),
01592                                                                    NULL,
01593                                                                    &appRef,
01594                                                                    NULL);
01595         if (err != noErr) {
01596                 // error, can't find PTBatcherGUI
01597                 wxMessageBox(wxString::Format(_("External program %s not found in the bundle, reverting to system path"), wxT("open")), _("Error"));
01598                 // Possibly a silly attempt otherwise the previous would have worked as well, but just try it.
01599                 wxExecute(_T("open -b net.sourceforge.hugin.PTBatcherGUI"));
01600         }
01601         else {
01602                 wxExecute(_T("open -b net.sourceforge.hugin.PTBatcherGUI"));
01603         }       
01604 #else
01605     const wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
01606         wxExecute(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + _T("PTBatcherGUI"));
01607 #endif
01608 }
01609 
01610 void MainFrame::OnFineTuneAll(wxCommandEvent & e)
01611 {
01612     DEBUG_TRACE("");
01613     // fine-tune all points
01614 
01615     HuginBase::CPVector cps = pano.getCtrlPoints();
01616 
01617     // create a map of all control points.
01618     std::set<unsigned int> unoptimized;
01619     for (unsigned int i=0; i < cps.size(); i++) {
01620         // create all control points.
01621         unoptimized.insert(i);
01622     }
01623 
01624     unsigned int nGood=0;
01625     unsigned int nBad=0;
01626 
01627     wxConfigBase *cfg = wxConfigBase::Get();
01628     double corrThresh=HUGIN_FT_CORR_THRESHOLD;
01629     cfg->Read(wxT("/Finetune/CorrThreshold"), &corrThresh, HUGIN_FT_CORR_THRESHOLD);
01630     double curvThresh = HUGIN_FT_CURV_THRESHOLD;
01631     cfg->Read(wxT("/Finetune/CurvThreshold"),&curvThresh, HUGIN_FT_CURV_THRESHOLD);
01632     // load parameters
01633     const long templWidth = cfg->Read(wxT("/Finetune/TemplateSize"), HUGIN_FT_TEMPLATE_SIZE);
01634     const long sWidth = templWidth + cfg->Read(wxT("/Finetune/LocalSearchWidth"), HUGIN_FT_LOCAL_SEARCH_WIDTH);
01635 
01636     {
01637         ProgressReporterDialog progress(unoptimized.size(), _("Fine-tuning all points"), _("Fine-tuning"), wxGetActiveWindow());
01638 
01639     ImageCache & imgCache = ImageCache::getInstance();
01640 
01641     // do not process the control points in random order,
01642     // but walk from image to image, to reduce image reloading
01643     // in low mem situations.
01644     for (unsigned int imgNr = 0 ; imgNr < pano.getNrOfImages(); imgNr++) {
01645         std::set<unsigned int>::iterator it=unoptimized.begin();
01646 
01647         imgCache.softFlush();
01648 
01649         while (it != unoptimized.end()) {
01650             if (cps[*it].image1Nr == imgNr || cps[*it].image2Nr == imgNr) {
01651                 if (!progress.updateDisplayValue())
01652                 {
01653                     return;
01654                 };
01655                 if (cps[*it].mode == HuginBase::ControlPoint::X_Y) {
01656                     // finetune only normal points
01657                     DEBUG_DEBUG("fine tuning point: " << *it);
01658                     wxImage wxSearchImg;
01659                     ImageCache::ImageCacheRGB8Ptr searchImg = imgCache.getImage(
01660                         pano.getImage(cps[*it].image2Nr).getFilename())->get8BitImage();
01661 
01662                     ImageCache::ImageCacheRGB8Ptr templImg = imgCache.getImage(
01663                         pano.getImage(cps[*it].image1Nr).getFilename())->get8BitImage();
01664 
01665                     vigra_ext::CorrelationResult res;
01666                     vigra::Diff2D roundP1(hugin_utils::roundi(cps[*it].x1), hugin_utils::roundi(cps[*it].y1));
01667                     vigra::Diff2D roundP2(hugin_utils::roundi(cps[*it].x2), hugin_utils::roundi(cps[*it].y2));
01668 
01669                     res = PointFineTuneProjectionAware(pano.getImage(cps[*it].image1Nr), *templImg, roundP1, templWidth,
01670                         pano.getImage(cps[*it].image2Nr), *searchImg, roundP2, sWidth);
01671 
01672                     // invert curvature. we always assume its a maxima, the curvature there is negative
01673                     // however, we allow the user to specify a positive threshold, so we need to
01674                     // invert it
01675                     res.curv.x = - res.curv.x;
01676                     res.curv.y = - res.curv.y;
01677 
01678                     if (res.maxi < corrThresh || res.curv.x < curvThresh || res.curv.y < curvThresh ||
01679                         res.maxpos.x < 0 || res.maxpos.y < 0 || res.corrPos.x < 0 || res.corrPos.y < 0)
01680                     {
01681                         // Bad correlation result.
01682                         nBad++;
01683                         if (res.maxi >= corrThresh) {
01684                             cps[*it].error = 0;
01685                         }
01686                         cps[*it].error = res.maxi;
01687                         DEBUG_DEBUG("low correlation: " << res.maxi << " curv: " << res.curv);
01688                     } else {
01689                         nGood++;
01690                         // only update if a good correlation was found
01691                         cps[*it].x1 = res.corrPos.x;
01692                         cps[*it].y1 = res.corrPos.y;
01693                         cps[*it].x2 = res.maxpos.x;
01694                         cps[*it].y2 = res.maxpos.y;
01695                         cps[*it].error = res.maxi;
01696                     }
01697                 }
01698                 unsigned int rm = *it;
01699                 ++it;
01700                 unoptimized.erase(rm);
01701             } else {
01702                 ++it;
01703             }
01704         }
01705     }
01706     }
01707     wxString result;
01708     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"),
01709                   nGood, nBad, corrThresh);
01710     wxMessageBox(result, _("Fine-tune result"), wxOK);
01711     // set newly optimized points
01712     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01713         new PanoCommand::UpdateCPsCmd(pano, cps, false)
01714         );
01715 }
01716 
01717 void MainFrame::OnRemoveCPinMasks(wxCommandEvent & e)
01718 {
01719     if(pano.getCtrlPoints().size()<2)
01720         return;
01721     HuginBase::UIntSet cps=getCPinMasks(pano);
01722     if(cps.size()>0)
01723     {
01724         PanoCommand::GlobalCmdHist::getInstance().addCommand(
01725                     new PanoCommand::RemoveCtrlPointsCmd(pano,cps)
01726                     );
01727         wxMessageBox(wxString::Format(_("Removed %lu control points"), static_cast<unsigned long>(cps.size())),
01728                    _("Removing control points in masks"),wxOK|wxICON_INFORMATION);
01729     };
01730 }
01731 
01732 #ifdef HUGIN_HSI
01733 void MainFrame::OnPythonScript(wxCommandEvent & e)
01734 {
01735     wxString fname;
01736     wxFileDialog dlg(wxGetActiveWindow(),
01737             _("Select python script"),
01738             wxConfigBase::Get()->Read(wxT("/lensPath"),wxT("")), wxT(""),
01739             _("Python script (*.py)|*.py|All files (*.*)|*.*"),
01740             wxFD_OPEN, wxDefaultPosition);
01741     dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/pythonScriptPath"),wxT("")));
01742 
01743     if (dlg.ShowModal() == wxID_OK)
01744     {
01745         wxString filename = dlg.GetPath();
01746         wxConfig::Get()->Write(wxT("/pythonScriptPath"), dlg.GetDirectory());
01747         std::string scriptfile((const char *)filename.mb_str(HUGIN_CONV_FILENAME));
01748         PanoCommand::GlobalCmdHist::getInstance().addCommand(
01749             new PanoCommand::PythonScriptPanoCmd(pano,scriptfile)
01750             );
01751     }
01752 }
01753 
01754 void MainFrame::OnPlugin(wxCommandEvent & e)
01755 {
01756     wxFileName file=m_plugins[e.GetId()];
01757     if(file.FileExists())
01758     {
01759         std::string scriptfile((const char *)file.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
01760         PanoCommand::GlobalCmdHist::getInstance().addCommand(
01761                                  new PanoCommand::PythonScriptPanoCmd(pano,scriptfile)
01762                                  );
01763     }
01764     else
01765     {
01766         wxMessageBox(wxString::Format(wxT("Python-Script %s not found.\nStopping processing."),file.GetFullPath().c_str()),_("Warning"),wxOK|wxICON_INFORMATION);
01767     };
01768 }
01769 
01770 #endif
01771 
01772 void MainFrame::OnUndo(wxCommandEvent & e)
01773 {
01774     DEBUG_TRACE("OnUndo");
01775     if (PanoCommand::GlobalCmdHist::getInstance().canUndo())
01776     {
01777         PanoCommand::GlobalCmdHist::getInstance().undo();
01778     }
01779     else
01780     {
01781         wxBell();
01782     };
01783 }
01784 
01785 void MainFrame::OnRedo(wxCommandEvent & e)
01786 {
01787     DEBUG_TRACE("OnRedo");
01788     if (PanoCommand::GlobalCmdHist::getInstance().canRedo())
01789     {
01790         PanoCommand::GlobalCmdHist::getInstance().redo();
01791     };
01792 }
01793 
01794 void MainFrame::ShowCtrlPoint(unsigned int cpNr)
01795 {
01796     DEBUG_DEBUG("Showing control point " << cpNr);
01797     m_notebook->SetSelection(2);
01798     cpe->ShowControlPoint(cpNr);
01799 }
01800 
01801 void MainFrame::ShowCtrlPointEditor(unsigned int img1, unsigned int img2)
01802 {
01803     if(!IsShown())
01804     {
01805         Show();
01806         Raise();
01807     };
01808     m_notebook->SetSelection(2);
01809     cpe->setLeftImage(img1);
01810     cpe->setRightImage(img2);
01811 }
01812 
01813 void MainFrame::ShowMaskEditor(size_t imgNr)
01814 {
01815     if(!IsShown())
01816     {
01817         Show();
01818         Raise();
01819     };
01820     m_notebook->SetSelection(1);
01821     mask_panel->setImage(imgNr, true);
01822 };
01823 
01824 void MainFrame::ShowStitcherTab()
01825 {
01827     if(m_show_opt_panel && m_show_opt_photo_panel)
01828     {
01829         m_notebook->SetSelection(5);
01830     }
01831     else
01832     {
01833         if(m_show_opt_panel || m_show_opt_photo_panel)
01834         {
01835             m_notebook->SetSelection(4);
01836         }
01837         else
01838         {
01839             m_notebook->SetSelection(3);
01840         };
01841     };
01842 }
01843 
01845 void MainFrame::updateProgressDisplay()
01846 {
01847     wxString msg;
01848     if (!m_message.empty())
01849     {
01850         msg = wxGetTranslation(wxString(m_message.c_str(), wxConvLocal));
01851         if (!m_filename.empty())
01852         {
01853             msg.Append(wxT(" "));
01854             msg.Append(wxString(ProgressDisplay::m_filename.c_str(), HUGIN_CONV_FILENAME));
01855         };
01856     };
01857     GetStatusBar()->SetStatusText(msg, 0);
01858 
01859 #ifdef __WXMSW__
01860     UpdateWindow(NULL);
01861 #endif
01862 }
01863 
01864 void MainFrame::enableTools(bool option)
01865 {
01866     wxToolBar* theToolBar = GetToolBar();
01867     theToolBar->EnableTool(XRCID("action_optimize"), option);
01868     theToolBar->EnableTool(XRCID("ID_SHOW_PREVIEW_FRAME"), option);
01869     //theToolBar->EnableTool(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), option);
01870     wxMenuBar* theMenuBar = GetMenuBar();
01871     theMenuBar->Enable(XRCID("action_optimize"), option);
01872     theMenuBar->Enable(XRCID("action_finetune_all_cp"), option);
01873     theMenuBar->Enable(XRCID("action_remove_cp_in_masks"), option);
01874     theMenuBar->Enable(XRCID("ID_SHOW_PREVIEW_FRAME"), option);
01875     theMenuBar->Enable(XRCID("action_stitch"), option);
01876     theMenuBar->Enable(XRCID("action_stitch_userdefined"), option);
01877     theMenuBar->Enable(theMenuBar->FindMenuItem(_("Output"), _("User defined output sequences")), option);
01878     m_menu_file_advanced->Enable(XRCID("action_import_papywizard"), option);
01879     //theMenuBar->Enable(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), option);
01880 }
01881 
01882 
01883 void MainFrame::OnSize(wxSizeEvent &e)
01884 {
01885 #ifdef DEBUG
01886     wxSize sz = this->GetSize();
01887     wxSize csz = this->GetClientSize();
01888     wxSize vsz = this->GetVirtualSize();
01889     DEBUG_TRACE(" size:" << sz.x << "," << sz.y <<
01890                 " client: "<< csz.x << "," << csz.y <<
01891                 " virtual: "<< vsz.x << "," << vsz.y);
01892 #endif
01893 
01894     Layout();
01895     e.Skip();
01896 }
01897 
01898 CPDetectorSetting& MainFrame::GetDefaultSetting()
01899 {
01900     return images_panel->GetDefaultSetting();
01901 };
01902 
01903 void MainFrame::RunCPGenerator(CPDetectorSetting &setting, const HuginBase::UIntSet& img)
01904 {
01905     images_panel->RunCPGenerator(setting, img);
01906 };
01907 
01908 void MainFrame::RunCPGenerator(const HuginBase::UIntSet& img)
01909 {
01910     images_panel->RunCPGenerator(img);
01911 };
01912 
01913 const wxString MainFrame::GetSelectedCPGenerator()
01914 {
01915     return images_panel->GetSelectedCPGenerator();
01916 };
01917 
01918 const wxString & MainFrame::GetXRCPath()
01919 {
01920      return huginApp::Get()->GetXRCPath();
01921 };
01922 
01923 const wxString & MainFrame::GetDataPath()
01924 {
01925     return wxGetApp().GetDataPath();
01926 };
01927 
01929 MainFrame * MainFrame::Get()
01930 {
01931     if (m_this) {
01932         return m_this;
01933     } else {
01934         DEBUG_FATAL("MainFrame not yet created");
01935         DEBUG_ASSERT(m_this);
01936         return 0;
01937     }
01938 }
01939 
01940 wxString MainFrame::getProjectName()
01941 {
01942     return m_filename;
01943 }
01944 
01945 void MainFrame::OnMRUFiles(wxCommandEvent &e)
01946 {
01947     size_t index = e.GetId() - wxID_FILE1;
01948     wxString f(m_mruFiles.GetHistoryFile(index));
01949     if (!f.empty())
01950     {
01951         wxFileName fn(f);
01952         if(fn.FileExists())
01953             LoadProjectFile(f);
01954         else
01955         {
01956             m_mruFiles.RemoveFileFromHistory(index);
01957             wxMessageBox(wxString::Format(_("File \"%s\" not found.\nMaybe file was renamed, moved or deleted."),f.c_str()),
01958                 _("Error!"),wxOK | wxICON_INFORMATION );
01959         };
01960     };
01961 }
01962 
01963 void MainFrame::OnFullScreen(wxCommandEvent & e)
01964 {
01965     ShowFullScreen(!IsFullScreen(), wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION);
01966 #ifdef __WXGTK__
01967     //workaround a wxGTK bug that also the toolbar is hidden, but not requested to hide
01968     GetToolBar()->Show(true);
01969 #endif
01970 };
01971 
01972 struct celeste::svm_model* MainFrame::GetSVMModel()
01973 {
01974     if(svmModel==NULL)
01975     {
01976         // determine file name of SVM model file
01977         // get XRC path from application
01978         wxString wxstrModelFileName = huginApp::Get()->GetDataPath() + wxT(HUGIN_CELESTE_MODEL);
01979         // convert wxString to string
01980         std::string strModelFileName(wxstrModelFileName.mb_str(HUGIN_CONV_FILENAME));
01981 
01982         // SVM model file
01983         if (! wxFile::Exists(wxstrModelFileName) ) {
01984             wxMessageBox(wxString::Format(_("Celeste model expected in %s not found, Hugin needs to be properly installed."),wxstrModelFileName.c_str()), _("Fatal Error"));
01985             return NULL;
01986         }
01987         if(!celeste::loadSVMmodel(svmModel,strModelFileName))
01988         {
01989             wxMessageBox(wxString::Format(_("Could not load Celeste model file %s"),wxstrModelFileName.c_str()),_("Error"));
01990             svmModel=NULL;
01991         };
01992     }
01993     return svmModel;
01994 };
01995 
01996 GLPreviewFrame * MainFrame::getGLPreview()
01997 {
01998     return gl_preview_frame;
01999 }
02000 
02001 void MainFrame::SetGuiLevel(GuiLevel newLevel)
02002 {
02003     if(gl_preview_frame==NULL && newLevel==GUI_SIMPLE)
02004     {
02005         SetGuiLevel(GUI_ADVANCED);
02006         return;
02007     };
02008     if(m_guiLevel==GUI_EXPERT && newLevel!=GUI_EXPERT && pano.getOptimizerSwitch()==0)
02009     {
02010         bool needsUpdateOptimizerVar=false;
02011         HuginBase::OptimizeVector optVec = pano.getOptimizeVector();
02012         for(size_t i=0; i<optVec.size(); i++)
02013         {
02014             bool hasTrX=optVec[i].erase("TrX")>0;
02015             bool hasTrY=optVec[i].erase("TrY")>0;
02016             bool hasTrZ=optVec[i].erase("TrZ")>0;
02017             bool hasTpy=optVec[i].erase("Tpy")>0;
02018             bool hasTpp=optVec[i].erase("Tpp")>0;
02019             bool hasg=optVec[i].erase("g")>0;
02020             bool hast=optVec[i].erase("t")>0;
02021             needsUpdateOptimizerVar=needsUpdateOptimizerVar || hasTrX || hasTrY || hasTrZ || hasTpy || hasTpp || hasg || hast;
02022         };
02023         if(needsUpdateOptimizerVar)
02024         {
02025             PanoCommand::GlobalCmdHist::getInstance().addCommand(
02026                 new PanoCommand::UpdateOptimizeVectorCmd(pano, optVec)
02027             );
02028         };
02029     };
02030     if(newLevel==GUI_SIMPLE && pano.getPhotometricOptimizerSwitch()==0)
02031     {
02032         bool needsUpdateOptimizerVar=false;
02033         HuginBase::OptimizeVector optVec = pano.getOptimizeVector();
02034         for(size_t i=0; i<optVec.size(); i++)
02035         {
02036             bool hasVx=optVec[i].erase("Vx")>0;
02037             bool hasVy=optVec[i].erase("Vy")>0;
02038             needsUpdateOptimizerVar=needsUpdateOptimizerVar || hasVx || hasVy;
02039         };
02040         if(needsUpdateOptimizerVar)
02041         {
02042             PanoCommand::GlobalCmdHist::getInstance().addCommand(
02043                 new PanoCommand::UpdateOptimizeVectorCmd(pano, optVec)
02044             );
02045         };
02046     };
02047     m_guiLevel=newLevel;
02048     images_panel->SetGuiLevel(m_guiLevel);
02049     opt_panel->SetGuiLevel(m_guiLevel);
02050     opt_photo_panel->SetGuiLevel(m_guiLevel);
02051     pano_panel->SetGuiLevel(m_guiLevel);
02052     if(gl_preview_frame)
02053     {
02054         gl_preview_frame->SetGuiLevel(m_guiLevel);
02055     };
02056     switch(m_guiLevel)
02057     {
02058         case GUI_SIMPLE:
02059             GetMenuBar()->FindItem(XRCID("action_gui_simple"))->Check();
02060             break;
02061         case GUI_ADVANCED:
02062             GetMenuBar()->FindItem(XRCID("action_gui_advanced"))->Check();
02063             break;
02064         case GUI_EXPERT:
02065             GetMenuBar()->FindItem(XRCID("action_gui_expert"))->Check();
02066             break;
02067     };
02068     if(m_guiLevel==GUI_SIMPLE)
02069     {
02070         if(!gl_preview_frame->IsShown())
02071         {
02072             wxCommandEvent dummy;
02073             OnToggleGLPreviewFrame(dummy);
02074         };
02075         wxGetApp().SetTopWindow(gl_preview_frame);
02076         GetMenuBar()->Remove(0);
02077         GetMenuBar()->Insert(0, m_menu_file_simple, _("&File"));
02078         if(m_filename.IsEmpty())
02079         {
02080             gl_preview_frame->SetTitle(_("Hugin - Panorama Stitcher"));
02081             SetTitle(_("Panorama editor"));
02082         }
02083         else
02084         {
02085             wxFileName scriptName = m_filename;
02086             gl_preview_frame->SetTitle(scriptName.GetName() + wxT(".") + scriptName.GetExt() + wxT(" - ") + _("Hugin - Panorama Stitcher"));
02087             SetTitle(scriptName.GetName() + wxT(".") + scriptName.GetExt() + wxT(" - ") + _("Panorama editor"));
02088         };
02089         Hide();
02090     }
02091     else
02092     {
02093         wxGetApp().SetTopWindow(this);
02094         GetMenuBar()->Remove(0);
02095         GetMenuBar()->Insert(0, m_menu_file_advanced, _("&File"));
02096         if(m_filename.IsEmpty())
02097         {
02098             SetTitle(_("Hugin - Panorama Stitcher"));
02099         }
02100         else
02101         {
02102             wxFileName scriptName = m_filename;
02103             SetTitle(scriptName.GetName() + wxT(".") + scriptName.GetExt() + wxT(" - ") + _("Hugin - Panorama Stitcher"));
02104         };
02105         if(!IsShown())
02106         {
02107             Show();
02108         };
02109     };
02110 };
02111 
02112 void MainFrame::OnSetGuiSimple(wxCommandEvent & e)
02113 {
02114     GuiLevel reqGuiLevel=GetMinimumGuiLevel(pano);
02115     if(reqGuiLevel<=GUI_SIMPLE)
02116     {
02117         SetGuiLevel(GUI_SIMPLE);
02118     }
02119     else
02120     {
02121         if(reqGuiLevel==GUI_ADVANCED)
02122         {
02123             wxMessageBox(_("Can't switch to simple interface. The project is using stacks and/or vignetting center shift.\nThese features are not supported in simple interface."),
02124 #ifdef __WXMSW__
02125                          wxT("Hugin"),
02126 #else
02127                          wxT(""),
02128 #endif
02129                          wxOK | wxICON_INFORMATION);
02130         }
02131         else
02132         {
02133             wxMessageBox(_("Can't switch to simple interface. The project is using translation or shear parameters.\nThese parameters are not supported in simple interface."),
02134 #ifdef __WXMSW__
02135                          wxT("Hugin"),
02136 #else
02137                          wxT(""),
02138 #endif
02139                          wxOK | wxICON_INFORMATION);
02140         }
02141         SetGuiLevel(m_guiLevel);
02142     };
02143 };
02144 
02145 void MainFrame::OnSetGuiAdvanced(wxCommandEvent & e)
02146 {
02147     GuiLevel reqGuiLevel=GetMinimumGuiLevel(pano);
02148     if(reqGuiLevel<=GUI_ADVANCED)
02149     {
02150         SetGuiLevel(GUI_ADVANCED);
02151     }
02152     else
02153     {
02154         wxMessageBox(_("Can't switch to advanced interface. The project is using translation or shear parameters.\nThese parameters are not supported in advanced interface."),
02155 #ifdef __WXMSW__
02156                      wxT("Hugin"),
02157 #else
02158                      wxT(""),
02159 #endif
02160                      wxOK | wxICON_INFORMATION);
02161         SetGuiLevel(GUI_EXPERT);
02162     };
02163 };
02164 
02165 void MainFrame::OnSetGuiExpert(wxCommandEvent & e)
02166 {
02167     SetGuiLevel(GUI_EXPERT);
02168 };
02169 
02170 void MainFrame::DisableOpenGLTools()
02171 {
02172     GetMenuBar()->Enable(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), false);
02173     GetMenuBar()->Enable(XRCID("action_gui_simple"), false);
02174     GetToolBar()->EnableTool(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), false); 
02175 };
02176 
02177 void MainFrame::RunAssistant(wxWindow* mainWin)
02178 {
02179     //save project into temp directory
02180     wxString tempDir= wxConfig::Get()->Read(wxT("tempDir"),wxT(""));
02181     if(!tempDir.IsEmpty())
02182     {
02183         if(tempDir.Last()!=wxFileName::GetPathSeparator())
02184         {
02185             tempDir.Append(wxFileName::GetPathSeparator());
02186         }
02187     };
02188     wxFileName scriptFileName(wxFileName::CreateTempFileName(tempDir+wxT("ha")));
02189     std::ofstream script(scriptFileName.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
02190     script.exceptions ( std::ofstream::eofbit | std::ofstream::failbit | std::ofstream::badbit );
02191     HuginBase::UIntSet all;
02192     fill_set(all, 0, pano.getNrOfImages()-1);
02193     pano.printPanoramaScript(script, pano.getOptimizeVector(), pano.getOptions(), all, false);
02194     script.close();
02195 
02196     // get assistant queue
02197     const wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
02198     HuginQueue::CommandQueue* commands = HuginQueue::GetAssistantCommandQueue(pano, exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR), scriptFileName.GetFullPath());
02199     //execute queue
02200     int ret = MyExecuteCommandQueue(commands, mainWin, _("Running assistant"));
02201 
02202     //read back panofile
02203     PanoCommand::GlobalCmdHist::getInstance().addCommand(new PanoCommand::wxLoadPTProjectCmd(pano,
02204         (const char *)scriptFileName.GetFullPath().mb_str(HUGIN_CONV_FILENAME), 
02205         (const char *)scriptFileName.GetPath(wxPATH_NATIVE | wxPATH_GET_SEPARATOR).mb_str(HUGIN_CONV_FILENAME), 
02206         ret==0, false));
02207 
02208     //delete temporary files
02209     wxRemoveFile(scriptFileName.GetFullPath());
02210     //if return value is non-zero, an error occurred in the assistant
02211     if(ret!=0)
02212     {
02213         if (pano.getNrOfImages())
02214         {
02215             wxMessageBox(_("The assistant could not find vertical lines. Please add vertical lines in the panorama editor and optimize project manually."),
02216                 _("Warning"), wxOK | wxICON_INFORMATION, mainWin);
02217         }
02218         else
02219         {
02220             //check for unconnected images
02221             HuginGraph::ImageGraph graph(pano);
02222             const HuginGraph::ImageGraph::Components comps = graph.GetComponents();
02223             if (comps.size() > 1)
02224             {
02225                 // switch to images panel.
02226                 unsigned i1 = *(comps[0].rbegin());
02227                 unsigned i2 = *(comps[1].begin());
02228                 ShowCtrlPointEditor(i1, i2);
02229                 // display message box with 
02230                 wxMessageBox(wxString::Format(_("Warning %d unconnected image groups found:"), static_cast<int>(comps.size())) + Components2Str(comps) + wxT("\n")
02231                     + _("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);
02232                 return;
02233             };
02234             wxMessageBox(_("The assistant did not complete successfully. Please check the resulting project file."),
02235                 _("Warning"), wxOK | wxICON_INFORMATION, mainWin);
02236         };
02237     };
02238 };
02239 
02240 void MainFrame::OnRunAssistant(wxCommandEvent & e)
02241 {
02242     RunAssistant(this);
02243 };
02244 
02245 void MainFrame::OnSendToAssistantQueue(wxCommandEvent &e)
02246 {
02247     wxCommandEvent dummy;
02248     OnSaveProject(dummy);
02249     wxString projectFile = getProjectName();
02250     if(wxFileName::FileExists(projectFile))
02251     {
02252 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
02253         // Original patch for OSX by Charlie Reiman dd. 18 June 2011
02254         // Slightly modified by HvdW. Errors in here are mine, not Charlie's. 
02255         FSRef appRef;
02256         FSRef actuallyLaunched;
02257         OSStatus err;
02258         FSRef documentArray[1]; // Don't really need an array if we only have 1 item
02259         LSLaunchFSRefSpec launchSpec;
02260         Boolean  isDir;
02261 
02262         err = LSFindApplicationForInfo(kLSUnknownCreator,
02263                                        CFSTR("net.sourceforge.hugin.PTBatcherGUI"),
02264                                        NULL,
02265                                        &appRef,
02266                                        NULL);
02267         if (err != noErr)
02268         {
02269             // error, can't find PTBatcherGUI
02270             wxMessageBox(wxString::Format(_("External program %s not found in the bundle, reverting to system path"), wxT("open")), _("Error"));
02271             // Possibly a silly attempt otherwise the previous would have worked as well, but just try it.
02272             wxExecute(_T("open -b net.sourceforge.hugin.PTBatcherGUI ")+hugin_utils::wxQuoteFilename(projectFile));
02273             return;
02274         }
02275 
02276         wxCharBuffer projectFilebuffer=projectFile.ToUTF8();
02277         // Point to document
02278         err = FSPathMakeRef((unsigned char*) projectFilebuffer.data(), &documentArray[0], &isDir);
02279         if (err != noErr || isDir)
02280         {
02281             // Something went wrong.
02282             wxMessageBox(wxString::Format(_("Project file not found"), wxT("open")), _("Error"));
02283             return;
02284         }
02285         launchSpec.appRef = &appRef;
02286         launchSpec.numDocs = sizeof(documentArray)/sizeof(documentArray[0]);
02287         launchSpec.itemRefs = documentArray;
02288         launchSpec.passThruParams = NULL;
02289         launchSpec.launchFlags = kLSLaunchDontAddToRecents + kLSLaunchDontSwitch;
02290         launchSpec.asyncRefCon = NULL;
02291 
02292         err = LSOpenFromRefSpec(&launchSpec, &actuallyLaunched);
02293         if (err != noErr && err != kLSLaunchInProgressErr)
02294         {  
02295             // Should be ok if it's in progress... I think. 
02296             // Launch failed.
02297             wxMessageBox(wxString::Format(_("Can't launch PTBatcherGui"), wxT("open")), _("Error"));
02298             return;
02299         }
02300 
02301         // Should verify that actuallyLaunched and appRef are the same.
02302         if (FSCompareFSRefs(&appRef, &actuallyLaunched) != noErr)
02303         {
02304             // error, lauched the wrong thing.
02305             wxMessageBox(wxString::Format(_("Launched incorrect programme"), wxT("open")), _("Error"));
02306             return;
02307         }
02308 #else
02309         const wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
02310         wxExecute(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + wxT("PTBatcherGUI -a ")+hugin_utils::wxQuoteFilename(projectFile));
02311 #endif
02312     }
02313 };
02314 
02315 wxString MainFrame::GetCurrentOptimizerString()
02316 {
02317     return images_panel->GetCurrentOptimizerString();
02318 };
02319 
02320 MainFrame * MainFrame::m_this = 0;

Generated on 19 Jan 2017 for Hugintrunk by  doxygen 1.4.7