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

Generated on 24 May 2016 for Hugintrunk by  doxygen 1.4.7