hugin_stitch_project.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00027 #include <hugin_config.h>
00028 #include "panoinc_WX.h"
00029 #include "panoinc.h"
00030 
00031 #include <wx/wfstream.h>
00032 #ifdef __WXMSW__
00033 #include <wx/stdpaths.h>
00034 #endif
00035 
00036 #include <fstream>
00037 #include <sstream>
00038 #include "base_wx/RunStitchPanel.h"
00039 #include "base_wx/huginConfig.h"
00040 #include "base_wx/MyExternalCmdExecDialog.h"
00041 #include "base_wx/platform.h"
00042 #include "base_wx/wxPlatform.h"
00043 
00044 #include <tiffio.h>
00045 
00046 // somewhere SetDesc gets defined.. this breaks wx/cmdline.h on OSX
00047 #ifdef SetDesc
00048 #undef SetDesc
00049 #endif
00050 
00051 #include <wx/cmdline.h>
00052 
00053 class RunStitchFrame: public wxFrame
00054 {
00055 public:
00056     RunStitchFrame(wxWindow * parent, const wxString& title, const wxPoint& pos, const wxSize& size);
00057 
00058     bool StitchProject(const wxString& scriptFile, const wxString& outname, const wxString& userDefinedOutput, bool doDeleteOnExit);
00059 
00060     void OnQuit(wxCommandEvent& event);
00061     void OnAbout(wxCommandEvent& event);
00062     void OnProgress(wxCommandEvent& event);
00064     void SetOverwrite(bool doOverwrite);
00065 
00066 private:
00067 
00068     bool m_isStitching;
00069     wxString m_scriptFile;
00070     bool m_deleteOnExit;
00071     wxGauge* m_progress;
00072 
00073     void OnProcessTerminate(wxProcessEvent & event);
00074     void OnCancel(wxCommandEvent & event);
00075 
00076     RunStitchPanel * m_stitchPanel;
00077 
00078     DECLARE_EVENT_TABLE()
00079 };
00080 
00081 // event ID's for RunStitchPanel
00082 enum
00083 {
00084     ID_Quit = 1,
00085     ID_About   
00086 };
00087 
00088 BEGIN_EVENT_TABLE(RunStitchFrame, wxFrame)
00089     EVT_MENU(ID_Quit,  RunStitchFrame::OnQuit)
00090     EVT_MENU(ID_About, RunStitchFrame::OnAbout)
00091     EVT_BUTTON(wxID_CANCEL, RunStitchFrame::OnCancel)
00092     EVT_END_PROCESS(-1, RunStitchFrame::OnProcessTerminate)
00093     EVT_COMMAND(wxID_ANY, EVT_QUEUE_PROGRESS, RunStitchFrame::OnProgress)
00094 END_EVENT_TABLE()
00095 
00096 RunStitchFrame::RunStitchFrame(wxWindow * parent, const wxString& title, const wxPoint& pos, const wxSize& size)
00097     : wxFrame(parent, -1, title, pos, size), m_isStitching(false)
00098 {
00099     wxBoxSizer * topsizer = new wxBoxSizer( wxVERTICAL );
00100     m_stitchPanel = new RunStitchPanel(this);
00101 
00102     topsizer->Add(m_stitchPanel, 1, wxEXPAND | wxALL, 2);
00103 
00104     wxBoxSizer* bottomsizer = new wxBoxSizer(wxHORIZONTAL);
00105 #if wxCHECK_VERSION(3,1,0)
00106     m_progress = new wxGauge(this, wxID_ANY, 100, wxDefaultPosition, wxDefaultSize, wxGA_HORIZONTAL | wxGA_PROGRESS);
00107 #else
00108     m_progress = new wxGauge(this, wxID_ANY, 100, wxDefaultPosition, wxDefaultSize, wxGA_HORIZONTAL);
00109 #endif
00110     bottomsizer->Add(m_progress, 1, wxEXPAND | wxALL, 10);
00111     bottomsizer->Add( new wxButton(this, wxID_CANCEL, _("Cancel")),
00112                    0, wxALL | wxALIGN_RIGHT, 10);
00113     topsizer->Add(bottomsizer, 0, wxEXPAND);
00114 
00115 #ifdef __WXMSW__
00116     // wxFrame does have a strange background color on Windows..
00117     this->SetBackgroundColour(m_stitchPanel->GetBackgroundColour());
00118 #endif
00119 
00120     SetSizer( topsizer );
00121 //    topsizer->SetSizeHints( this );   // set size hints to honour minimum size
00122     m_deleteOnExit=false;
00123 }
00124 
00125 void RunStitchFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
00126 {
00127     wxMessageBox(wxString::Format(_("HuginStitchProject. Application to stitch hugin project files.\n Version: %s"), hugin_utils::GetHuginVersion().c_str()),
00128                   wxT("About hugin_stitch_project"),
00129                   wxOK | wxICON_INFORMATION );
00130 }
00131 void RunStitchFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
00132 {
00133     DEBUG_TRACE("");
00134     if (m_isStitching) {
00135         m_stitchPanel->CancelStitch();
00136         m_isStitching = false;
00137     }
00138     Close();
00139 }
00140 
00141 void RunStitchFrame::OnCancel(wxCommandEvent& WXUNUSED(event))
00142 {
00143     DEBUG_TRACE("");
00144     if (m_isStitching) {
00145         m_stitchPanel->CancelStitch();
00146         m_isStitching = false;
00147     } else {
00148         Close();
00149     }
00150 }
00151 
00152 void RunStitchFrame::OnProcessTerminate(wxProcessEvent & event)
00153 {
00154     if (! m_isStitching) {
00155         // canceled stitch
00156         // TODO: Cleanup files?
00157         Close();
00158     } else {
00159         m_isStitching = false;
00160         if (event.GetExitCode() != 0)
00161         {
00162             if(wxMessageBox(_("Error during stitching\nPlease report the complete text to the bug tracker on https://bugs.launchpad.net/hugin.\n\nDo you want to save the log file?"),
00163                 _("Error during stitching"), wxICON_ERROR | wxYES_NO )==wxYES)
00164             {
00165                 wxString defaultdir = wxConfigBase::Get()->Read(wxT("/actualPath"),wxT(""));
00166                 wxFileDialog dlg(this,
00167                          _("Specify log file"),
00168                          defaultdir, wxT(""),
00169                          _("Log files (*.log)|*.log|All files (*)|*"),
00170                          wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
00171                 dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
00172                 if (dlg.ShowModal() == wxID_OK)
00173                 {
00174                     wxConfig::Get()->Write(wxT("/actualPath"), dlg.GetDirectory());  // remember for later
00175                     m_stitchPanel->SaveLog(dlg.GetPath());
00176                 };
00177             }
00178         } else {
00179             if(m_deleteOnExit)
00180             {
00181                 wxRemoveFile(m_scriptFile);
00182             };
00183             Close();
00184         }
00185     }
00186 }
00187 
00188 void RunStitchFrame::OnProgress(wxCommandEvent& event)
00189 {
00190     if (event.GetInt() >= 0)
00191     {
00192         m_progress->SetValue(event.GetInt());
00193     };
00194 };
00195 
00196 bool RunStitchFrame::StitchProject(const wxString& scriptFile, const wxString& outname, const wxString& userDefinedOutput, bool doDeleteOnExit)
00197 {
00198     if (! m_stitchPanel->StitchProject(scriptFile, outname, userDefinedOutput)) {
00199         return false;
00200     }
00201     m_isStitching = true;
00202     m_scriptFile=scriptFile;
00203     m_deleteOnExit=doDeleteOnExit;
00204     return true;
00205 }
00206 
00207 void RunStitchFrame::SetOverwrite(bool doOverwrite)
00208 {
00209     m_stitchPanel->SetOverwrite(doOverwrite);
00210 };
00211 
00212 // **********************************************************************
00213 
00214 
00219 class stitchApp : public wxApp
00220 {
00221 public:
00222 
00225     stitchApp();
00226 
00229     virtual ~stitchApp();
00230 
00233     virtual bool OnInit();
00234 
00236     virtual int OnExit();
00237     
00238 #ifdef __WXMAC__
00239 
00240     void MacOpenFile(const wxString &fileName);
00241 #endif
00242 
00243 private:
00244     wxLocale m_locale;
00245 #ifdef __WXMAC__
00246     wxString m_macFileNameToOpenOnStart;
00247 #endif
00248 };
00249 
00250 stitchApp::stitchApp()
00251 {
00252     // suppress tiff warnings
00253     TIFFSetWarningHandler(0);
00254 
00255     DEBUG_TRACE("ctor");
00256 }
00257 
00258 stitchApp::~stitchApp()
00259 {
00260     DEBUG_TRACE("dtor");
00261     DEBUG_TRACE("dtor end");
00262 }
00263 
00264 bool stitchApp::OnInit()
00265 {
00266     // Required to access the preferences of hugin
00267     SetAppName(wxT("hugin"));
00268 
00269 #if defined __WXMSW__
00270     int localeID = wxConfigBase::Get()->Read(wxT("language"), (long) wxLANGUAGE_DEFAULT);
00271     m_locale.Init(localeID);
00272 #else
00273     m_locale.Init(wxLANGUAGE_DEFAULT);
00274 #endif
00275 
00276     // setup the environment for the different operating systems
00277 #if defined __WXMSW__
00278     wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
00279     exePath.RemoveLastDir();
00280     // locale setup
00281     m_locale.AddCatalogLookupPathPrefix(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + wxT("share\\locale"));
00282 
00283 #else
00284     // add the locale directory specified during configure
00285     m_locale.AddCatalogLookupPathPrefix(wxT(INSTALL_LOCALE_DIR));
00286 #endif
00287 
00288 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
00289     {
00290         wxString thePath = MacGetPathToBundledResourceFile(CFSTR("locale"));
00291         if(thePath != wxT(""))
00292             m_locale.AddCatalogLookupPathPrefix(thePath);
00293         else {
00294             wxMessageBox(_("Translations not found in bundle"), _("Fatal Error"));
00295             return false;
00296         }
00297     }
00298 #endif
00299     
00300     // set the name of locale recource to look for
00301     m_locale.AddCatalog(wxT("hugin"));
00302 
00303     // parse arguments
00304     static const wxCmdLineEntryDesc cmdLineDesc[] =
00305     {
00306         //On wxWidgets 2.9, wide characters don't work here.
00307         //On previous versions, the wxT macro is required for unicode builds.
00308 #if wxCHECK_VERSION(2,9,0)
00309       { wxCMD_LINE_SWITCH, "h", "help", "show this help message",
00310         wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
00311       { wxCMD_LINE_OPTION, "o", "output",  "output prefix" },
00312       { wxCMD_LINE_SWITCH, "d", "delete",  "delete pto file after stitching" },
00313       { wxCMD_LINE_SWITCH, "w", "overwrite", "overwrite existing files" },
00314       { wxCMD_LINE_OPTION, "u", "user-defined-output", "use user defined output" },
00315       { wxCMD_LINE_PARAM,  NULL, NULL, "<project>",
00316         wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
00317       { wxCMD_LINE_NONE }
00318 #else 
00319       { wxCMD_LINE_SWITCH, wxT("h"), wxT("help"), wxT("show this help message"),
00320         wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
00321       { wxCMD_LINE_OPTION, wxT("o"), wxT("output"),  wxT("output prefix") },
00322       { wxCMD_LINE_SWITCH, wxT("d"), wxT("delete"),  wxT("delete pto file after stitching") },
00323       { wxCMD_LINE_SWITCH, wxT("w"), wxT("overwrite"), wxT("overwrite existing files") },
00324       { wxCMD_LINE_OPTION, wxT("u"), wxT("user-defined-output"), wxT("use user defined output") },
00325       { wxCMD_LINE_PARAM,  NULL, NULL, wxT("<project>"),
00326         wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
00327       { wxCMD_LINE_NONE }
00328 #endif 
00329     };
00330 
00331     wxCmdLineParser parser(cmdLineDesc, argc, argv);
00332 
00333     switch ( parser.Parse() ) {
00334       case -1: // -h or --help was given, and help displayed so exit
00335         return false;
00336         break;
00337       case 0:  // all is well
00338         break;
00339       default:
00340         wxLogError(_("Syntax error in parameters detected, aborting."));
00341         return false;
00342         break;
00343     }
00344 
00345     wxString scriptFile;
00346 #ifdef __WXMAC__
00347     m_macFileNameToOpenOnStart = wxT("");
00348     wxYield();
00349     scriptFile = m_macFileNameToOpenOnStart;
00350     
00351     // bring myself front (for being called from command line)
00352     {
00353         ProcessSerialNumber selfPSN;
00354         OSErr err = GetCurrentProcess(&selfPSN);
00355         if (err == noErr)
00356         {
00357             SetFrontProcess(&selfPSN);
00358         }
00359     }
00360 #endif
00361     
00362     wxString userDefinedOutput;
00363     parser.Found(wxT("u"), &userDefinedOutput);
00364     if (!userDefinedOutput.IsEmpty())
00365     {
00366         if (!wxFileName::FileExists(userDefinedOutput))
00367         {
00368             wxMessageBox(wxString::Format(_("Could not find the specified user output file \"%s\"."), userDefinedOutput.c_str()),
00369                 _("Error"), wxOK | wxICON_EXCLAMATION);
00370             return false;
00371         };
00372     };
00373     if( parser.GetParamCount() == 0 && wxIsEmpty(scriptFile)) 
00374     {
00375         wxString defaultdir = wxConfigBase::Get()->Read(wxT("/actualPath"),wxT(""));
00376         wxFileDialog dlg(0,
00377                          _("Specify project source project file"),
00378                          defaultdir, wxT(""),
00379                          _("Project files (*.pto)|*.pto|All files (*)|*"),
00380                          wxFD_OPEN, wxDefaultPosition);
00381 
00382         dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
00383         if (dlg.ShowModal() == wxID_OK) {
00384             wxConfig::Get()->Write(wxT("/actualPath"), dlg.GetDirectory());  // remember for later
00385             scriptFile = dlg.GetPath();
00386         } else { // bail
00387             return false;
00388         }
00389     } else if(wxIsEmpty(scriptFile)) {
00390         scriptFile = parser.GetParam(0);
00391         std::cout << "********************* script file: " << (const char *)scriptFile.mb_str(wxConvLocal) << std::endl;
00392         if (! wxIsAbsolutePath(scriptFile)) {
00393             scriptFile = wxGetCwd() + wxFileName::GetPathSeparator() + scriptFile;
00394         }
00395     }
00396 
00397     std::cout << "input file is " << (const char *)scriptFile.mb_str(wxConvLocal) << std::endl;
00398 
00399     wxString outname;
00400 
00401     if ( !parser.Found(wxT("o"), &outname) ) {
00402         // ask for output.
00403         wxFileDialog dlg(0,_("Specify output prefix"),
00404                          wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")),
00405                          wxT(""), wxT(""),
00406                          wxFD_SAVE, wxDefaultPosition);
00407         dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
00408         if (dlg.ShowModal() == wxID_OK) {
00409             while(containsInvalidCharacters(dlg.GetPath()))
00410             {
00411                 wxMessageBox(wxString::Format(_("The given filename contains one of the following invalid characters: %s\nHugin can not work with this filename. Please enter a valid filename."),getInvalidCharacters().c_str()),
00412                     _("Error"),wxOK | wxICON_EXCLAMATION);
00413                 if(dlg.ShowModal()!=wxID_OK)
00414                     return false;
00415             };
00416             wxFileName prefix(dlg.GetPath());
00417             while (!prefix.IsDirWritable())
00418             {
00419                 wxMessageBox(wxString::Format(_("You have no permissions to write in folder \"%s\".\nPlease select another folder for the final output."), prefix.GetPath().c_str()),
00420 #ifdef __WXMSW__
00421                     wxT("Hugin_stitch_project"),
00422 #else
00423                     wxT(""),
00424 #endif
00425                     wxOK | wxICON_INFORMATION);
00426                 if (dlg.ShowModal() != wxID_OK)
00427                 {
00428                     return false;
00429                 };
00430                 prefix = dlg.GetPath();
00431             };
00432 
00433             wxConfig::Get()->Write(wxT("/actualPath"), dlg.GetDirectory());  // remember for later
00434             outname = dlg.GetPath();
00435         } else { // bail
00436 //            wxLogError( _("No project files specified"));
00437             return false;
00438         }
00439     }
00440 
00441     // check output filename
00442     wxFileName outfn(outname);
00443     wxString ext = outfn.GetExt();
00444     // remove extension if it indicates an image file
00445     if (ext.CmpNoCase(wxT("jpg")) == 0 || ext.CmpNoCase(wxT("jpeg")) == 0|| 
00446         ext.CmpNoCase(wxT("tif")) == 0|| ext.CmpNoCase(wxT("tiff")) == 0 || 
00447         ext.CmpNoCase(wxT("png")) == 0 || ext.CmpNoCase(wxT("exr")) == 0 ||
00448         ext.CmpNoCase(wxT("pnm")) == 0 || ext.CmpNoCase(wxT("hdr"))) 
00449     {
00450         outfn.ClearExt();
00451         outname = outfn.GetFullPath();
00452     }
00453 
00454     RunStitchFrame *frame = new RunStitchFrame(NULL, wxT("Hugin Stitcher"), wxDefaultPosition, wxSize(640,600) );
00455     frame->Show( true );
00456     SetTopWindow( frame );
00457 
00458     wxFileName basename(scriptFile);
00459     frame->SetTitle(wxString::Format(_("%s - Stitching"), basename.GetName().c_str()));
00460     frame->SetOverwrite(parser.Found(wxT("w")));
00461     bool n = frame->StitchProject(scriptFile, outname, userDefinedOutput, parser.Found(wxT("d")));
00462     return n;
00463 }
00464 
00465 
00466 int stitchApp::OnExit()
00467 {
00468     DEBUG_TRACE("");
00469     return 0;
00470 }
00471 
00472 
00473 #ifdef __WXMAC__
00474 // wx calls this method when the app gets "Open file" AppleEvent 
00475 void stitchApp::MacOpenFile(const wxString &fileName)
00476 {
00477     m_macFileNameToOpenOnStart = fileName;
00478 }
00479 #endif
00480 
00481 // make wxwindows use this class as the main application
00482 IMPLEMENT_APP(stitchApp)

Generated on 7 Feb 2016 for Hugintrunk by  doxygen 1.4.7