PTBatcherGUI.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00027 #include "PTBatcherGUI.h"
00028 #include <wx/cshelp.h>
00029 #ifdef __WXMSW__
00030 #include <wx/stdpaths.h>
00031 #endif
00032 #include "lensdb/LensDB.h"
00033 
00034 // make wxwindows use this class as the main application
00035 #if defined USE_GDKBACKEND_X11
00036 // wxWidgets does not support wxTaskBarIcon::IsAvailable on Wayland
00037 // so until it is fixed upstream enforce using x11 backendj
00038 // see ticket http://trac.wxwidgets.org/ticket/17779
00039 #warning Using Hugin with hard coded GDK_BACKEND=x11
00040 wxIMPLEMENT_WX_THEME_SUPPORT
00041 wxIMPLEMENT_APP_NO_MAIN(PTBatcherGUI);
00042 #include <stdlib.h>
00043 int main(int argc, char **argv)
00044 {   
00045     wxDISABLE_DEBUG_SUPPORT();
00046     char backend[]="GDK_BACKEND=x11";
00047     putenv(backend);
00048     return wxEntry(argc, argv);
00049 };
00050 #else
00051 wxIMPLEMENT_APP(PTBatcherGUI);
00052 #endif
00053 
00054 BEGIN_EVENT_TABLE(PTBatcherGUI, wxApp)
00055     EVT_LIST_ITEM_ACTIVATED(XRCID("project_listbox"),PTBatcherGUI::OnItemActivated)
00056     EVT_KEY_DOWN(PTBatcherGUI::OnKeyDown)
00057 END_EVENT_TABLE()
00058 
00059 bool PTBatcherGUI::OnInit()
00060 {
00061 #if wxUSE_ON_FATAL_EXCEPTION
00062     wxHandleFatalExceptions();
00063 #endif
00064     // Required to access the preferences of hugin
00065     SetAppName(wxT("hugin"));
00066 
00067     // need to explicitly initialize locale for C++ library/runtime
00068     setlocale(LC_ALL, "");
00069 #if defined __WXMSW__
00070     int localeID = wxConfigBase::Get()->Read(wxT("language"), (long) wxLANGUAGE_DEFAULT);
00071     m_locale.Init(localeID);
00072 #else
00073     m_locale.Init(wxLANGUAGE_DEFAULT);
00074 #endif
00075     // initialize help provider
00076     wxHelpControllerHelpProvider* provider = new wxHelpControllerHelpProvider;
00077     wxHelpProvider::Set(provider);
00078 
00079     // setup the environment for the different operating systems
00080 #if defined __WXMSW__
00081     wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
00082     exePath.RemoveLastDir();
00083     const wxString huginRoot(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00084     m_xrcPrefix = huginRoot + wxT("share\\hugin\\xrc\\");
00085 
00086     // locale setup
00087     m_locale.AddCatalogLookupPathPrefix(huginRoot + wxT("share\\locale"));
00088 #elif defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
00089     {
00090         wxString exec_path = MacGetPathToBundledResourceFile(CFSTR("xrc"));
00091         if(exec_path != wxT(""))
00092         {
00093             m_xrcPrefix = exec_path + wxT("/");
00094         }
00095         else
00096         {
00097             wxMessageBox(_("xrc directory not found in bundle"), _("Fatal Error"));
00098             return false;
00099         }
00100 
00101     }
00102 #else
00103     // add the locale directory specified during configure
00104     m_xrcPrefix = wxT(INSTALL_XRC_DIR);
00105     m_locale.AddCatalogLookupPathPrefix(wxT(INSTALL_LOCALE_DIR));
00106 #endif
00107 
00108     // set the name of locale recource to look for
00109     m_locale.AddCatalog(wxT("hugin"));
00110 
00111     const wxString name = wxString::Format(_T("PTBatcherGUI-%s"), wxGetUserId().c_str());
00112     m_checker = new wxSingleInstanceChecker(name+wxT(".lock"),wxFileName::GetTempDir());
00113     bool IsFirstInstance=(!m_checker->IsAnotherRunning());
00114 
00115     if(IsFirstInstance)
00116     {
00117         if ( ! wxFile::Exists(m_xrcPrefix + wxT("/batch_frame.xrc")) )
00118         {
00119             wxMessageBox(_("xrc directory not found, hugin needs to be properly installed\nTried Path:") + m_xrcPrefix , _("Fatal Error"));
00120             return false;
00121         }
00122         // initialize image handlers
00123         wxInitAllImageHandlers();
00124 
00125         // Initialize all the XRC handlers.
00126         wxXmlResource::Get()->InitAllHandlers();
00127         wxXmlResource::Get()->AddHandler(new ProjectListBoxXmlHandler());
00128         // load XRC files
00129         wxXmlResource::Get()->Load(m_xrcPrefix + wxT("batch_frame.xrc"));
00130         wxXmlResource::Get()->Load(m_xrcPrefix + wxT("batch_toolbar.xrc"));
00131         wxXmlResource::Get()->Load(m_xrcPrefix + wxT("batch_menu.xrc"));
00132         wxXmlResource::Get()->Load(m_xrcPrefix + wxT("lensdb_dialogs.xrc"));
00133         wxXmlResource::Get()->Load(m_xrcPrefix + wxT("dlg_warning.xrc"));
00134     };
00135 
00136     // parse arguments
00137     static const wxCmdLineEntryDesc cmdLineDesc[] =
00138     {
00139         {
00140             wxCMD_LINE_SWITCH, "h", "help", "show this help message",
00141             wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP
00142         },
00143         { wxCMD_LINE_SWITCH, "b", "batch",  "run batch immediately" },
00144         { wxCMD_LINE_SWITCH, "o", "overwrite",  "overwrite previous files without asking" },
00145         { wxCMD_LINE_SWITCH, "s", "shutdown",  "shutdown computer after batch is complete" },
00146         { wxCMD_LINE_SWITCH, "v", "verbose",  "show verbose output when processing projects" },
00147         { wxCMD_LINE_SWITCH, "a", "assistant", "run the assistant on the given projects" },
00148         {
00149             wxCMD_LINE_PARAM,  NULL, NULL, "stitch_project.pto [output prefix]|assistant_project.pto",
00150             wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL + wxCMD_LINE_PARAM_MULTIPLE
00151         },
00152         { wxCMD_LINE_NONE }
00153     };
00154     wxCmdLineParser parser(cmdLineDesc, argc, argv);
00155 
00156     switch ( parser.Parse() )
00157     {
00158         case -1: // -h or --help was given, and help displayed so exit
00159             return false;
00160             break;
00161         case 0:  // all is well
00162             break;
00163         default:
00164             wxLogError(_("Syntax error in parameters detected, aborting."));
00165             return false;
00166             break;
00167     }
00168 
00169     wxClient client;
00170     wxConnectionBase* conn;
00171     wxString servername;
00172 #ifdef _WIN32
00173     servername=name;
00174 #else
00175     servername=wxFileName::GetTempDir()+wxFileName::GetPathSeparator()+name+wxT(".ipc");
00176 #endif
00177     if(IsFirstInstance)
00178     {
00179         m_frame = new BatchFrame(&m_locale,m_xrcPrefix);
00180         m_frame->RestoreSize();
00181         // init help system
00182         provider->SetHelpController(&m_frame->GetHelpController());
00183 #ifdef __WXMSW__
00184         m_frame->GetHelpController().Initialize(m_xrcPrefix + wxT("data/hugin_help_en_EN.chm"));
00185 #else
00186 #if wxUSE_WXHTML_HELP
00187         // using wxHtmlHelpController
00188 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
00189         // On Mac, xrc/data/help_LOCALE should be in the bundle as LOCALE.lproj/help
00190         // which we can rely on the operating sytem to pick the right locale's.
00191         wxString strFile = MacGetPathToBundledResourceFile(CFSTR("help"));
00192         if (!strFile.IsEmpty())
00193         {
00194             m_frame->GetHelpController().AddBook(wxFileName(strFile + wxT("/hugin_help_en_EN.hhp")));
00195         }
00196         else
00197         {
00198             wxLogError(wxString::Format(wxT("Could not find help directory in the bundle"), strFile.c_str()));
00199             return false;
00200         }
00201 #else
00202         m_frame->GetHelpController().AddBook(wxFileName(m_xrcPrefix + wxT("data/help_en_EN/hugin_help_en_EN.hhp")));
00203 #endif
00204 #else
00205         // using wxExtHelpController
00206         m_frame->GetHelpController().Initialize(Initialize(m_xrcPrefix + wxT("data/help_en_EN")));
00207 #endif
00208 #endif
00209 
00210         SetTopWindow(m_frame);
00211         if(!(m_frame->IsStartedMinimized()))
00212         {
00213             m_frame->Show(true);
00214         }
00215         else
00216         {
00217             m_frame->SetStatusInformation(_("PTBatcherGUI started"));
00218         };
00219         m_server = new BatchIPCServer();
00220         if (!m_server->Create(servername))
00221         {
00222             delete m_server;
00223             m_server = NULL;
00224         };
00225     }
00226     else
00227     {
00228         conn=client.MakeConnection(wxEmptyString, servername, IPC_START);
00229         if(!conn)
00230         {
00231             return false;
00232         }
00233     };
00234 
00235     size_t count = 0;
00236     if (parser.Found(wxT("a")))
00237     {
00238         //added assistant files
00239         while (parser.GetParamCount() > count)
00240         {
00241             wxString param = parser.GetParam(count);
00242             count++;
00243             wxFileName name(param);
00244             name.MakeAbsolute();
00245             if (name.FileExists())
00246             {
00247                 //only add existing pto files
00248                 if (name.GetExt().CmpNoCase(wxT("pto")) == 0)
00249                 {
00250                     if (IsFirstInstance)
00251                     {
00252                         m_frame->AddToList(name.GetFullPath(), Project::DETECTING);
00253                     }
00254                     else
00255                     {
00256                         conn->Request(wxT("D ") + name.GetFullPath());
00257                     };
00258                 };
00259             };
00260         };
00261     }
00262     else
00263     {
00264         bool projectSpecified = false;
00265         //we collect all parameters - all project files <and their output prefixes>
00266         while (parser.GetParamCount() > count)
00267         {
00268             wxString param = parser.GetParam(count);
00269             count++;
00270             if (!projectSpecified)      //next parameter must be new script file
00271             {
00272                 wxFileName name(param);
00273                 name.MakeAbsolute();
00274                 if (IsFirstInstance)
00275                 {
00276                     m_frame->AddToList(name.GetFullPath());
00277                 }
00278                 else
00279                 {
00280                     conn->Request(wxT("A ") + name.GetFullPath());
00281                 }
00282                 projectSpecified = true;
00283             }
00284             else        //parameter could be previous project's output prefix
00285             {
00286                 wxFileName fn(param);
00287                 fn.MakeAbsolute();
00288                 if (!fn.HasExt())       //if there is no extension we have a prefix
00289                 {
00290                     if (IsFirstInstance)
00291                     {
00292                         m_frame->ChangePrefix(-1, fn.GetFullPath());
00293                     }
00294                     else
00295                     {
00296                         conn->Request(wxT("P ") + fn.GetFullPath());
00297                     }
00298                     projectSpecified = false;
00299                 }
00300                 else
00301                 {
00302                     wxString ext = fn.GetExt();
00303                     //we may still have a prefix, but with added image extension
00304                     if (ext.CmpNoCase(wxT("jpg")) == 0 || ext.CmpNoCase(wxT("jpeg")) == 0 ||
00305                         ext.CmpNoCase(wxT("tif")) == 0 || ext.CmpNoCase(wxT("tiff")) == 0 ||
00306                         ext.CmpNoCase(wxT("png")) == 0 || ext.CmpNoCase(wxT("exr")) == 0 ||
00307                         ext.CmpNoCase(wxT("pnm")) == 0 || ext.CmpNoCase(wxT("hdr")) == 0)
00308                     {
00309                         //extension will be removed before stitch, so there is no need to do it now
00310                         if (IsFirstInstance)
00311                         {
00312                             m_frame->ChangePrefix(-1, fn.GetFullPath());
00313                         }
00314                         else
00315                         {
00316                             conn->Request(wxT("P ") + fn.GetFullPath());
00317                         }
00318                         projectSpecified = false;
00319                     }
00320                     else //if parameter has a different extension we presume it is a new script file
00321                     {
00322                         //we add the new project
00323                         if (IsFirstInstance)
00324                         {
00325                             m_frame->AddToList(fn.GetFullPath());
00326                         }
00327                         else
00328                         {
00329                             conn->Request(wxT("A ") + fn.GetFullPath());
00330                         }
00331                         projectSpecified = true;
00332                     }
00333                 } //else of if(!fn.HasExt())
00334             }
00335         }
00336     };
00337 
00338     if(IsFirstInstance)
00339     {
00340         wxConfigBase* config=wxConfigBase::Get();
00341         if (parser.Found(wxT("s")))
00342         {
00343             config->DeleteEntry(wxT("/BatchFrame/ShutdownCheck"));
00344 #if !defined __WXMAC__ && !defined __WXOSX_COCOA__
00345             // wxMac has not wxShutdown
00346             config->Write(wxT("/BatchFrame/AtEnd"), static_cast<long>(Batch::SHUTDOWN));
00347 #endif
00348         }
00349         if (parser.Found(wxT("o")))
00350         {
00351             config->Write(wxT("/BatchFrame/OverwriteCheck"), 1l);
00352         }
00353         if (parser.Found(wxT("v")))
00354         {
00355             config->Write(wxT("/BatchFrame/VerboseCheck"), 1l);
00356         }
00357         config->Flush();
00358     }
00359     else
00360     {
00361         if (parser.Found(wxT("s")))
00362         {
00363 #if !defined __WXMAC__ && !defined __WXOSX_COCOA__
00364             // wxMac has not wxShutdown
00365             conn->Request(wxT("SetShutdownCheck"));
00366 #endif
00367         }
00368         if (parser.Found(wxT("o")))
00369         {
00370             conn->Request(wxT("SetOverwriteCheck"));
00371         }
00372         if (parser.Found(wxT("v")))
00373         {
00374             conn->Request(wxT("SetVerboseCheck"));
00375         }
00376         conn->Request(wxT("BringWindowToTop"));
00377         if(parser.Found(wxT("b")))
00378         {
00379             conn->Request(wxT("RunBatch"));
00380         }
00381         conn->Disconnect();
00382         delete conn;
00383         delete m_checker;
00384         return false;
00385     };
00386     m_frame->SetCheckboxes();
00387     m_frame->PropagateDefaults();
00388     //deactivate verbose output if started minimized
00389     if(m_frame->IsStartedMinimized())
00390     {
00391         m_frame->SetInternalVerbose(false);
00392     };
00393     if (parser.Found(wxT("b")) )
00394     {
00395         m_frame->RunBatch();
00396     }
00397 #ifdef __WXMAC__
00398     // if there are command line parameters they are handled all by the code above
00399     // but wxMac calls also MacOpenFiles after OnInit with the command line
00400     // parameters again, so the files get added twice. To prevent this we
00401     // reset the internal file list for MacOpenFiles here
00402     // but we need to process the files when PTBatcherGUI is called from finder
00403     // with an open files AppleEvent, in this case the argv is empty (except argc[0])
00404     // and we don't want to skip the MacOpenFile function
00405     if (argc > 1)
00406     {
00407         wxArrayString emptyFiles;
00408         OSXStoreOpenFiles(emptyFiles);
00409     };
00410 #endif
00411     return true;
00412 }
00413 
00414 int PTBatcherGUI::OnExit()
00415 {
00416     HuginBase::LensDB::LensDB::Clean();
00417     delete m_checker;
00418     delete m_server;
00419     delete wxHelpProvider::Set(NULL);
00420     return 0;
00421 }
00422 
00423 #if wxUSE_ON_FATAL_EXCEPTION
00424 void PTBatcherGUI::OnFatalException()
00425 {
00426     GenerateReport(wxDebugReport::Context_Exception);
00427 };
00428 #endif
00429 
00430 void PTBatcherGUI::OnItemActivated(wxListEvent& event)
00431 {
00432     wxCommandEvent dummy;
00433     m_frame->OnButtonOpenWithHugin(dummy);
00434 }
00435 
00436 void PTBatcherGUI::OnKeyDown(wxKeyEvent& event)
00437 {
00438     wxCommandEvent dummy;
00439     switch(event.GetKeyCode())
00440     {
00441         case WXK_DELETE:
00442             m_frame->OnButtonRemoveFromList(dummy);
00443             break;
00444         case WXK_INSERT:
00445             m_frame->OnButtonAddToStitchingQueue(dummy);
00446             break;
00447         case WXK_ESCAPE:
00448             m_frame->OnButtonCancel(dummy);
00449             break;
00450         default:
00451             event.Skip();
00452             break;
00453     }
00454 
00455 }
00456 
00457 #ifdef __WXMAC__
00458 // wx calls this method when the app gets "Open files" AppleEvent
00459 void PTBatcherGUI::MacOpenFiles(const wxArrayString &fileNames) 
00460 {
00461     if(m_frame)
00462     {
00463         for (int i = 0; i < fileNames.GetCount(); ++i)
00464         {
00465             wxFileName fn(fileNames[i]);
00466             m_frame->AddToList(fn.GetFullPath());
00467         };
00468     };
00469 }
00470 #endif
00471 
00472 const void* BatchIPCConnection::OnRequest(const wxString& topic, const wxString& item, size_t* size, wxIPCFormat format)
00473 {
00474     *size=wxNO_LEN;
00475     BatchFrame* MyBatchFrame=wxGetApp().GetFrame();
00476     if(item.Left(1)==wxT("A"))
00477     {
00478         MyBatchFrame->AddToList(item.Mid(2));
00479         return wxEmptyString;
00480     };
00481     if(item.Left(1)==wxT("D"))
00482     {
00483         MyBatchFrame->AddToList(item.Mid(2),Project::DETECTING);
00484         return wxEmptyString;
00485     };
00486     if(item.Left(1)==wxT("P"))
00487     {
00488         MyBatchFrame->ChangePrefix(-1,item.Mid(2));
00489         return wxEmptyString;
00490     };
00491     wxCommandEvent event;
00492     event.SetInt(1);
00493 #if !defined __WXMAC__ && !defined __WXOSX_COCOA__
00494     // wxMac has not wxShutdown
00495     if(item==wxT("SetShutdownCheck"))
00496         if (MyBatchFrame->GetEndTask()!=Batch::SHUTDOWN)
00497         {
00498             wxCommandEvent choiceEvent;
00499             choiceEvent.SetInt(Batch::SHUTDOWN);
00500             MyBatchFrame->OnChoiceEnd(choiceEvent);
00501             MyBatchFrame->SetCheckboxes();
00502         };
00503 #endif
00504     if(item==wxT("SetOverwriteCheck"))
00505         if(!MyBatchFrame->GetCheckOverwrite())
00506         {
00507             MyBatchFrame->OnCheckOverwrite(event);
00508             MyBatchFrame->SetCheckboxes();
00509         };
00510     if(item==wxT("SetVerboseCheck"))
00511         if(!MyBatchFrame->GetCheckVerbose())
00512         {
00513             MyBatchFrame->OnCheckVerbose(event);
00514             MyBatchFrame->SetCheckboxes();
00515         };
00516     if(item==wxT("BringWindowToTop"))
00517     {
00518         MyBatchFrame->RequestUserAttention();
00519     }
00520     if(item==wxT("RunBatch"))
00521     {
00522         wxCommandEvent myEvent(wxEVT_COMMAND_TOOL_CLICKED ,XRCID("tool_start"));
00523         MyBatchFrame->GetEventHandler()->AddPendingEvent(myEvent);
00524     };
00525     return wxEmptyString;
00526 };
00527 
00528 wxConnectionBase* BatchIPCServer::OnAcceptConnection (const wxString& topic)
00529 {
00530     if(topic==IPC_START)
00531     {
00532         return new BatchIPCConnection;
00533     }
00534     return NULL;
00535 };

Generated on 18 Oct 2017 for Hugintrunk by  doxygen 1.4.7