Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
hugin_stitch_project.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
27 #include <hugin_config.h>
28 #include "panoinc_WX.h"
29 #include "panoinc.h"
30 
31 #include <wx/wfstream.h>
32 #if defined __WXMSW__ || defined UNIX_SELF_CONTAINED_BUNDLE
33 #include <wx/stdpaths.h>
34 #endif
35 
36 #include <fstream>
37 #include <sstream>
38 #include "base_wx/RunStitchPanel.h"
39 #include "base_wx/huginConfig.h"
41 #include "base_wx/platform.h"
42 #include "base_wx/wxPlatform.h"
43 
44 #include <tiffio.h>
45 
46 // somewhere SetDesc gets defined.. this breaks wx/cmdline.h on OSX
47 #ifdef SetDesc
48 #undef SetDesc
49 #endif
50 
51 #include <wx/cmdline.h>
52 
53 class RunStitchFrame: public wxFrame
54 {
55 public:
56  RunStitchFrame(wxWindow * parent, const wxString& title, const wxPoint& pos, const wxSize& size);
57 
58  bool StitchProject(const wxString& scriptFile, const wxString& outname, const wxString& userDefinedOutput, bool doDeleteOnExit);
59 
60  void OnQuit(wxCommandEvent& event);
61  void OnAbout(wxCommandEvent& event);
62  void OnProgress(wxCommandEvent& event);
64  void SetOverwrite(bool doOverwrite);
65 
66 private:
67 
68  bool m_isStitching;
69  wxString m_scriptFile;
71  wxGauge* m_progress;
72 
73  void OnProcessTerminate(wxProcessEvent & event);
74  void OnCancel(wxCommandEvent & event);
75 
77 };
78 
79 // event ID's for RunStitchPanel
80 enum
81 {
82  ID_Quit = 1,
84 };
85 
86 RunStitchFrame::RunStitchFrame(wxWindow * parent, const wxString& title, const wxPoint& pos, const wxSize& size)
87  : wxFrame(parent, -1, title, pos, size), m_isStitching(false)
88 {
89  wxBoxSizer * topsizer = new wxBoxSizer( wxVERTICAL );
90  m_stitchPanel = new RunStitchPanel(this);
91 
92  topsizer->Add(m_stitchPanel, 1, wxEXPAND | wxALL, 2);
93 
94  wxBoxSizer* bottomsizer = new wxBoxSizer(wxHORIZONTAL);
95  m_progress = new wxGauge(this, wxID_ANY, 100, wxDefaultPosition, wxDefaultSize, wxGA_HORIZONTAL | wxGA_PROGRESS);
96  bottomsizer->Add(m_progress, 1, wxEXPAND | wxALL, 10);
97  bottomsizer->Add( new wxButton(this, wxID_CANCEL, _("Cancel")),
98  0, wxALL, 10);
99  topsizer->Add(bottomsizer, 0, wxEXPAND);
100 
101 #ifdef __WXMSW__
102  // wxFrame does have a strange background color on Windows..
103  this->SetBackgroundColour(m_stitchPanel->GetBackgroundColour());
104 #endif
105 
106  // setup the environment for the different operating systems
107  wxInitAllImageHandlers();
108 #if defined __WXMSW__
109  wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
110  exePath.RemoveLastDir();
111  wxIconBundle myIcons(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + "share\\hugin\\xrc\\data\\hugin.ico", wxBITMAP_TYPE_ICO);
112  SetIcons(myIcons);
113 #else
114  wxString xrcPrefix;
115 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
116  {
117  wxString exec_path = MacGetPathToBundledResourceFile(CFSTR("xrc"));
118  if (!exec_path.IsEmpty())
119  {
120  xrcPrefix = exec_path + "/";
121  }
122  else
123  {
124  wxMessageBox(_("xrc directory not found in bundle"), _("Fatal Error"));
125  return false;
126  }
127  }
128 #elif defined UNIX_SELF_CONTAINED_BUNDLE
129  // initialize paths
130  {
131  wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
132  exePath.RemoveLastDir();
133  const wxString huginRoot(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
134  xrcPrefix = huginRoot + "share/hugin/xrc/";
135  }
136 #else
137  // add the locale directory specified during configure
138  xrcPrefix = INSTALL_XRC_DIR;
139 #endif
140  wxIcon myIcon(xrcPrefix + "data/hugin.png", wxBITMAP_TYPE_PNG);
141  SetIcon(myIcon);
142 #endif
143 
144  SetSizer( topsizer );
145 // topsizer->SetSizeHints( this ); // set size hints to honour minimum size
146  m_deleteOnExit=false;
147  // bind event handler
148  Bind(wxEVT_MENU, &RunStitchFrame::OnQuit, this, ID_Quit);
149  Bind(wxEVT_MENU, &RunStitchFrame::OnAbout, this, ID_About);
150  Bind(wxEVT_BUTTON, &RunStitchFrame::OnCancel, this, wxID_CANCEL);
151  Bind(wxEVT_END_PROCESS, &RunStitchFrame::OnProcessTerminate, this);
152  Bind(EVT_QUEUE_PROGRESS, &RunStitchFrame::OnProgress, this);
153 
154 }
155 
156 void RunStitchFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
157 {
158  wxMessageBox(wxString::Format(_("HuginStitchProject. Application to stitch hugin project files.\n Version: %s"), hugin_utils::GetHuginVersion().c_str()),
159  wxT("About hugin_stitch_project"),
160  wxOK | wxICON_INFORMATION );
161 }
162 void RunStitchFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
163 {
164  DEBUG_TRACE("");
165  if (m_isStitching) {
167  m_isStitching = false;
168  }
169  Close();
170 }
171 
172 void RunStitchFrame::OnCancel(wxCommandEvent& WXUNUSED(event))
173 {
174  DEBUG_TRACE("");
175  if (m_isStitching) {
177  m_isStitching = false;
178  } else {
179  Close();
180  }
181 }
182 
183 void RunStitchFrame::OnProcessTerminate(wxProcessEvent & event)
184 {
185  if (! m_isStitching) {
186  // canceled stitch
187  // TODO: Cleanup files?
188  Close();
189  } else {
190  m_isStitching = false;
191  if (event.GetExitCode() != 0)
192  {
193  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?"),
194  _("Error during stitching"), wxICON_ERROR | wxYES_NO )==wxYES)
195  {
196  wxString defaultdir = wxConfigBase::Get()->Read(wxT("/actualPath"),wxT(""));
197  wxFileDialog dlg(this,
198  _("Specify log file"),
199  defaultdir, wxT(""),
200  _("Log files (*.log)|*.log|All files (*)|*"),
201  wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
202  dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
203  if (dlg.ShowModal() == wxID_OK)
204  {
205  wxConfig::Get()->Write(wxT("/actualPath"), dlg.GetDirectory()); // remember for later
206  m_stitchPanel->SaveLog(dlg.GetPath());
207  };
208  }
209  } else {
210  if(m_deleteOnExit)
211  {
212  wxRemoveFile(m_scriptFile);
213  };
214  Close();
215  }
216  }
217 }
218 
219 void RunStitchFrame::OnProgress(wxCommandEvent& event)
220 {
221  if (event.GetInt() >= 0)
222  {
223  m_progress->SetValue(event.GetInt());
224  };
225 };
226 
227 bool RunStitchFrame::StitchProject(const wxString& scriptFile, const wxString& outname, const wxString& userDefinedOutput, bool doDeleteOnExit)
228 {
229  if (! m_stitchPanel->StitchProject(scriptFile, outname, userDefinedOutput)) {
230  return false;
231  }
232  m_isStitching = true;
233  m_scriptFile=scriptFile;
234  m_deleteOnExit=doDeleteOnExit;
235  return true;
236 }
237 
238 void RunStitchFrame::SetOverwrite(bool doOverwrite)
239 {
240  m_stitchPanel->SetOverwrite(doOverwrite);
241 };
242 
243 // **********************************************************************
244 
245 
250 class stitchApp : public wxApp
251 {
252 public:
253 
256  stitchApp();
257 
260  virtual ~stitchApp();
261 
264  virtual bool OnInit();
265 
267  virtual int OnExit();
268 
269 #ifdef __WXMAC__
270 
271  void MacOpenFile(const wxString &fileName);
272 #endif
273 
274 private:
275  wxLocale m_locale;
276 #ifdef __WXMAC__
277  wxString m_macFileNameToOpenOnStart;
278 #endif
279 };
280 
282 {
283  // suppress tiff warnings
284  TIFFSetWarningHandler(0);
285 
286  DEBUG_TRACE("ctor");
287 }
288 
290 {
291  DEBUG_TRACE("dtor");
292  DEBUG_TRACE("dtor end");
293 }
294 
296 {
297  // Required to access the preferences of hugin
298  SetAppName(wxT("hugin"));
299 #if defined __WXGTK__
300  CheckConfigFilename();
301 #endif
302 
303  // need to explicitly initialize locale for C++ library/runtime
304  setlocale(LC_ALL, "");
305  // initialize i18n
306 #if defined __WXMSW__
307  int localeID = wxConfigBase::Get()->Read(wxT("language"), (long) wxLANGUAGE_DEFAULT);
308  m_locale.Init(localeID);
309 #else
310  m_locale.Init(wxLANGUAGE_DEFAULT);
311 #endif
312 
313  // setup the environment for the different operating systems
314 #if defined __WXMSW__
315  wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
316  exePath.RemoveLastDir();
317  // locale setup
318  m_locale.AddCatalogLookupPathPrefix(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + wxT("share\\locale"));
319 
320 #elif defined UNIX_SELF_CONTAINED_BUNDLE
321  // initialize paths
322  {
323  wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
324  exePath.RemoveLastDir();
325  const wxString huginRoot=exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
326  // add the locale directory specified during configure
327  m_locale.AddCatalogLookupPathPrefix(huginRoot + wxT("share/locale"));
328  }
329 #else
330  // add the locale directory specified during configure
331  m_locale.AddCatalogLookupPathPrefix(wxT(INSTALL_LOCALE_DIR));
332 #endif
333 
334  // set the name of locale recource to look for
335  m_locale.AddCatalog(wxT("hugin"));
336 
337  // parse arguments
338  static const wxCmdLineEntryDesc cmdLineDesc[] =
339  {
340  //On wxWidgets 2.9, wide characters don't work here.
341  //On previous versions, the wxT macro is required for unicode builds.
342  { wxCMD_LINE_SWITCH, "h", "help", "show this help message",
343  wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
344  { wxCMD_LINE_OPTION, "o", "output", "output prefix" },
345  { wxCMD_LINE_SWITCH, "d", "delete", "delete pto file after stitching" },
346  { wxCMD_LINE_SWITCH, "w", "overwrite", "overwrite existing files" },
347  { wxCMD_LINE_OPTION, "u", "user-defined-output", "use user defined output" },
348  { wxCMD_LINE_PARAM, NULL, NULL, "<project>",
349  wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
350  { wxCMD_LINE_NONE }
351  };
352 
353  wxCmdLineParser parser(cmdLineDesc, argc, argv);
354 
355  switch ( parser.Parse() ) {
356  case -1: // -h or --help was given, and help displayed so exit
357  return false;
358  break;
359  case 0: // all is well
360  break;
361  default:
362  wxLogError(_("Syntax error in parameters detected, aborting."));
363  return false;
364  break;
365  }
366 
367  wxString scriptFile;
368 #ifdef __WXMAC__
369  m_macFileNameToOpenOnStart = wxT("");
370  wxYield();
371  scriptFile = m_macFileNameToOpenOnStart;
372 
373  // bring myself front (for being called from command line)
374  {
375  ProcessSerialNumber selfPSN;
376  OSErr err = GetCurrentProcess(&selfPSN);
377  if (err == noErr)
378  {
379  SetFrontProcess(&selfPSN);
380  }
381  }
382 #endif
383 
384  wxString userDefinedOutput;
385  parser.Found(wxT("u"), &userDefinedOutput);
386  if (!userDefinedOutput.IsEmpty())
387  {
388  if (!wxFileName::FileExists(userDefinedOutput))
389  {
390  wxMessageBox(wxString::Format(_("Could not find the specified user output file \"%s\"."), userDefinedOutput.c_str()),
391  _("Error"), wxOK | wxICON_EXCLAMATION);
392  return false;
393  };
394  };
395  if( parser.GetParamCount() == 0 && wxIsEmpty(scriptFile))
396  {
397  wxString defaultdir = wxConfigBase::Get()->Read(wxT("/actualPath"),wxT(""));
398  wxFileDialog dlg(0,
399  _("Specify project source project file"),
400  defaultdir, wxT(""),
401  _("Project files (*.pto)|*.pto|All files (*)|*"),
402  wxFD_OPEN, wxDefaultPosition);
403 
404  dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
405  if (dlg.ShowModal() == wxID_OK) {
406  wxConfig::Get()->Write(wxT("/actualPath"), dlg.GetDirectory()); // remember for later
407  scriptFile = dlg.GetPath();
408  } else { // bail
409  return false;
410  }
411  } else if(wxIsEmpty(scriptFile)) {
412  scriptFile = parser.GetParam(0);
413  std::cout << "********************* script file: " << (const char *)scriptFile.mb_str(wxConvLocal) << std::endl;
414  if (! wxIsAbsolutePath(scriptFile)) {
415  scriptFile = wxGetCwd() + wxFileName::GetPathSeparator() + scriptFile;
416  }
417  }
418 
419  std::cout << "input file is " << (const char *)scriptFile.mb_str(wxConvLocal) << std::endl;
420 
421  wxString outname;
422 
423  if ( !parser.Found(wxT("o"), &outname) ) {
424  // ask for output.
425  wxFileDialog dlg(0,_("Specify output prefix"),
426  wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")),
427  wxT(""), wxT(""),
428  wxFD_SAVE, wxDefaultPosition);
429  dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
430  if (dlg.ShowModal() == wxID_OK) {
431  while(containsInvalidCharacters(dlg.GetPath()))
432  {
433  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()),
434  _("Error"),wxOK | wxICON_EXCLAMATION);
435  if(dlg.ShowModal()!=wxID_OK)
436  return false;
437  };
438  wxFileName prefix(dlg.GetPath());
439  while (!prefix.IsDirWritable())
440  {
441  wxMessageBox(wxString::Format(_("You have no permissions to write in folder \"%s\".\nPlease select another folder for the final output."), prefix.GetPath().c_str()),
442 #ifdef __WXMSW__
443  wxT("Hugin_stitch_project"),
444 #else
445  wxT(""),
446 #endif
447  wxOK | wxICON_INFORMATION);
448  if (dlg.ShowModal() != wxID_OK)
449  {
450  return false;
451  };
452  prefix = dlg.GetPath();
453  };
454 
455  wxConfig::Get()->Write(wxT("/actualPath"), dlg.GetDirectory()); // remember for later
456  outname = dlg.GetPath();
457  } else { // bail
458 // wxLogError( _("No project files specified"));
459  return false;
460  }
461  }
462 
463  // check output filename
464  wxFileName outfn(outname);
465  wxString ext = outfn.GetExt();
466  // remove extension if it indicates an image file
467  if (ext.CmpNoCase(wxT("jpg")) == 0 || ext.CmpNoCase(wxT("jpeg")) == 0||
468  ext.CmpNoCase(wxT("tif")) == 0|| ext.CmpNoCase(wxT("tiff")) == 0 ||
469  ext.CmpNoCase(wxT("png")) == 0 || ext.CmpNoCase(wxT("exr")) == 0 ||
470  ext.CmpNoCase(wxT("pnm")) == 0 || ext.CmpNoCase(wxT("hdr")))
471  {
472  outfn.ClearExt();
473  outname = outfn.GetFullPath();
474  }
475 
476  RunStitchFrame *frame = new RunStitchFrame(NULL, wxT("Hugin Stitcher"), wxDefaultPosition, wxSize(640,600) );
477  frame->Show( true );
478  SetTopWindow( frame );
479 
480  wxFileName basename(scriptFile);
481  frame->SetTitle(wxString::Format(_("%s - Stitching"), basename.GetName().c_str()));
482  frame->SetOverwrite(parser.Found(wxT("w")));
483  bool n = frame->StitchProject(scriptFile, outname, userDefinedOutput, parser.Found(wxT("d")));
484  return n;
485 }
486 
487 
489 {
490  DEBUG_TRACE("");
491  return 0;
492 }
493 
494 
495 #ifdef __WXMAC__
496 // wx calls this method when the app gets "Open file" AppleEvent
497 void stitchApp::MacOpenFile(const wxString &fileName)
498 {
499  m_macFileNameToOpenOnStart = fileName;
500 }
501 #endif
502 
503 // make wxwindows use this class as the main application
504 IMPLEMENT_APP(stitchApp)
RunStitchFrame(wxWindow *parent, const wxString &title, const wxPoint &pos, const wxSize &size)
implementation of huginApp Class
bool FileExists(const std::string &filename)
checks if file exists
Definition: utils.cpp:362
void OnCancel(wxCommandEvent &event)
Cancels project execution - kills process.
void OnProcessTerminate(wxProcessEvent &event)
RunStitchPanel * m_stitchPanel
bool StitchProject(const wxString &scriptFile, const wxString &outname, const wxString &userDefinedOutput=wxEmptyString)
#define DEBUG_TRACE(msg)
Definition: utils.h:67
include file for the hugin project
virtual ~stitchApp()
dtor.
bool StitchProject(wxString scriptFile, wxString outname, wxString userDefinedOutput=wxEmptyString)
Starts stitching of project file.
bool SaveLog(const wxString &filename)
save the content of the window into a given log file
void OnAbout(wxCommandEvent &event)
void OnQuit(wxCommandEvent &event)
The application class for hugin_stitch_project.
include file for the hugin project
void SetOverwrite(bool over=true)
bool containsInvalidCharacters(const wxString stringToTest)
returns true, if the given strings contains invalid characters
Definition: platform.cpp:502
std::string GetHuginVersion()
return a string with version numbers
Definition: utils.cpp:907
functions for interaction with the hugin configuration file
platform/compiler specific stuff.
const wxString getInvalidCharacters()
returns all invalid characters for the filename (mainly characters, which does not work with gnu make...
Definition: platform.cpp:487
virtual bool OnInit()
pseudo constructor.
virtual int OnExit()
just for testing purposes
void SetOverwrite(bool doOverwrite)
sets, if existing output file should be automatic overwritten
void OnProgress(wxCommandEvent &event)