hugin_stitch_project.cpp

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

Generated on Wed Jul 16 01:25:37 2014 for Hugintrunk by  doxygen 1.3.9.1