MainFrame.cpp

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