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 #if defined _MSC_VER && defined Hugin_shared
00271     setlocale(LC_NUMERIC, "");
00272 #endif
00273     int localeID = wxConfigBase::Get()->Read(wxT("language"), (long) wxLANGUAGE_DEFAULT);
00274     m_locale.Init(localeID);
00275 #else
00276     m_locale.Init(wxLANGUAGE_DEFAULT);
00277 #endif
00278 
00279     // setup the environment for the different operating systems
00280 #if defined __WXMSW__
00281     wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
00282     exePath.RemoveLastDir();
00283     // locale setup
00284     m_locale.AddCatalogLookupPathPrefix(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + wxT("share\\locale"));
00285 
00286 #else
00287     // add the locale directory specified during configure
00288     m_locale.AddCatalogLookupPathPrefix(wxT(INSTALL_LOCALE_DIR));
00289 #endif
00290 
00291     // set the name of locale recource to look for
00292     m_locale.AddCatalog(wxT("hugin"));
00293 
00294     // parse arguments
00295     static const wxCmdLineEntryDesc cmdLineDesc[] =
00296     {
00297         //On wxWidgets 2.9, wide characters don't work here.
00298         //On previous versions, the wxT macro is required for unicode builds.
00299       { wxCMD_LINE_SWITCH, "h", "help", "show this help message",
00300         wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
00301       { wxCMD_LINE_OPTION, "o", "output",  "output prefix" },
00302       { wxCMD_LINE_SWITCH, "d", "delete",  "delete pto file after stitching" },
00303       { wxCMD_LINE_SWITCH, "w", "overwrite", "overwrite existing files" },
00304       { wxCMD_LINE_OPTION, "u", "user-defined-output", "use user defined output" },
00305       { wxCMD_LINE_PARAM,  NULL, NULL, "<project>",
00306         wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
00307       { wxCMD_LINE_NONE }
00308     };
00309 
00310     wxCmdLineParser parser(cmdLineDesc, argc, argv);
00311 
00312     switch ( parser.Parse() ) {
00313       case -1: // -h or --help was given, and help displayed so exit
00314         return false;
00315         break;
00316       case 0:  // all is well
00317         break;
00318       default:
00319         wxLogError(_("Syntax error in parameters detected, aborting."));
00320         return false;
00321         break;
00322     }
00323 
00324     wxString scriptFile;
00325 #ifdef __WXMAC__
00326     m_macFileNameToOpenOnStart = wxT("");
00327     wxYield();
00328     scriptFile = m_macFileNameToOpenOnStart;
00329     
00330     // bring myself front (for being called from command line)
00331     {
00332         ProcessSerialNumber selfPSN;
00333         OSErr err = GetCurrentProcess(&selfPSN);
00334         if (err == noErr)
00335         {
00336             SetFrontProcess(&selfPSN);
00337         }
00338     }
00339 #endif
00340     
00341     wxString userDefinedOutput;
00342     parser.Found(wxT("u"), &userDefinedOutput);
00343     if (!userDefinedOutput.IsEmpty())
00344     {
00345         if (!wxFileName::FileExists(userDefinedOutput))
00346         {
00347             wxMessageBox(wxString::Format(_("Could not find the specified user output file \"%s\"."), userDefinedOutput.c_str()),
00348                 _("Error"), wxOK | wxICON_EXCLAMATION);
00349             return false;
00350         };
00351     };
00352     if( parser.GetParamCount() == 0 && wxIsEmpty(scriptFile)) 
00353     {
00354         wxString defaultdir = wxConfigBase::Get()->Read(wxT("/actualPath"),wxT(""));
00355         wxFileDialog dlg(0,
00356                          _("Specify project source project file"),
00357                          defaultdir, wxT(""),
00358                          _("Project files (*.pto)|*.pto|All files (*)|*"),
00359                          wxFD_OPEN, wxDefaultPosition);
00360 
00361         dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
00362         if (dlg.ShowModal() == wxID_OK) {
00363             wxConfig::Get()->Write(wxT("/actualPath"), dlg.GetDirectory());  // remember for later
00364             scriptFile = dlg.GetPath();
00365         } else { // bail
00366             return false;
00367         }
00368     } else if(wxIsEmpty(scriptFile)) {
00369         scriptFile = parser.GetParam(0);
00370         std::cout << "********************* script file: " << (const char *)scriptFile.mb_str(wxConvLocal) << std::endl;
00371         if (! wxIsAbsolutePath(scriptFile)) {
00372             scriptFile = wxGetCwd() + wxFileName::GetPathSeparator() + scriptFile;
00373         }
00374     }
00375 
00376     std::cout << "input file is " << (const char *)scriptFile.mb_str(wxConvLocal) << std::endl;
00377 
00378     wxString outname;
00379 
00380     if ( !parser.Found(wxT("o"), &outname) ) {
00381         // ask for output.
00382         wxFileDialog dlg(0,_("Specify output prefix"),
00383                          wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")),
00384                          wxT(""), wxT(""),
00385                          wxFD_SAVE, wxDefaultPosition);
00386         dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
00387         if (dlg.ShowModal() == wxID_OK) {
00388             while(containsInvalidCharacters(dlg.GetPath()))
00389             {
00390                 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()),
00391                     _("Error"),wxOK | wxICON_EXCLAMATION);
00392                 if(dlg.ShowModal()!=wxID_OK)
00393                     return false;
00394             };
00395             wxFileName prefix(dlg.GetPath());
00396             while (!prefix.IsDirWritable())
00397             {
00398                 wxMessageBox(wxString::Format(_("You have no permissions to write in folder \"%s\".\nPlease select another folder for the final output."), prefix.GetPath().c_str()),
00399 #ifdef __WXMSW__
00400                     wxT("Hugin_stitch_project"),
00401 #else
00402                     wxT(""),
00403 #endif
00404                     wxOK | wxICON_INFORMATION);
00405                 if (dlg.ShowModal() != wxID_OK)
00406                 {
00407                     return false;
00408                 };
00409                 prefix = dlg.GetPath();
00410             };
00411 
00412             wxConfig::Get()->Write(wxT("/actualPath"), dlg.GetDirectory());  // remember for later
00413             outname = dlg.GetPath();
00414         } else { // bail
00415 //            wxLogError( _("No project files specified"));
00416             return false;
00417         }
00418     }
00419 
00420     // check output filename
00421     wxFileName outfn(outname);
00422     wxString ext = outfn.GetExt();
00423     // remove extension if it indicates an image file
00424     if (ext.CmpNoCase(wxT("jpg")) == 0 || ext.CmpNoCase(wxT("jpeg")) == 0|| 
00425         ext.CmpNoCase(wxT("tif")) == 0|| ext.CmpNoCase(wxT("tiff")) == 0 || 
00426         ext.CmpNoCase(wxT("png")) == 0 || ext.CmpNoCase(wxT("exr")) == 0 ||
00427         ext.CmpNoCase(wxT("pnm")) == 0 || ext.CmpNoCase(wxT("hdr"))) 
00428     {
00429         outfn.ClearExt();
00430         outname = outfn.GetFullPath();
00431     }
00432 
00433     RunStitchFrame *frame = new RunStitchFrame(NULL, wxT("Hugin Stitcher"), wxDefaultPosition, wxSize(640,600) );
00434     frame->Show( true );
00435     SetTopWindow( frame );
00436 
00437     wxFileName basename(scriptFile);
00438     frame->SetTitle(wxString::Format(_("%s - Stitching"), basename.GetName().c_str()));
00439     frame->SetOverwrite(parser.Found(wxT("w")));
00440     bool n = frame->StitchProject(scriptFile, outname, userDefinedOutput, parser.Found(wxT("d")));
00441     return n;
00442 }
00443 
00444 
00445 int stitchApp::OnExit()
00446 {
00447     DEBUG_TRACE("");
00448     return 0;
00449 }
00450 
00451 
00452 #ifdef __WXMAC__
00453 // wx calls this method when the app gets "Open file" AppleEvent 
00454 void stitchApp::MacOpenFile(const wxString &fileName)
00455 {
00456     m_macFileNameToOpenOnStart = fileName;
00457 }
00458 #endif
00459 
00460 // make wxwindows use this class as the main application
00461 IMPLEMENT_APP(stitchApp)

Generated on 25 Jun 2016 for Hugintrunk by  doxygen 1.4.7