MainFrame.cpp

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

Generated on 21 Jul 2017 for Hugintrunk by  doxygen 1.4.7