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         if (pano.getNrOfImages() > 0)
01000         {
01001             SetStatusText(_("Project opened"));
01002             m_mruFiles.AddFileToHistory(fname.GetFullPath());
01003             if (m_guiLevel == GUI_SIMPLE)
01004             {
01005                 if (gl_preview_frame)
01006                 {
01007                     gl_preview_frame->SetTitle(fname.GetName() + wxT(".") + fname.GetExt() + wxT(" - ") + _("Hugin - Panorama Stitcher"));
01008                 };
01009                 SetTitle(fname.GetName() + wxT(".") + fname.GetExt() + wxT(" - ") + _("Panorama editor"));
01010             }
01011             else
01012             {
01013                 SetTitle(fname.GetName() + wxT(".") + fname.GetExt() + wxT(" - ") + _("Hugin - Panorama Stitcher"));
01014             };
01015         }
01016         else
01017         {
01018             SetStatusText(_("Loading canceled"));
01019             m_filename = "";
01020             if (m_guiLevel == GUI_SIMPLE)
01021             {
01022                 if (gl_preview_frame)
01023                 {
01024                     gl_preview_frame->SetTitle(_("Hugin - Panorama Stitcher"));
01025                 };
01026                 SetTitle(_("Panorama editor"));
01027             }
01028             else
01029             {
01030                 SetTitle(_("Hugin - Panorama Stitcher"));
01031             };
01032         };
01033         if (! (fname.GetExt() == wxT("pto"))) {
01034             // do not remember filename if its not a hugin project
01035             // to avoid overwriting the original project with an
01036             // incompatible one
01037             m_filename = wxT("");
01038         }
01039         // get the global config object
01040         wxConfigBase* config = wxConfigBase::Get();
01041         config->Write(wxT("/actualPath"), path);  // remember for later
01042     } else {
01043         SetStatusText( _("Error opening project:   ") + filename);
01044         DEBUG_ERROR("Could not open file " << filename);
01045     }
01046 
01047     // force update of preview window
01048     if ( !(preview_frame->IsIconized() ||(! preview_frame->IsShown()) ) ) {
01049         wxCommandEvent dummy;
01050         preview_frame->OnUpdate(dummy);
01051     }
01052 }
01053 
01054 #ifdef __WXMAC__
01055 void MainFrame::MacOnOpenFile(const wxString & filename)
01056 {
01057     if(!CloseProject(true, LOAD_NEW_PROJECT)) return; //if closing old project is canceled do nothing.
01058 
01059     ImageCache::getInstance().flush();
01060     LoadProjectFile(filename);
01061 }
01062 #endif
01063 
01064 void MainFrame::OnLoadProject(wxCommandEvent & e)
01065 {
01066     DEBUG_TRACE("");
01067 
01068     if(CloseProject(true, LOAD_NEW_PROJECT)) //if closing old project is canceled do nothing.
01069     {
01070         // get the global config object
01071         wxConfigBase* config = wxConfigBase::Get();
01072 
01073         wxString defaultdir = config->Read(wxT("/actualPath"),wxT(""));
01074         wxFileDialog dlg(wxGetActiveWindow(),
01075                          _("Open project file"),
01076                          defaultdir, wxT(""),
01077                          _("Project files (*.pto)|*.pto|All files (*)|*"),
01078                          wxFD_OPEN, wxDefaultPosition);
01079         dlg.SetDirectory(defaultdir);
01080         if (dlg.ShowModal() == wxID_OK)
01081         {
01082             wxString filename = dlg.GetPath();
01083             if(vigra::isImage(filename.mb_str(HUGIN_CONV_FILENAME)))
01084             {
01085                 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()),
01086 #ifdef __WXMSW__
01087                     _("Hugin"),
01088 #else
01089                     wxT(""),
01090 #endif
01091                     wxYES_NO | wxICON_QUESTION)==wxYES)
01092                 {
01093                     wxArrayString filenameArray;
01094                     filenameArray.Add(filename);
01095                     AddImages(filenameArray);
01096                 };
01097                 return;
01098             }
01099             else
01100             {
01101                 // remove old images from cache
01102                 ImageCache::getInstance().flush();
01103 
01104                 LoadProjectFile(filename);
01105                 return;
01106             };
01107         }
01108     }
01109     // do not close old project
01110     // nothing to open
01111     SetStatusText( _("Open project: cancel"));
01112 }
01113 
01114 void MainFrame::OnNewProject(wxCommandEvent & e)
01115 {
01116     if(!CloseProject(true, NEW_PROJECT)) return; //if closing current project is canceled
01117 
01118     m_filename = wxT("");
01119     PanoCommand::GlobalCmdHist::getInstance().addCommand(new PanoCommand::wxNewProjectCmd(pano));
01120     PanoCommand::GlobalCmdHist::getInstance().clear();
01121     // remove old images from cache
01122     ImageCache::getInstance().flush();
01123     if(m_guiLevel==GUI_SIMPLE)
01124     {
01125         if(gl_preview_frame)
01126         {
01127             gl_preview_frame->SetTitle(_("Hugin - Panorama Stitcher"));
01128         };
01129         SetTitle(_("Panorama editor"));
01130     }
01131     else
01132     {
01133         SetTitle(_("Hugin - Panorama Stitcher"));
01134     };
01135 
01136     wxCommandEvent dummy;
01137     preview_frame->OnUpdate(dummy);
01138 }
01139 
01140 void MainFrame::OnAddImages( wxCommandEvent& event )
01141 {
01142     DEBUG_TRACE("");
01143     PanoOperation::AddImageOperation addImage;
01144     HuginBase::UIntSet images;
01145     PanoCommand::PanoCommand* cmd = addImage.GetCommand(wxGetActiveWindow(), pano, images, m_guiLevel);
01146     if(cmd!=NULL)
01147     {
01148         PanoCommand::GlobalCmdHist::getInstance().addCommand(cmd);
01149     }
01150     else
01151     {
01152         // nothing to open
01153         SetStatusText( _("Add Image: cancel"));
01154     }
01155 
01156     DEBUG_TRACE("");
01157 }
01158 
01159 void MainFrame::AddImages(wxArrayString& filenameArray)
01160 {
01161     wxArrayString invalidFiles;
01162     for(unsigned int i=0;i<filenameArray.GetCount(); i++)
01163     {
01164         if(containsInvalidCharacters(filenameArray[i]))
01165         {
01166             invalidFiles.Add(filenameArray[i]);
01167         };
01168     };
01169     if(invalidFiles.size()>0)
01170     {
01171         ShowFilenameWarning(this, invalidFiles);
01172     }
01173     else
01174     {
01175         std::vector<std::string> filesv;
01176         for (unsigned int i=0; i< filenameArray.GetCount(); i++) {
01177             filesv.push_back((const char *)filenameArray[i].mb_str(HUGIN_CONV_FILENAME));
01178         }
01179 
01180         // we got some images to add.
01181         if (filesv.size() > 0) {
01182             // use a Command to ensure proper undo and updating of GUI
01183             // parts
01184             wxBusyCursor();
01185             PanoCommand::GlobalCmdHist::getInstance().addCommand(
01186                 new PanoCommand::wxAddImagesCmd(pano, filesv)
01187                 );
01188         };
01189     };
01190 };
01191 
01192 void MainFrame::OnAddTimeImages( wxCommandEvent& event )
01193 {
01194     PanoOperation::AddImagesSeriesOperation imageSeriesOp;
01195     HuginBase::UIntSet images;
01196     PanoCommand::PanoCommand* cmd = imageSeriesOp.GetCommand(wxGetActiveWindow(), pano, images, m_guiLevel);
01197     if(cmd!=NULL)
01198     {
01199         PanoCommand::GlobalCmdHist::getInstance().addCommand(cmd);
01200     };
01201 };
01202 
01203 
01204 void MainFrame::OnShowPanel(wxCommandEvent & e)
01205 {
01206     if(e.GetId()==XRCID("ID_SHOW_PANEL_MASK"))
01207         m_notebook->SetSelection(1);
01208     else
01209         if(e.GetId()==XRCID("ID_SHOW_PANEL_CP_EDITOR"))
01210             m_notebook->SetSelection(2);
01211         else
01212             if(e.GetId()==XRCID("ID_SHOW_PANEL_OPTIMIZER"))
01213                 m_notebook->SetSelection(3);
01214             else
01215                 if(e.GetId()==XRCID("ID_SHOW_PANEL_OPTIMIZER_PHOTOMETRIC"))
01216                 {
01217                     if(m_show_opt_panel)
01218                     {
01219                         m_notebook->SetSelection(4);
01220                     }
01221                     else
01222                     {
01223                         m_notebook->SetSelection(3);
01224                     };
01225                 }
01226                 else
01227                     if(e.GetId()==XRCID("ID_SHOW_PANEL_PANORAMA"))
01228                     {
01229                         if(m_show_opt_panel && m_show_opt_photo_panel)
01230                         {
01231                             m_notebook->SetSelection(5);
01232                         }
01233                         else
01234                         {
01235                             if(m_show_opt_panel || m_show_opt_photo_panel)
01236                             {
01237                                 m_notebook->SetSelection(4);
01238                             }
01239                             else
01240                             {
01241                                 m_notebook->SetSelection(3);
01242                             };
01243                         };
01244                     }
01245                     else
01246                         m_notebook->SetSelection(0);
01247 }
01248 
01249 void MainFrame::OnLoadingFailed(wxCommandEvent & e)
01250 {
01251     // check if file exists
01252     if (wxFileExists(e.GetString()))
01253     {
01254         // file exists, but could not loaded
01255         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()),
01256 #ifdef _WIN32
01257             _("Hugin"),
01258 #else
01259             wxT(""),
01260 #endif
01261             wxOK | wxICON_ERROR);
01262     }
01263     else
01264     {
01265         // file does not exists
01266         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()),
01267 #ifdef _WIN32
01268             _("Hugin"),
01269 #else
01270             wxT(""),
01271 #endif
01272             wxOK | wxICON_ERROR);
01273     };
01274     // now remove the file from the pano
01275     const std::string filename(e.GetString().mb_str(HUGIN_CONV_FILENAME));
01276     HuginBase::UIntSet imagesToRemove;
01277     for (size_t i = 0; i < pano.getNrOfImages(); ++i)
01278     {
01279         if (pano.getImage(i).getFilename() == filename)
01280         {
01281             imagesToRemove.insert(i);
01282         };
01283     };
01284     if (!imagesToRemove.empty())
01285     {
01286         PanoCommand::GlobalCmdHist::getInstance().addCommand(new PanoCommand::RemoveImagesCmd(pano, imagesToRemove));
01287     };
01288 }
01289 
01290 
01291 void MainFrame::OnAbout(wxCommandEvent & e)
01292 {
01293     AboutDialog dlg(wxGetActiveWindow());
01294     dlg.ShowModal();
01295 }
01296 
01297 /*
01298 void MainFrame::OnAbout(wxCommandEvent & e)
01299 {
01300     DEBUG_TRACE("");
01301     wxDialog dlg;
01302         wxString strFile;
01303         wxString langCode;
01304 
01305     wxXmlResource::Get()->LoadDialog(&dlg, this, wxT("about_dlg"));
01306 
01307 #if __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
01308     //rely on the system's locale choice
01309     strFile = MacGetPathToBundledResourceFile(CFSTR("about.htm"));
01310     if(strFile!=wxT("")) XRCCTRL(dlg,"about_html",wxHtmlWindow)->LoadPage(strFile);
01311 #else
01312     //if the language is not default, load custom About file (if exists)
01313     langCode = huginApp::Get()->GetLocale().GetName().Left(2).Lower();
01314     DEBUG_INFO("Lang Code: " << langCode.mb_str(wxConvLocal));
01315     if(langCode != wxString(wxT("en")))
01316     {
01317         strFile = GetXRCPath() + wxT("data/about_") + langCode + wxT(".htm");
01318         if(wxFile::Exists(strFile))
01319         {
01320             DEBUG_TRACE("Using About: " << strFile.mb_str(wxConvLocal));
01321             XRCCTRL(dlg,"about_html",wxHtmlWindow)->LoadPage(strFile);
01322         }
01323     }
01324 #endif
01325     dlg.ShowModal();
01326 }
01327 */
01328 
01329 void MainFrame::OnHelp(wxCommandEvent & e)
01330 {
01331     DisplayHelp();
01332 }
01333 
01334 void MainFrame::OnKeyboardHelp(wxCommandEvent & e)
01335 {
01336     DisplayHelp(wxT("Hugin_Keyboard_shortcuts.html"));
01337 }
01338 
01339 void MainFrame::OnFAQ(wxCommandEvent & e)
01340 {
01341     DisplayHelp(wxT("Hugin_FAQ.html"));
01342 }
01343 
01344 
01345 void MainFrame::DisplayHelp(wxString section)
01346 {
01347     if (section.IsEmpty())
01348     {
01349         GetHelpController().DisplayContents();
01350     }
01351     else
01352     {
01353 #if defined __wxMSW__ && !(wxCHECK_VERSION(3,1,1))
01354         // wxWidgets 3.x has a bug, that prevents DisplaySection to work on Win8/10 64 bit
01355         // see: http://trac.wxwidgets.org/ticket/14888
01356         // so using DisplayContents() and our own implementation of HuginCHMHelpController
01357         GetHelpController().DisplayHelpPage(section);
01358 #else
01359         GetHelpController().DisplaySection(section);
01360 #endif
01361     };
01362 }
01363 
01364 void MainFrame::OnTipOfDay(wxCommandEvent& WXUNUSED(e))
01365 {
01366     wxString strFile;
01367     bool bShowAtStartup;
01368 // DGSW FIXME - Unreferenced
01369 //      bool bTipsExist = false;
01370     int nValue;
01371 
01372     wxConfigBase * config = wxConfigBase::Get();
01373     nValue = config->Read(wxT("/MainFrame/ShowStartTip"),1l);
01374 
01375     //TODO: tips not localisable
01376     DEBUG_INFO("Tip index: " << nValue);
01377     strFile = GetXRCPath() + wxT("data/tips.txt");  //load default file
01378 
01379     DEBUG_INFO("Reading tips from " << strFile.mb_str(wxConvLocal));
01380     wxTipProvider *tipProvider = new LocalizedFileTipProvider(strFile, nValue);
01381     bShowAtStartup = wxShowTip(wxGetActiveWindow(), tipProvider, (nValue ? true : false));
01382 
01383     //store startup preferences
01384     nValue = (bShowAtStartup ? tipProvider->GetCurrentTip() : 0);
01385     DEBUG_INFO("Writing tip index: " << nValue);
01386     config->Write(wxT("/MainFrame/ShowStartTip"), nValue);
01387     delete tipProvider;
01388 }
01389 
01390 
01391 void MainFrame::OnShowPrefs(wxCommandEvent & e)
01392 {
01393     DEBUG_TRACE("");
01394     PreferencesDialog pref_dlg(wxGetActiveWindow());
01395     pref_dlg.ShowModal();
01396     //update image cache size
01397     wxConfigBase* cfg=wxConfigBase::Get();
01398 #if defined __WXMSW__
01399     unsigned long long mem = HUGIN_IMGCACHE_UPPERBOUND;
01400     unsigned long mem_low = cfg->Read(wxT("/ImageCache/UpperBound"), HUGIN_IMGCACHE_UPPERBOUND);
01401     unsigned long mem_high = cfg->Read(wxT("/ImageCache/UpperBoundHigh"), (long) 0);
01402     if (mem_high > 0)
01403     {
01404       mem = ((unsigned long long) mem_high << 32) + mem_low;
01405     }
01406     else
01407     {
01408       mem = mem_low;
01409     }
01410     ImageCache::getInstance().SetUpperLimit(mem);
01411 #else
01412     ImageCache::getInstance().SetUpperLimit(cfg->Read(wxT("/ImageCache/UpperBound"), HUGIN_IMGCACHE_UPPERBOUND));
01413 #endif
01414     images_panel->ReloadCPDetectorSettings();
01415     if(gl_preview_frame)
01416     {
01417         gl_preview_frame->SetShowProjectionHints(cfg->Read(wxT("/GLPreviewFrame/ShowProjectionHints"),HUGIN_SHOW_PROJECTION_HINTS)!=0);
01418     };
01419 }
01420 
01421 void MainFrame::UpdatePanels( wxCommandEvent& WXUNUSED(event) )
01422 {   // Maybe this can be invoced by the Panorama::Changed() or
01423     // something like this. So no everytime update would be needed.
01424     DEBUG_TRACE("");
01425 }
01426 
01427 void MainFrame::OnTogglePreviewFrame(wxCommandEvent & e)
01428 {
01429     DEBUG_TRACE("");
01430     if (preview_frame->IsIconized()) {
01431         preview_frame->Iconize(false);
01432     }
01433     preview_frame->Show();
01434     preview_frame->Raise();
01435 
01436         // we need to force an update since autoupdate fires
01437         // before the preview frame is shown
01438     wxCommandEvent dummy;
01439         preview_frame->OnUpdate(dummy);
01440 }
01441 
01442 void MainFrame::OnToggleGLPreviewFrame(wxCommandEvent & e)
01443 {
01444     if(gl_preview_frame==NULL)
01445     {
01446         return;
01447     };
01448 #if defined __WXMSW__ || defined __WXMAC__
01449     gl_preview_frame->InitPreviews();
01450 #endif
01451     if (gl_preview_frame->IsIconized()) {
01452         gl_preview_frame->Iconize(false);
01453     }
01454     gl_preview_frame->Show();
01455 #if defined __WXMSW__
01456     // on wxMSW Show() does not send OnShowEvent needed to update the
01457     // visibility state of the fast preview windows
01458     // so explicit calling this event handler
01459     wxShowEvent se;
01460     se.SetShow(true);
01461     gl_preview_frame->OnShowEvent(se);
01462 #elif defined __WXGTK__
01463     gl_preview_frame->LoadOpenGLLayout();
01464 #endif
01465     gl_preview_frame->Raise();
01466 }
01467 
01468 void MainFrame::OnShowCPFrame(wxCommandEvent & e)
01469 {
01470     DEBUG_TRACE("");
01471     if (cp_frame) {
01472         if (cp_frame->IsIconized()) {
01473             cp_frame->Iconize(false);
01474         }
01475         cp_frame->Show();
01476         cp_frame->Raise();
01477     } else {
01478         cp_frame = new CPListFrame(this, pano);
01479         cp_frame->Show();
01480     }
01481 }
01482 
01483 void MainFrame::OnCPListFrameClosed()
01484 {
01485     cp_frame = 0;
01486 }
01487 
01488 void MainFrame::OnOptimize(wxCommandEvent & e)
01489 {
01490     DEBUG_TRACE("");
01491     wxCommandEvent dummy;
01492     opt_panel->OnOptimizeButton(dummy);
01493 }
01494 
01495 void MainFrame::OnOnlyActiveImages(wxCommandEvent &e)
01496 {
01497     SetOptimizeOnlyActiveImages(GetMenuBar()->IsChecked(XRCID("action_optimize_only_active")));
01498 };
01499 
01500 void MainFrame::SetOptimizeOnlyActiveImages(const bool onlyActive)
01501 {
01502     m_optOnlyActiveImages = onlyActive;
01503     wxMenuBar* menubar = GetMenuBar();
01504     if (menubar)
01505     {
01506         menubar->Check(XRCID("action_optimize_only_active"), onlyActive);
01507     };
01508     opt_panel->SetOnlyActiveImages(m_optOnlyActiveImages);
01509     opt_photo_panel->SetOnlyActiveImages(m_optOnlyActiveImages);
01510     // notify all observer so they can update their display
01511     pano.changeFinished();
01512 };
01513 
01514 const bool MainFrame::GetOptimizeOnlyActiveImages() const
01515 {
01516     return m_optOnlyActiveImages;
01517 };
01518 
01519 void MainFrame::OnIgnoreLineCp(wxCommandEvent &e)
01520 {
01521     m_optIgnoreLineCp = GetMenuBar()->IsChecked(XRCID("action_optimize_ignore_line_cp"));
01522     opt_panel->SetIgnoreLineCP(m_optIgnoreLineCp);
01523     // notify all observer so they can update their display
01524     pano.changeFinished();
01525 };
01526 
01527 void MainFrame::SetOptimizeIgnoreLineCp(const bool ignoreLineCP)
01528 {
01529     m_optIgnoreLineCp = ignoreLineCP;
01530     wxMenuBar* menubar = GetMenuBar();
01531     if (menubar)
01532     {
01533         menubar->Check(XRCID("action_optimize_ignore_line_cp"), ignoreLineCP);
01534         // notify all observer so they can update their display
01535         pano.changeFinished();
01536     };
01537 };
01538 
01539 const bool MainFrame::GetOptimizeIgnoreLineCp() const
01540 {
01541     return m_optIgnoreLineCp;
01542 };
01543 
01544 void MainFrame::OnPhotometricOptimize(wxCommandEvent & e)
01545 {
01546     wxCommandEvent dummy;
01547     opt_photo_panel->OnOptimizeButton(dummy);
01548 };
01549 
01550 void MainFrame::OnDoStitch(wxCommandEvent & e)
01551 {
01552     DEBUG_TRACE("");
01553     wxCommandEvent cmdEvt(wxEVT_COMMAND_BUTTON_CLICKED,XRCID("pano_button_stitch"));
01554     pano_panel->GetEventHandler()->AddPendingEvent(cmdEvt);
01555 }
01556 
01557 void MainFrame::OnUserDefinedStitch(wxCommandEvent & e)
01558 {
01559     pano_panel->DoUserDefinedStitch();
01560 }
01561 
01562 void MainFrame::OnUserDefinedStitchSaved(wxCommandEvent & e)
01563 {
01564     auto filename = m_userOutput.find(e.GetId());
01565     if (filename != m_userOutput.end())
01566     {
01567         pano_panel->DoUserDefinedStitch(filename->second);
01568     }
01569     else
01570     {
01571         wxBell();
01572     };
01573 }
01574 
01575 void MainFrame::OnMergeProject(wxCommandEvent & e)
01576 {
01577     // get the global config object
01578     wxConfigBase* config = wxConfigBase::Get();
01579 
01580     wxString defaultdir = config->Read(wxT("/actualPath"),wxT(""));
01581     wxFileDialog dlg(wxGetActiveWindow(),
01582                      _("Open project file"),
01583                      defaultdir, wxT(""),
01584                      _("Project files (*.pto)|*.pto|All files (*)|*"),
01585                      wxFD_OPEN, wxDefaultPosition);
01586     dlg.SetDirectory(defaultdir);
01587     if (dlg.ShowModal() == wxID_OK)
01588     {
01589         wxString filename = dlg.GetPath();
01590         wxFileName fname(filename);
01591         wxString path = fname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
01592         if (fname.IsOk() && fname.FileExists())
01593         {
01594             wxBusyCursor wait;
01595             HuginBase::PanoramaMemento newPano;
01596             std::ifstream in((const char *)fname.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
01597             int ptoversion=0;
01598             if (newPano.loadPTScript(in, ptoversion, (const char *)path.mb_str(HUGIN_CONV_FILENAME)))
01599             {
01600                 HuginBase::Panorama new_pano;
01601                 new_pano.setMemento(newPano);
01602                 PanoCommand::GlobalCmdHist::getInstance().addCommand(
01603                     new PanoCommand::MergePanoCmd(pano, new_pano)
01604                 );
01605                 m_mruFiles.AddFileToHistory(fname.GetFullPath());
01606                 // force update of preview window
01607                 if ( !(preview_frame->IsIconized() ||(! preview_frame->IsShown()) ) )
01608                 {
01609                     wxCommandEvent dummy;
01610                     preview_frame->OnUpdate(dummy);
01611                 };
01612             }
01613             else
01614             {
01615                 wxMessageBox(wxString::Format(_("Could not read project file %s."),fname.GetFullPath().c_str()),_("Error"),wxOK|wxICON_ERROR);
01616             };
01617         };
01618     }
01619 }
01620 
01621 void MainFrame::OnReadPapywizard(wxCommandEvent & e)
01622 {
01623     wxString currentDir = wxConfigBase::Get()->Read(wxT("/actualPath"), wxT(""));
01624     wxFileDialog dlg(wxGetActiveWindow(), _("Open Papywizard xml file"),
01625         currentDir, wxT(""), _("Papywizard xml files (*.xml)|*.xml|All files (*)|*"),
01626         wxFD_OPEN, wxDefaultPosition);
01627     dlg.SetDirectory(currentDir);
01628     if (dlg.ShowModal() == wxID_OK)
01629     {
01630         wxConfigBase::Get()->Write(wxT("/actualPath"), dlg.GetDirectory());
01631         Papywizard::ImportPapywizardFile(dlg.GetPath(), pano);
01632     };
01633 };
01634 
01635 void MainFrame::OnApplyTemplate(wxCommandEvent & e)
01636 {
01637     // get the global config object
01638     wxConfigBase* config = wxConfigBase::Get();
01639 
01640     wxFileDialog dlg(wxGetActiveWindow(),
01641                      _("Choose template project"),
01642                      config->Read(wxT("/templatePath"),wxT("")), wxT(""),
01643                      _("Project files (*.pto)|*.pto|All files (*)|*"),
01644                      wxFD_OPEN, wxDefaultPosition);
01645     dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/templatePath"),wxT("")));
01646     if (dlg.ShowModal() == wxID_OK) {
01647         wxString filename = dlg.GetPath();
01648         wxConfig::Get()->Write(wxT("/templatePath"), dlg.GetDirectory());  // remember for later
01649 
01650         std::ifstream file((const char *)filename.mb_str(HUGIN_CONV_FILENAME));
01651 
01652         PanoCommand::GlobalCmdHist::getInstance().addCommand(
01653             new PanoCommand::wxApplyTemplateCmd(pano, file));
01654 
01655     }
01656 }
01657 
01658 void MainFrame::OnOpenPTBatcher(wxCommandEvent & e)
01659 {
01660 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
01661         // Original patch for OSX by Charlie Reiman dd. 18 June 2011
01662         // Slightly modified by HvdW. Errors in here are mine, not Charlie's. 
01663         FSRef appRef;
01664         FSRef actuallyLaunched;
01665         OSStatus err;
01666         FSRef documentArray[1]; // Don't really need an array if we only have 1 item
01667         LSLaunchFSRefSpec launchSpec;
01668         Boolean  isDir;
01669         
01670         err = LSFindApplicationForInfo(kLSUnknownCreator,
01671                                                                    CFSTR("net.sourceforge.hugin.PTBatcherGUI"),
01672                                                                    NULL,
01673                                                                    &appRef,
01674                                                                    NULL);
01675         if (err != noErr) {
01676                 // error, can't find PTBatcherGUI
01677                 wxMessageBox(wxString::Format(_("External program %s not found in the bundle, reverting to system path"), wxT("open")), _("Error"));
01678                 // Possibly a silly attempt otherwise the previous would have worked as well, but just try it.
01679                 wxExecute(_T("open -b net.sourceforge.hugin.PTBatcherGUI"));
01680         }
01681         else {
01682                 wxExecute(_T("open -b net.sourceforge.hugin.PTBatcherGUI"));
01683         }       
01684 #else
01685     const wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
01686         wxExecute(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + _T("PTBatcherGUI"));
01687 #endif
01688 }
01689 
01690 void MainFrame::OnFineTuneAll(wxCommandEvent & e)
01691 {
01692     DEBUG_TRACE("");
01693     // fine-tune all points
01694 
01695     HuginBase::CPVector cps = pano.getCtrlPoints();
01696 
01697     // create a map of all control points.
01698     std::set<unsigned int> unoptimized;
01699     for (unsigned int i=0; i < cps.size(); i++) {
01700         // create all control points.
01701         unoptimized.insert(i);
01702     }
01703 
01704     unsigned int nGood=0;
01705     unsigned int nBad=0;
01706 
01707     wxConfigBase *cfg = wxConfigBase::Get();
01708     double corrThresh=HUGIN_FT_CORR_THRESHOLD;
01709     cfg->Read(wxT("/Finetune/CorrThreshold"), &corrThresh, HUGIN_FT_CORR_THRESHOLD);
01710     double curvThresh = HUGIN_FT_CURV_THRESHOLD;
01711     cfg->Read(wxT("/Finetune/CurvThreshold"),&curvThresh, HUGIN_FT_CURV_THRESHOLD);
01712     // load parameters
01713     const long templWidth = cfg->Read(wxT("/Finetune/TemplateSize"), HUGIN_FT_TEMPLATE_SIZE);
01714     const long sWidth = templWidth + cfg->Read(wxT("/Finetune/LocalSearchWidth"), HUGIN_FT_LOCAL_SEARCH_WIDTH);
01715 
01716     {
01717         ProgressReporterDialog progress(unoptimized.size(), _("Fine-tuning all points"), _("Fine-tuning"), wxGetActiveWindow());
01718 
01719     ImageCache & imgCache = ImageCache::getInstance();
01720 
01721     // do not process the control points in random order,
01722     // but walk from image to image, to reduce image reloading
01723     // in low mem situations.
01724     for (unsigned int imgNr = 0 ; imgNr < pano.getNrOfImages(); imgNr++) {
01725         std::set<unsigned int>::iterator it=unoptimized.begin();
01726 
01727         imgCache.softFlush();
01728 
01729         while (it != unoptimized.end()) {
01730             if (cps[*it].image1Nr == imgNr || cps[*it].image2Nr == imgNr) {
01731                 if (!progress.updateDisplayValue())
01732                 {
01733                     return;
01734                 };
01735                 if (cps[*it].mode == HuginBase::ControlPoint::X_Y) {
01736                     // finetune only normal points
01737                     DEBUG_DEBUG("fine tuning point: " << *it);
01738                     wxImage wxSearchImg;
01739                     ImageCache::ImageCacheRGB8Ptr searchImg = imgCache.getImage(
01740                         pano.getImage(cps[*it].image2Nr).getFilename())->get8BitImage();
01741 
01742                     ImageCache::ImageCacheRGB8Ptr templImg = imgCache.getImage(
01743                         pano.getImage(cps[*it].image1Nr).getFilename())->get8BitImage();
01744 
01745                     vigra_ext::CorrelationResult res;
01746                     vigra::Diff2D roundP1(hugin_utils::roundi(cps[*it].x1), hugin_utils::roundi(cps[*it].y1));
01747                     vigra::Diff2D roundP2(hugin_utils::roundi(cps[*it].x2), hugin_utils::roundi(cps[*it].y2));
01748 
01749                     res = PointFineTuneProjectionAware(pano.getImage(cps[*it].image1Nr), *templImg, roundP1, templWidth,
01750                         pano.getImage(cps[*it].image2Nr), *searchImg, roundP2, sWidth);
01751 
01752                     // invert curvature. we always assume its a maxima, the curvature there is negative
01753                     // however, we allow the user to specify a positive threshold, so we need to
01754                     // invert it
01755                     res.curv.x = - res.curv.x;
01756                     res.curv.y = - res.curv.y;
01757 
01758                     if (res.maxi < corrThresh || res.curv.x < curvThresh || res.curv.y < curvThresh ||
01759                         res.maxpos.x < 0 || res.maxpos.y < 0 || res.corrPos.x < 0 || res.corrPos.y < 0)
01760                     {
01761                         // Bad correlation result.
01762                         nBad++;
01763                         if (res.maxi >= corrThresh) {
01764                             cps[*it].error = 0;
01765                         }
01766                         cps[*it].error = res.maxi;
01767                         DEBUG_DEBUG("low correlation: " << res.maxi << " curv: " << res.curv);
01768                     } else {
01769                         nGood++;
01770                         // only update if a good correlation was found
01771                         cps[*it].x1 = res.corrPos.x;
01772                         cps[*it].y1 = res.corrPos.y;
01773                         cps[*it].x2 = res.maxpos.x;
01774                         cps[*it].y2 = res.maxpos.y;
01775                         cps[*it].error = res.maxi;
01776                     }
01777                 }
01778                 unsigned int rm = *it;
01779                 ++it;
01780                 unoptimized.erase(rm);
01781             } else {
01782                 ++it;
01783             }
01784         }
01785     }
01786     }
01787     wxString result;
01788     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"),
01789                   nGood, nBad, corrThresh);
01790     wxMessageBox(result, _("Fine-tune result"), wxOK);
01791     // set newly optimized points
01792     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01793         new PanoCommand::UpdateCPsCmd(pano, cps, false)
01794         );
01795 }
01796 
01797 void MainFrame::OnRemoveCPinMasks(wxCommandEvent & e)
01798 {
01799     if(pano.getCtrlPoints().size()<2)
01800         return;
01801     HuginBase::UIntSet cps=getCPinMasks(pano);
01802     if(cps.size()>0)
01803     {
01804         PanoCommand::GlobalCmdHist::getInstance().addCommand(
01805                     new PanoCommand::RemoveCtrlPointsCmd(pano,cps)
01806                     );
01807         wxMessageBox(wxString::Format(_("Removed %lu control points"), static_cast<unsigned long>(cps.size())),
01808                    _("Removing control points in masks"),wxOK|wxICON_INFORMATION);
01809     };
01810 }
01811 
01812 #ifdef HUGIN_HSI
01813 void MainFrame::OnPythonScript(wxCommandEvent & e)
01814 {
01815     wxString fname;
01816     wxFileDialog dlg(wxGetActiveWindow(),
01817             _("Select python script"),
01818             wxConfigBase::Get()->Read(wxT("/lensPath"),wxT("")), wxT(""),
01819             _("Python script (*.py)|*.py|All files (*.*)|*.*"),
01820             wxFD_OPEN, wxDefaultPosition);
01821     dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/pythonScriptPath"),wxT("")));
01822 
01823     if (dlg.ShowModal() == wxID_OK)
01824     {
01825         wxString filename = dlg.GetPath();
01826         wxConfig::Get()->Write(wxT("/pythonScriptPath"), dlg.GetDirectory());
01827         std::string scriptfile((const char *)filename.mb_str(HUGIN_CONV_FILENAME));
01828         PanoCommand::GlobalCmdHist::getInstance().addCommand(
01829             new PanoCommand::PythonScriptPanoCmd(pano,scriptfile)
01830             );
01831     }
01832 }
01833 
01834 void MainFrame::OnPlugin(wxCommandEvent & e)
01835 {
01836     wxFileName file=m_plugins[e.GetId()];
01837     if(file.FileExists())
01838     {
01839         std::string scriptfile((const char *)file.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
01840         PanoCommand::GlobalCmdHist::getInstance().addCommand(
01841                                  new PanoCommand::PythonScriptPanoCmd(pano,scriptfile)
01842                                  );
01843     }
01844     else
01845     {
01846         wxMessageBox(wxString::Format(wxT("Python-Script %s not found.\nStopping processing."),file.GetFullPath().c_str()),_("Warning"),wxOK|wxICON_INFORMATION);
01847     };
01848 }
01849 
01850 #endif
01851 
01852 void MainFrame::OnUndo(wxCommandEvent & e)
01853 {
01854     DEBUG_TRACE("OnUndo");
01855     if (PanoCommand::GlobalCmdHist::getInstance().canUndo())
01856     {
01857         PanoCommand::GlobalCmdHist::getInstance().undo();
01858     }
01859     else
01860     {
01861         wxBell();
01862     };
01863 }
01864 
01865 void MainFrame::OnRedo(wxCommandEvent & e)
01866 {
01867     DEBUG_TRACE("OnRedo");
01868     if (PanoCommand::GlobalCmdHist::getInstance().canRedo())
01869     {
01870         PanoCommand::GlobalCmdHist::getInstance().redo();
01871     };
01872 }
01873 
01874 void MainFrame::ShowCtrlPoint(unsigned int cpNr)
01875 {
01876     DEBUG_DEBUG("Showing control point " << cpNr);
01877     m_notebook->SetSelection(2);
01878     cpe->ShowControlPoint(cpNr);
01879 }
01880 
01881 void MainFrame::ShowCtrlPointEditor(unsigned int img1, unsigned int img2)
01882 {
01883     if(!IsShown())
01884     {
01885         Show();
01886         Raise();
01887     };
01888     m_notebook->SetSelection(2);
01889     cpe->setLeftImage(img1);
01890     cpe->setRightImage(img2);
01891 }
01892 
01893 void MainFrame::ShowMaskEditor(size_t imgNr)
01894 {
01895     if(!IsShown())
01896     {
01897         Show();
01898         Raise();
01899     };
01900     m_notebook->SetSelection(1);
01901     mask_panel->setImage(imgNr, true);
01902 };
01903 
01904 void MainFrame::ShowStitcherTab()
01905 {
01907     if(m_show_opt_panel && m_show_opt_photo_panel)
01908     {
01909         m_notebook->SetSelection(5);
01910     }
01911     else
01912     {
01913         if(m_show_opt_panel || m_show_opt_photo_panel)
01914         {
01915             m_notebook->SetSelection(4);
01916         }
01917         else
01918         {
01919             m_notebook->SetSelection(3);
01920         };
01921     };
01922 }
01923 
01925 void MainFrame::updateProgressDisplay()
01926 {
01927     wxString msg;
01928     if (!m_message.empty())
01929     {
01930         msg = wxGetTranslation(wxString(m_message.c_str(), wxConvLocal));
01931         if (!m_filename.empty())
01932         {
01933             msg.Append(wxT(" "));
01934             msg.Append(wxString(ProgressDisplay::m_filename.c_str(), HUGIN_CONV_FILENAME));
01935         };
01936     };
01937     GetStatusBar()->SetStatusText(msg, 0);
01938 
01939 #ifdef __WXMSW__
01940     UpdateWindow(NULL);
01941 #endif
01942 }
01943 
01944 void MainFrame::enableTools(bool option)
01945 {
01946     wxToolBar* theToolBar = GetToolBar();
01947     theToolBar->EnableTool(XRCID("action_optimize"), option);
01948     theToolBar->EnableTool(XRCID("ID_SHOW_PREVIEW_FRAME"), option);
01949     //theToolBar->EnableTool(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), option);
01950     wxMenuBar* theMenuBar = GetMenuBar();
01951     theMenuBar->Enable(XRCID("action_optimize"), option);
01952     theMenuBar->Enable(XRCID("action_finetune_all_cp"), option);
01953     theMenuBar->Enable(XRCID("action_remove_cp_in_masks"), option);
01954     theMenuBar->Enable(XRCID("ID_SHOW_PREVIEW_FRAME"), option);
01955     theMenuBar->Enable(XRCID("action_stitch"), option);
01956     theMenuBar->Enable(XRCID("action_stitch_userdefined"), option);
01957     const int userOutputMenuId = theMenuBar->FindMenuItem(_("&Output"), _("User defined output sequences"));
01958     if (userOutputMenuId != wxNOT_FOUND)
01959     {
01960         theMenuBar->Enable(userOutputMenuId, option);
01961     };
01962     m_menu_file_advanced->Enable(XRCID("action_import_papywizard"), option);
01963     //theMenuBar->Enable(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), option);
01964 }
01965 
01966 
01967 void MainFrame::OnSize(wxSizeEvent &e)
01968 {
01969 #ifdef DEBUG
01970     wxSize sz = this->GetSize();
01971     wxSize csz = this->GetClientSize();
01972     wxSize vsz = this->GetVirtualSize();
01973     DEBUG_TRACE(" size:" << sz.x << "," << sz.y <<
01974                 " client: "<< csz.x << "," << csz.y <<
01975                 " virtual: "<< vsz.x << "," << vsz.y);
01976 #endif
01977 
01978     Layout();
01979     e.Skip();
01980 }
01981 
01982 CPDetectorSetting& MainFrame::GetDefaultSetting()
01983 {
01984     return images_panel->GetDefaultSetting();
01985 };
01986 
01987 void MainFrame::RunCPGenerator(CPDetectorSetting &setting, const HuginBase::UIntSet& img)
01988 {
01989     images_panel->RunCPGenerator(setting, img);
01990 };
01991 
01992 void MainFrame::RunCPGenerator(const HuginBase::UIntSet& img)
01993 {
01994     images_panel->RunCPGenerator(img);
01995 };
01996 
01997 const wxString MainFrame::GetSelectedCPGenerator()
01998 {
01999     return images_panel->GetSelectedCPGenerator();
02000 };
02001 
02002 const wxString & MainFrame::GetXRCPath()
02003 {
02004      return huginApp::Get()->GetXRCPath();
02005 };
02006 
02007 const wxString & MainFrame::GetDataPath()
02008 {
02009     return wxGetApp().GetDataPath();
02010 };
02011 
02013 MainFrame * MainFrame::Get()
02014 {
02015     if (m_this) {
02016         return m_this;
02017     } else {
02018         DEBUG_FATAL("MainFrame not yet created");
02019         DEBUG_ASSERT(m_this);
02020         return 0;
02021     }
02022 }
02023 
02024 wxString MainFrame::getProjectName()
02025 {
02026     return m_filename;
02027 }
02028 
02029 void MainFrame::OnMRUFiles(wxCommandEvent &e)
02030 {
02031     size_t index = e.GetId() - wxID_FILE1;
02032     wxString f(m_mruFiles.GetHistoryFile(index));
02033     if (!f.empty())
02034     {
02035         wxFileName fn(f);
02036         if (fn.FileExists())
02037         {
02038             // if closing old project was canceled do nothing
02039             if (CloseProject(true, LOAD_NEW_PROJECT))
02040             {
02041                 // remove old images from cache
02042                 ImageCache::getInstance().flush();
02043                 // finally load project
02044                 LoadProjectFile(f);
02045             };
02046         }
02047         else
02048         {
02049             m_mruFiles.RemoveFileFromHistory(index);
02050             wxMessageBox(wxString::Format(_("File \"%s\" not found.\nMaybe file was renamed, moved or deleted."),f.c_str()),
02051                 _("Error!"),wxOK | wxICON_INFORMATION );
02052         };
02053     };
02054 }
02055 
02056 void MainFrame::OnFullScreen(wxCommandEvent & e)
02057 {
02058     ShowFullScreen(!IsFullScreen(), wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION);
02059 #ifdef __WXGTK__
02060     //workaround a wxGTK bug that also the toolbar is hidden, but not requested to hide
02061     GetToolBar()->Show(true);
02062 #endif
02063 };
02064 
02065 struct celeste::svm_model* MainFrame::GetSVMModel()
02066 {
02067     if(svmModel==NULL)
02068     {
02069         // determine file name of SVM model file
02070         // get XRC path from application
02071         wxString wxstrModelFileName = huginApp::Get()->GetDataPath() + wxT(HUGIN_CELESTE_MODEL);
02072         // convert wxString to string
02073         std::string strModelFileName(wxstrModelFileName.mb_str(HUGIN_CONV_FILENAME));
02074 
02075         // SVM model file
02076         if (! wxFile::Exists(wxstrModelFileName) ) {
02077             wxMessageBox(wxString::Format(_("Celeste model expected in %s not found, Hugin needs to be properly installed."),wxstrModelFileName.c_str()), _("Fatal Error"));
02078             return NULL;
02079         }
02080         if(!celeste::loadSVMmodel(svmModel,strModelFileName))
02081         {
02082             wxMessageBox(wxString::Format(_("Could not load Celeste model file %s"),wxstrModelFileName.c_str()),_("Error"));
02083             svmModel=NULL;
02084         };
02085     }
02086     return svmModel;
02087 };
02088 
02089 GLPreviewFrame * MainFrame::getGLPreview()
02090 {
02091     return gl_preview_frame;
02092 }
02093 
02094 void MainFrame::SetGuiLevel(GuiLevel newLevel)
02095 {
02096     if(gl_preview_frame==NULL && newLevel==GUI_SIMPLE)
02097     {
02098         SetGuiLevel(GUI_ADVANCED);
02099         return;
02100     };
02101     if(m_guiLevel==GUI_EXPERT && newLevel!=GUI_EXPERT && pano.getOptimizerSwitch()==0)
02102     {
02103         bool needsUpdateOptimizerVar=false;
02104         HuginBase::OptimizeVector optVec = pano.getOptimizeVector();
02105         for(size_t i=0; i<optVec.size(); i++)
02106         {
02107             bool hasTrX=optVec[i].erase("TrX")>0;
02108             bool hasTrY=optVec[i].erase("TrY")>0;
02109             bool hasTrZ=optVec[i].erase("TrZ")>0;
02110             bool hasTpy=optVec[i].erase("Tpy")>0;
02111             bool hasTpp=optVec[i].erase("Tpp")>0;
02112             bool hasg=optVec[i].erase("g")>0;
02113             bool hast=optVec[i].erase("t")>0;
02114             needsUpdateOptimizerVar=needsUpdateOptimizerVar || hasTrX || hasTrY || hasTrZ || hasTpy || hasTpp || hasg || hast;
02115         };
02116         if(needsUpdateOptimizerVar)
02117         {
02118             PanoCommand::GlobalCmdHist::getInstance().addCommand(
02119                 new PanoCommand::UpdateOptimizeVectorCmd(pano, optVec)
02120             );
02121         };
02122     };
02123     if(newLevel==GUI_SIMPLE && pano.getPhotometricOptimizerSwitch()==0)
02124     {
02125         bool needsUpdateOptimizerVar=false;
02126         HuginBase::OptimizeVector optVec = pano.getOptimizeVector();
02127         for(size_t i=0; i<optVec.size(); i++)
02128         {
02129             bool hasVx=optVec[i].erase("Vx")>0;
02130             bool hasVy=optVec[i].erase("Vy")>0;
02131             needsUpdateOptimizerVar=needsUpdateOptimizerVar || hasVx || hasVy;
02132         };
02133         if(needsUpdateOptimizerVar)
02134         {
02135             PanoCommand::GlobalCmdHist::getInstance().addCommand(
02136                 new PanoCommand::UpdateOptimizeVectorCmd(pano, optVec)
02137             );
02138         };
02139     };
02140     m_guiLevel=newLevel;
02141     images_panel->SetGuiLevel(m_guiLevel);
02142     opt_panel->SetGuiLevel(m_guiLevel);
02143     opt_photo_panel->SetGuiLevel(m_guiLevel);
02144     pano_panel->SetGuiLevel(m_guiLevel);
02145     if(gl_preview_frame)
02146     {
02147         gl_preview_frame->SetGuiLevel(m_guiLevel);
02148     };
02149     switch(m_guiLevel)
02150     {
02151         case GUI_SIMPLE:
02152             GetMenuBar()->FindItem(XRCID("action_gui_simple"))->Check();
02153             break;
02154         case GUI_ADVANCED:
02155             GetMenuBar()->FindItem(XRCID("action_gui_advanced"))->Check();
02156             break;
02157         case GUI_EXPERT:
02158             GetMenuBar()->FindItem(XRCID("action_gui_expert"))->Check();
02159             break;
02160     };
02161     if(m_guiLevel==GUI_SIMPLE)
02162     {
02163         if(!gl_preview_frame->IsShown())
02164         {
02165             wxCommandEvent dummy;
02166             OnToggleGLPreviewFrame(dummy);
02167         };
02168         wxGetApp().SetTopWindow(gl_preview_frame);
02169         GetMenuBar()->Remove(0);
02170         GetMenuBar()->Insert(0, m_menu_file_simple, _("&File"));
02171         if(m_filename.IsEmpty())
02172         {
02173             gl_preview_frame->SetTitle(_("Hugin - Panorama Stitcher"));
02174             SetTitle(_("Panorama editor"));
02175         }
02176         else
02177         {
02178             wxFileName scriptName = m_filename;
02179             gl_preview_frame->SetTitle(scriptName.GetName() + wxT(".") + scriptName.GetExt() + wxT(" - ") + _("Hugin - Panorama Stitcher"));
02180             SetTitle(scriptName.GetName() + wxT(".") + scriptName.GetExt() + wxT(" - ") + _("Panorama editor"));
02181         };
02182         Hide();
02183     }
02184     else
02185     {
02186         wxGetApp().SetTopWindow(this);
02187         GetMenuBar()->Remove(0);
02188         GetMenuBar()->Insert(0, m_menu_file_advanced, _("&File"));
02189         if(m_filename.IsEmpty())
02190         {
02191             SetTitle(_("Hugin - Panorama Stitcher"));
02192         }
02193         else
02194         {
02195             wxFileName scriptName = m_filename;
02196             SetTitle(scriptName.GetName() + wxT(".") + scriptName.GetExt() + wxT(" - ") + _("Hugin - Panorama Stitcher"));
02197         };
02198         if(!IsShown())
02199         {
02200             Show();
02201         };
02202     };
02203 };
02204 
02205 void MainFrame::OnSetGuiSimple(wxCommandEvent & e)
02206 {
02207     GuiLevel reqGuiLevel=GetMinimumGuiLevel(pano);
02208     if(reqGuiLevel<=GUI_SIMPLE)
02209     {
02210         SetGuiLevel(GUI_SIMPLE);
02211     }
02212     else
02213     {
02214         if(reqGuiLevel==GUI_ADVANCED)
02215         {
02216             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."),
02217 #ifdef __WXMSW__
02218                          wxT("Hugin"),
02219 #else
02220                          wxT(""),
02221 #endif
02222                          wxOK | wxICON_INFORMATION);
02223         }
02224         else
02225         {
02226             wxMessageBox(_("Can't switch to simple interface. The project is using translation or shear parameters.\nThese parameters are not supported in simple interface."),
02227 #ifdef __WXMSW__
02228                          wxT("Hugin"),
02229 #else
02230                          wxT(""),
02231 #endif
02232                          wxOK | wxICON_INFORMATION);
02233         }
02234         SetGuiLevel(m_guiLevel);
02235     };
02236 };
02237 
02238 void MainFrame::OnSetGuiAdvanced(wxCommandEvent & e)
02239 {
02240     GuiLevel reqGuiLevel=GetMinimumGuiLevel(pano);
02241     if(reqGuiLevel<=GUI_ADVANCED)
02242     {
02243         SetGuiLevel(GUI_ADVANCED);
02244     }
02245     else
02246     {
02247         wxMessageBox(_("Can't switch to advanced interface. The project is using translation or shear parameters.\nThese parameters are not supported in advanced interface."),
02248 #ifdef __WXMSW__
02249                      wxT("Hugin"),
02250 #else
02251                      wxT(""),
02252 #endif
02253                      wxOK | wxICON_INFORMATION);
02254         SetGuiLevel(GUI_EXPERT);
02255     };
02256 };
02257 
02258 void MainFrame::OnSetGuiExpert(wxCommandEvent & e)
02259 {
02260     SetGuiLevel(GUI_EXPERT);
02261 };
02262 
02263 void MainFrame::DisableOpenGLTools()
02264 {
02265     GetMenuBar()->Enable(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), false);
02266     GetMenuBar()->Enable(XRCID("action_gui_simple"), false);
02267     GetToolBar()->EnableTool(XRCID("ID_SHOW_GL_PREVIEW_FRAME"), false); 
02268 };
02269 
02270 void MainFrame::RunAssistant(wxWindow* mainWin)
02271 {
02272     //save project into temp directory
02273     wxString tempDir= wxConfig::Get()->Read(wxT("tempDir"),wxT(""));
02274     if(!tempDir.IsEmpty())
02275     {
02276         if(tempDir.Last()!=wxFileName::GetPathSeparator())
02277         {
02278             tempDir.Append(wxFileName::GetPathSeparator());
02279         }
02280     };
02281     wxFileName scriptFileName(wxFileName::CreateTempFileName(tempDir+wxT("ha")));
02282     std::ofstream script(scriptFileName.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
02283     script.exceptions ( std::ofstream::eofbit | std::ofstream::failbit | std::ofstream::badbit );
02284     HuginBase::UIntSet all;
02285     fill_set(all, 0, pano.getNrOfImages()-1);
02286     pano.printPanoramaScript(script, pano.getOptimizeVector(), pano.getOptions(), all, false);
02287     script.close();
02288 
02289     // get assistant queue
02290     const wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
02291     HuginQueue::CommandQueue* commands = HuginQueue::GetAssistantCommandQueue(pano, exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR), scriptFileName.GetFullPath());
02292     //execute queue
02293     int ret = MyExecuteCommandQueue(commands, mainWin, _("Running assistant"));
02294 
02295     //read back panofile
02296     PanoCommand::GlobalCmdHist::getInstance().addCommand(new PanoCommand::wxLoadPTProjectCmd(pano,
02297         (const char *)scriptFileName.GetFullPath().mb_str(HUGIN_CONV_FILENAME), 
02298         (const char *)scriptFileName.GetPath(wxPATH_NATIVE | wxPATH_GET_SEPARATOR).mb_str(HUGIN_CONV_FILENAME), 
02299         ret==0, false));
02300 
02301     //delete temporary files
02302     wxRemoveFile(scriptFileName.GetFullPath());
02303     //if return value is non-zero, an error occurred in the assistant
02304     if(ret!=0)
02305     {
02306         if (pano.getNrOfImages() == 1)
02307         {
02308             wxMessageBox(_("The assistant could not find vertical lines. Please add vertical lines in the panorama editor and optimize project manually."),
02309                 _("Warning"), wxOK | wxICON_INFORMATION, mainWin);
02310         }
02311         else
02312         {
02313             //check for unconnected images
02314             HuginGraph::ImageGraph graph(pano);
02315             const HuginGraph::ImageGraph::Components comps = graph.GetComponents();
02316             if (comps.size() > 1)
02317             {
02318                 // switch to images panel.
02319                 unsigned i1 = *(comps[0].rbegin());
02320                 unsigned i2 = *(comps[1].begin());
02321                 ShowCtrlPointEditor(i1, i2);
02322                 // display message box with 
02323                 wxMessageBox(wxString::Format(_("Warning %d unconnected image groups found:"), static_cast<int>(comps.size())) + Components2Str(comps) + wxT("\n")
02324                     + _("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);
02325                 return;
02326             };
02327             wxMessageBox(_("The assistant did not complete successfully. Please check the resulting project file."),
02328                 _("Warning"), wxOK | wxICON_INFORMATION, mainWin);
02329         };
02330     };
02331 };
02332 
02333 void MainFrame::OnRunAssistant(wxCommandEvent & e)
02334 {
02335     RunAssistant(this);
02336 };
02337 
02338 void MainFrame::OnSendToAssistantQueue(wxCommandEvent &e)
02339 {
02340     wxCommandEvent dummy;
02341     OnSaveProject(dummy);
02342     wxString projectFile = getProjectName();
02343     if(wxFileName::FileExists(projectFile))
02344     {
02345 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
02346         // Original patch for OSX by Charlie Reiman dd. 18 June 2011
02347         // Slightly modified by HvdW. Errors in here are mine, not Charlie's. 
02348         FSRef appRef;
02349         FSRef actuallyLaunched;
02350         OSStatus err;
02351         FSRef documentArray[1]; // Don't really need an array if we only have 1 item
02352         LSLaunchFSRefSpec launchSpec;
02353         Boolean  isDir;
02354 
02355         err = LSFindApplicationForInfo(kLSUnknownCreator,
02356                                        CFSTR("net.sourceforge.hugin.PTBatcherGUI"),
02357                                        NULL,
02358                                        &appRef,
02359                                        NULL);
02360         if (err != noErr)
02361         {
02362             // error, can't find PTBatcherGUI
02363             wxMessageBox(wxString::Format(_("External program %s not found in the bundle, reverting to system path"), wxT("open")), _("Error"));
02364             // Possibly a silly attempt otherwise the previous would have worked as well, but just try it.
02365             wxExecute(_T("open -b net.sourceforge.hugin.PTBatcherGUI ")+hugin_utils::wxQuoteFilename(projectFile));
02366             return;
02367         }
02368 
02369         wxCharBuffer projectFilebuffer=projectFile.ToUTF8();
02370         // Point to document
02371         err = FSPathMakeRef((unsigned char*) projectFilebuffer.data(), &documentArray[0], &isDir);
02372         if (err != noErr || isDir)
02373         {
02374             // Something went wrong.
02375             wxMessageBox(wxString::Format(_("Project file not found"), wxT("open")), _("Error"));
02376             return;
02377         }
02378         launchSpec.appRef = &appRef;
02379         launchSpec.numDocs = sizeof(documentArray)/sizeof(documentArray[0]);
02380         launchSpec.itemRefs = documentArray;
02381         launchSpec.passThruParams = NULL;
02382         launchSpec.launchFlags = kLSLaunchDontAddToRecents + kLSLaunchDontSwitch;
02383         launchSpec.asyncRefCon = NULL;
02384 
02385         err = LSOpenFromRefSpec(&launchSpec, &actuallyLaunched);
02386         if (err != noErr && err != kLSLaunchInProgressErr)
02387         {  
02388             // Should be ok if it's in progress... I think. 
02389             // Launch failed.
02390             wxMessageBox(wxString::Format(_("Can't launch PTBatcherGui"), wxT("open")), _("Error"));
02391             return;
02392         }
02393 
02394         // Should verify that actuallyLaunched and appRef are the same.
02395         if (FSCompareFSRefs(&appRef, &actuallyLaunched) != noErr)
02396         {
02397             // error, lauched the wrong thing.
02398             wxMessageBox(wxString::Format(_("Launched incorrect programme"), wxT("open")), _("Error"));
02399             return;
02400         }
02401 #else
02402         const wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
02403         wxExecute(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + wxT("PTBatcherGUI -a ")+hugin_utils::wxQuoteFilename(projectFile));
02404 #endif
02405     }
02406 };
02407 
02408 wxString MainFrame::GetCurrentOptimizerString()
02409 {
02410     return images_panel->GetCurrentOptimizerString();
02411 };
02412 
02413 MainFrame * MainFrame::m_this = 0;

Generated on 23 Sep 2017 for Hugintrunk by  doxygen 1.4.7