00001
00002
00027 #include <config.h>
00028
00029 #include "panoinc_WX.h"
00030
00031 #ifdef __WXMAC__
00032 #include <wx/sysopt.h>
00033 #endif
00034
00035 #include "panoinc.h"
00036
00037
00038 #include "hugin/config_defaults.h"
00039 #include "hugin/huginApp.h"
00040 #include "hugin/ImagesPanel.h"
00041 #include "hugin/MaskEditorPanel.h"
00042 #include "hugin/CPEditorPanel.h"
00043 #include "hugin/OptimizePhotometricPanel.h"
00044 #include "hugin/PanoPanel.h"
00045 #include "hugin/ImagesList.h"
00046 #include "hugin/PreviewPanel.h"
00047 #include "hugin/GLPreviewFrame.h"
00048 #include "base_wx/PTWXDlg.h"
00049 #include "hugin/CommandHistory.h"
00050 #include "hugin/wxPanoCommand.h"
00051 #include "hugin/HtmlWindow.h"
00052 #include "hugin/treelistctrl.h"
00053 #include "hugin/ImagesTree.h"
00054
00055 #include "base_wx/platform.h"
00056 #include "base_wx/huginConfig.h"
00057 #ifdef __WXMSW__
00058 #include "wx/dir.h"
00059 #include "wx/cshelp.h"
00060 #endif
00061
00062 #include <tiffio.h>
00063
00064 #include "AboutDialog.h"
00065
00066 #include <hugin_version.h>
00067
00068 #include "hugin_utils/alphanum.h"
00069 #include "lensdb/LensDB.h"
00070
00071 bool checkVersion(wxString v1, wxString v2)
00072 {
00073 return doj::alphanum_comp(std::string(v1.mb_str(wxConvLocal)),std::string(v2.mb_str(wxConvLocal))) < 0;
00074 };
00075
00076 using namespace hugin_utils;
00077
00078
00079 bool str2double(wxString s, double & d)
00080 {
00081 if (!stringToDouble(std::string(s.mb_str(wxConvLocal)), d)) {
00082 wxLogError(_("Value must be numeric."));
00083 return false;
00084 }
00085 return true;
00086 }
00087
00088 wxString Components2Str(const CPComponents & comp)
00089 {
00090 wxString ret;
00091 for (unsigned i=0; i < comp.size(); i++) {
00092 ret = ret + wxT("[");
00093 CPComponents::value_type::const_iterator it;
00094 size_t c=0;
00095 for (it = comp[i].begin();
00096 it != comp[i].end();
00097 ++it)
00098 {
00099 ret = ret + wxString::Format(wxT("%d"), (*it));
00100 if (c+1 != comp[i].size()) {
00101 ret = ret + wxT(", ");
00102 }
00103 c++;
00104 }
00105 if (i+1 != comp.size())
00106 ret = ret + wxT("], ");
00107 else
00108 ret = ret + wxT("]");
00109 }
00110 return ret;
00111 }
00112
00113 #if _WINDOWS && defined Hugin_shared
00114 DEFINE_LOCAL_EVENT_TYPE( EVT_IMAGE_READY )
00115 #else
00116 DEFINE_EVENT_TYPE( EVT_IMAGE_READY )
00117 #endif
00118
00119 BEGIN_EVENT_TABLE(huginApp, wxApp)
00120 EVT_IMAGE_READY2(-1, huginApp::relayImageLoaded)
00121 END_EVENT_TABLE()
00122
00123
00124 IMPLEMENT_APP(huginApp)
00125
00126 huginApp::huginApp()
00127 {
00128 DEBUG_TRACE("ctor");
00129 m_this=this;
00130 }
00131
00132 huginApp::~huginApp()
00133 {
00134 DEBUG_TRACE("dtor");
00135
00136
00137
00138
00139
00140
00141
00142
00143 HuginBase::LensDB::LensDB::Clean();
00144 DEBUG_TRACE("dtor end");
00145 }
00146
00147 bool huginApp::OnInit()
00148 {
00149 DEBUG_TRACE("=========================== huginApp::OnInit() begin ===================");
00150 SetAppName(wxT("hugin"));
00151
00152
00153 ImageCache::getInstance().asyncLoadCompleteSignal = &huginApp::imageLoadedAsync;
00154
00155 #ifdef __WXMAC__
00156
00157 wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), 1);
00158 #endif
00159
00160
00161 registerPTWXDlgFcn();
00162
00163
00164 wxFileSystem::AddHandler(new wxZipFSHandler);
00165
00166
00167 #if defined __WXMSW__
00168
00169 wxHelpControllerHelpProvider* provider = new wxHelpControllerHelpProvider;
00170 wxHelpProvider::Set(provider);
00171
00172 wxString huginExeDir = getExePath(argv[0]);
00173
00174 wxString huginRoot;
00175 wxFileName::SplitPath( huginExeDir, &huginRoot, NULL, NULL );
00176
00177 m_xrcPrefix = huginRoot + wxT("/share/hugin/xrc/");
00178 m_DataDir = huginRoot + wxT("/share/hugin/data/");
00179 m_utilsBinDir = huginRoot + wxT("/bin/");
00180
00181
00182 locale.AddCatalogLookupPathPrefix(huginRoot + wxT("/share/locale"));
00183
00184 wxString lensfunDBPath=huginRoot + wxT("/share/lensfun");
00185 HuginBase::LensDB::LensDB::GetSingleton().SetMainDBPath(std::string(lensfunDBPath.mb_str(HUGIN_CONV_FILENAME)));
00186
00187 #elif defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
00188
00189 {
00190 wxString thePath = MacGetPathToBundledResourceFile(CFSTR("xrc"));
00191 if (thePath == wxT("")) {
00192 wxMessageBox(_("xrc directory not found in bundle"), _("Fatal Error"));
00193 return false;
00194 }
00195 m_xrcPrefix = thePath + wxT("/");
00196 m_DataDir = thePath + wxT("/");
00197 }
00198
00199 {
00200 wxString thePath = MacGetPathToBundledResourceFile(CFSTR("locale"));
00201 if(thePath != wxT(""))
00202 locale.AddCatalogLookupPathPrefix(thePath);
00203 else {
00204 wxMessageBox(_("Translations not found in bundle"), _("Fatal Error"));
00205 return false;
00206 }
00207 }
00208
00209 {
00210 wxString thePath = MacGetPathToBundledResourceFile(CFSTR("lensfun"));
00211 if (thePath == wxT("")) {
00212 wxMessageBox(_("lensfun directory not found in bundle"),
00213 _("Fatal Error"));
00214 return false;
00215 }
00216 HuginBase::LensDB::LensDB::GetSingleton().SetMainDBPath(std::string(thePath.mb_str(HUGIN_CONV_FILENAME)));
00217 }
00218
00219 #else
00220
00221 m_xrcPrefix = wxT(INSTALL_XRC_DIR);
00222 m_DataDir = wxT(INSTALL_DATA_DIR);
00223 locale.AddCatalogLookupPathPrefix(wxT(INSTALL_LOCALE_DIR));
00224 #endif
00225
00226 if ( ! wxFile::Exists(m_xrcPrefix + wxT("/main_frame.xrc")) ) {
00227 wxMessageBox(_("xrc directory not found, hugin needs to be properly installed\nTried Path:" + m_xrcPrefix ), _("Fatal Error"));
00228 return false;
00229 }
00230
00231
00232 wxConfigBase * config = wxConfigBase::Get();
00233
00234 config->SetRecordDefaults(false);
00235
00236 config->Flush();
00237
00238
00239 int localeID = config->Read(wxT("language"), (long) HUGIN_LANGUAGE);
00240 DEBUG_TRACE("localeID: " << localeID);
00241 {
00242 bool bLInit;
00243 bLInit = locale.Init(localeID);
00244 if (bLInit) {
00245 DEBUG_TRACE("locale init OK");
00246 DEBUG_TRACE("System Locale: " << locale.GetSysName().mb_str(wxConvLocal))
00247 DEBUG_TRACE("Canonical Locale: " << locale.GetCanonicalName().mb_str(wxConvLocal))
00248 } else {
00249 DEBUG_TRACE("locale init failed");
00250 }
00251 }
00252
00253
00254 locale.AddCatalog(wxT("hugin"));
00255
00256
00257 wxInitAllImageHandlers();
00258
00259
00260 wxXmlResource::Get()->InitAllHandlers();
00261
00262
00263 #ifdef _INCLUDE_UI_RESOURCES
00264 InitXmlResource();
00265 #else
00266
00267
00268 wxXmlResource::Get()->AddHandler(new ImagesPanelXmlHandler());
00269 wxXmlResource::Get()->AddHandler(new CPEditorPanelXmlHandler());
00270 wxXmlResource::Get()->AddHandler(new CPImageCtrlXmlHandler());
00271 wxXmlResource::Get()->AddHandler(new CPImagesComboBoxXmlHandler());
00272 wxXmlResource::Get()->AddHandler(new MaskEditorPanelXmlHandler());
00273 wxXmlResource::Get()->AddHandler(new ImagesListMaskXmlHandler());
00274 wxXmlResource::Get()->AddHandler(new MaskImageCtrlXmlHandler());
00275 wxXmlResource::Get()->AddHandler(new OptimizePanelXmlHandler());
00276 wxXmlResource::Get()->AddHandler(new OptimizePhotometricPanelXmlHandler());
00277 wxXmlResource::Get()->AddHandler(new PanoPanelXmlHandler());
00278 wxXmlResource::Get()->AddHandler(new PreviewPanelXmlHandler());
00279 wxXmlResource::Get()->AddHandler(new HtmlWindowXmlHandler());
00280 wxXmlResource::Get()->AddHandler(new wxTreeListCtrlXmlHandler());
00281 wxXmlResource::Get()->AddHandler(new ImagesTreeCtrlXmlHandler());
00282
00283
00284 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("cp_list_frame.xrc"));
00285 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("preview_frame.xrc"));
00286 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("edit_script_dialog.xrc"));
00287 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("main_menu.xrc"));
00288 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("main_tool.xrc"));
00289 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("about.xrc"));
00290 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("pref_dialog.xrc"));
00291 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("cpdetector_dialog.xrc"));
00292 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("reset_dialog.xrc"));
00293 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("optimize_photo_panel.xrc"));
00294 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("cp_editor_panel.xrc"));
00295 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("images_panel.xrc"));
00296 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("main_frame.xrc"));
00297 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("optimize_panel.xrc"));
00298 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("pano_panel.xrc"));
00299 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("mask_editor_panel.xrc"));
00300 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("lensdb_dialogs.xrc"));
00301 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("image_variable_dlg.xrc"));
00302 wxXmlResource::Get()->Load(m_xrcPrefix + wxT("dlg_warning.xrc"));
00303 #endif
00304
00305 #ifdef __WXMAC__
00306
00307
00308 m_macInitDone=false;
00309 m_macOpenFileOnStart=false;
00310 #endif
00311
00312 frame = new MainFrame(NULL, pano);
00313 SetTopWindow(frame);
00314
00315
00316 RestoreFramePosition(frame, wxT("MainFrame"));
00317 #ifdef __WXMSW__
00318 provider->SetHelpController(&frame->GetHelpController());
00319 frame->GetHelpController().Initialize(m_xrcPrefix+wxT("data/hugin_help_en_EN.chm"));
00320 frame->SendSizeEvent();
00321 #endif
00322
00323
00324 SetExitOnFrameDelete(true);
00325
00326 if(frame->GetGuiLevel()==GUI_SIMPLE)
00327 {
00328 SetTopWindow(frame->getGLPreview());
00329 }
00330 else
00331 {
00332 frame->Show(TRUE);
00333 };
00334
00335 wxString cwd = wxFileName::GetCwd();
00336
00337 m_workDir = config->Read(wxT("tempDir"),wxT(""));
00338
00339
00340 if (m_workDir == wxT("")) {
00341 #if (defined __WXMSW__)
00342 DEBUG_DEBUG("figuring out windows temp dir");
00343
00344 wxChar buffer[MAX_PATH];
00345 GetTempPath(MAX_PATH, buffer);
00346 m_workDir = buffer;
00347 #elif (defined __WXMAC__) && (defined MAC_SELF_CONTAINED_BUNDLE)
00348 DEBUG_DEBUG("temp dir on Mac");
00349 m_workDir = MacGetPathToUserDomainTempDir();
00350 if(m_workDir == wxT(""))
00351 m_workDir = wxT("/tmp");
00352 #else //UNIX
00353 DEBUG_DEBUG("temp dir on unix");
00354
00355 if (!wxGetEnv(wxT("TMPDIR"), &m_workDir)) {
00356
00357 m_workDir = wxT("/tmp");
00358 }
00359 #endif
00360
00361 }
00362
00363 if (!wxFileName::DirExists(m_workDir)) {
00364 DEBUG_DEBUG("creating temp dir: " << m_workDir.mb_str(wxConvLocal));
00365 if (!wxMkdir(m_workDir)) {
00366 DEBUG_ERROR("Tempdir could not be created: " << m_workDir.mb_str(wxConvLocal));
00367 }
00368 }
00369 if (!wxSetWorkingDirectory(m_workDir)) {
00370 DEBUG_ERROR("could not change to temp. dir: " << m_workDir.mb_str(wxConvLocal));
00371 }
00372 DEBUG_DEBUG("using temp dir: " << m_workDir.mb_str(wxConvLocal));
00373
00374
00375 GlobalCmdHist::getInstance().addCommand(new wxNewProjectCmd(pano));
00376 GlobalCmdHist::getInstance().clear();
00377
00378
00379 TIFFSetWarningHandler(0);
00380
00381 if (argc > 1)
00382 {
00383 #ifdef __WXMSW__
00384
00385
00386
00387 if(frame->GetGuiLevel()==GUI_SIMPLE)
00388 {
00389 frame->getGLPreview()->Update();
00390 };
00391 #endif
00392 wxFileName file(argv[1]);
00393
00394 if (file.GetExt().CmpNoCase(wxT("pto")) == 0 ||
00395 file.GetExt().CmpNoCase(wxT("pts")) == 0 ||
00396 file.GetExt().CmpNoCase(wxT("ptp")) == 0 )
00397 {
00398 if(file.IsRelative())
00399 file.MakeAbsolute(cwd);
00400
00401
00402
00403 frame->LoadProjectFile(file.GetFullPath());
00404 } else {
00405 std::vector<std::string> filesv;
00406 for (int i=1; i< argc; i++)
00407 {
00408 bool actualPathSet = false;
00409 #if defined __WXMSW__
00410
00411 wxFileName fileList(argv[i]);
00412 if(fileList.IsRelative())
00413 fileList.MakeAbsolute(cwd);
00414 wxDir dir;
00415 wxString foundFile;
00416 wxFileName file;
00417 if(fileList.DirExists())
00418 if(dir.Open(fileList.GetPath()))
00419 if(dir.GetFirst(&foundFile,fileList.GetFullName(),wxDIR_FILES | wxDIR_HIDDEN))
00420 do
00421 {
00422 file=foundFile;
00423 file.MakeAbsolute(dir.GetName());
00424 #else
00425 wxFileName file(argv[i]);
00426 #endif
00427 if (file.GetExt().CmpNoCase(wxT("jpg")) == 0 ||
00428 file.GetExt().CmpNoCase(wxT("jpeg")) == 0 ||
00429 file.GetExt().CmpNoCase(wxT("tif")) == 0 ||
00430 file.GetExt().CmpNoCase(wxT("tiff")) == 0 ||
00431 file.GetExt().CmpNoCase(wxT("png")) == 0 ||
00432 file.GetExt().CmpNoCase(wxT("bmp")) == 0 ||
00433 file.GetExt().CmpNoCase(wxT("gif")) == 0 ||
00434 file.GetExt().CmpNoCase(wxT("pnm")) == 0 ||
00435 file.GetExt().CmpNoCase(wxT("sun")) == 0 ||
00436 file.GetExt().CmpNoCase(wxT("hdr")) == 0 ||
00437 file.GetExt().CmpNoCase(wxT("viff")) == 0 )
00438 {
00439 if(file.IsRelative())
00440 file.MakeAbsolute(cwd);
00441 if(!containsInvalidCharacters(file.GetFullPath()))
00442 {
00443 filesv.push_back((const char *)(file.GetFullPath().mb_str(HUGIN_CONV_FILENAME)));
00444 };
00445
00446
00447 if (! actualPathSet)
00448 {
00449 config->Write(wxT("/actualPath"), file.GetPath());
00450 actualPathSet = true;
00451 }
00452 }
00453 #if defined __WXMSW__
00454 } while (dir.GetNext(&foundFile));
00455 #endif
00456 }
00457 if(filesv.size()>0)
00458 {
00459 std::vector<PT::PanoCommand*> cmds;
00460 cmds.push_back(new PT::wxAddImagesCmd(pano,filesv));
00461 cmds.push_back(new PT::DistributeImagesCmd(pano));
00462 cmds.push_back(new PT::CenterPanoCmd(pano));
00463 GlobalCmdHist::getInstance().addCommand(new PT::CombinedPanoCommand(pano, cmds));
00464 }
00465 }
00466 }
00467 #ifdef __WXMAC__
00468 m_macInitDone = true;
00469 if(m_macOpenFileOnStart) {frame->LoadProjectFile(m_macFileNameToOpenOnStart);}
00470 m_macOpenFileOnStart = false;
00471 #endif
00472
00473
00474 wxString secondParam = argc > 2 ? wxString(argv[2]) : wxString();
00475 if(secondParam.Cmp(_T("-notips"))!=0)
00476 {
00477
00478 int nValue = config->Read(wxT("/MainFrame/ShowStartTip"), 1l);
00479
00480
00481 if(nValue > 0)
00482 {
00483 wxCommandEvent dummy;
00484 frame->OnTipOfDay(dummy);
00485 }
00486 }
00487
00488 DEBUG_TRACE("=========================== huginApp::OnInit() end ===================");
00489 return true;
00490 }
00491
00492 int huginApp::OnExit()
00493 {
00494 DEBUG_TRACE("");
00495 return wxApp::OnExit();
00496 }
00497
00498 huginApp * huginApp::Get()
00499 {
00500 if (m_this) {
00501 return m_this;
00502 } else {
00503 DEBUG_FATAL("huginApp not yet created");
00504 DEBUG_ASSERT(m_this);
00505 return 0;
00506 }
00507 }
00508
00509 MainFrame* huginApp::getMainFrame()
00510 {
00511 if (m_this) {
00512 return m_this->frame;
00513 } else {
00514 return 0;
00515 }
00516 }
00517
00518 void huginApp::relayImageLoaded(ImageReadyEvent & event)
00519 {
00520 ImageCache::getInstance().postEvent(event.request, event.entry);
00521 }
00522
00523 void huginApp::imageLoadedAsync(ImageCache::RequestPtr request, ImageCache::EntryPtr entry)
00524 {
00525 ImageReadyEvent event(request, entry);
00526
00527
00528
00529
00530 Get()->AddPendingEvent(event);
00531 }
00532
00533 #ifdef __WXMAC__
00534 void huginApp::MacOpenFile(const wxString &fileName)
00535 {
00536 if(!m_macInitDone)
00537 {
00538 m_macOpenFileOnStart=true;
00539 m_macFileNameToOpenOnStart = fileName;
00540 return;
00541 }
00542
00543 if(frame) frame->MacOnOpenFile(fileName);
00544 }
00545 #endif
00546
00547 huginApp * huginApp::m_this = 0;
00548
00549
00550
00551
00552 void RestoreFramePosition(wxTopLevelWindow * frame, const wxString & basename)
00553 {
00554 DEBUG_TRACE(basename.mb_str(wxConvLocal));
00555
00556 wxConfigBase * config = wxConfigBase::Get();
00557
00558
00559 int dx,dy;
00560 wxDisplaySize(&dx,&dy);
00561
00562 #if ( __WXGTK__ ) && wxCHECK_VERSION(2,6,0)
00563
00564
00565
00566 int w = config->Read(wxT("/") + basename + wxT("/width"),-1l);
00567 int h = config->Read(wxT("/") + basename + wxT("/height"),-1l);
00568 if (w > 0 && w <= dx) {
00569 frame->SetClientSize(w,h);
00570 } else {
00571 frame->Fit();
00572 }
00573
00574 int x = config->Read(wxT("/") + basename + wxT("/positionX"),-1l);
00575 int y = config->Read(wxT("/") + basename + wxT("/positionY"),-1l);
00576 if ( y >= 0 && x >= 0 && x < dx && y < dy) {
00577 frame->Move(x, y);
00578 } else {
00579 frame->Move(0, 44);
00580 }
00581 #else
00582 bool maximized = config->Read(wxT("/") + basename + wxT("/maximized"), 0l) != 0;
00583 if (maximized) {
00584 frame->Maximize();
00585 } else {
00586
00587 int w = config->Read(wxT("/") + basename + wxT("/width"),-1l);
00588 int h = config->Read(wxT("/") + basename + wxT("/height"),-1l);
00589 if (w > 0 && w <= dx) {
00590 frame->SetClientSize(w,h);
00591 } else {
00592 frame->Fit();
00593 }
00594
00595 int x = config->Read(wxT("/") + basename + wxT("/positionX"),-1l);
00596 int y = config->Read(wxT("/") + basename + wxT("/positionY"),-1l);
00597 if ( y >= 0 && x >= 0 && x < dx && y < dy) {
00598 frame->Move(x, y);
00599 } else {
00600 frame->Move(0, 44);
00601 }
00602 }
00603 #endif
00604 }
00605
00606
00607 void StoreFramePosition(wxTopLevelWindow * frame, const wxString & basename)
00608 {
00609 DEBUG_TRACE(basename);
00610
00611 wxConfigBase * config = wxConfigBase::Get();
00612
00613 #if ( __WXGTK__ ) && wxCHECK_VERSION(2,6,0)
00614
00615
00616
00617 wxSize sz = frame->GetClientSize();
00618 config->Write(wxT("/") + basename + wxT("/width"), sz.GetWidth());
00619 config->Write(wxT("/") + basename + wxT("/height"), sz.GetHeight());
00620 wxPoint ps = frame->GetPosition();
00621 config->Write(wxT("/") + basename + wxT("/positionX"), ps.x);
00622 config->Write(wxT("/") + basename + wxT("/positionY"), ps.y);
00623 config->Write(wxT("/") + basename + wxT("/maximized"), 0);
00624 #else
00625 if ( (! frame->IsMaximized()) && (! frame->IsIconized()) ) {
00626 wxSize sz = frame->GetClientSize();
00627 config->Write(wxT("/") + basename + wxT("/width"), sz.GetWidth());
00628 config->Write(wxT("/") + basename + wxT("/height"), sz.GetHeight());
00629 wxPoint ps = frame->GetPosition();
00630 config->Write(wxT("/") + basename + wxT("/positionX"), ps.x);
00631 config->Write(wxT("/") + basename + wxT("/positionY"), ps.y);
00632 config->Write(wxT("/") + basename + wxT("/maximized"), 0);
00633 } else if (frame->IsMaximized()){
00634 config->Write(wxT("/") + basename + wxT("/maximized"), 1l);
00635 }
00636 #endif
00637 }