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

Generated on 4 Aug 2015 for Hugintrunk by  doxygen 1.4.7