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  DECLARE_EVENT_TABLE()
79 };
80 
81 // event ID's for RunStitchPanel
82 enum
83 {
84  ID_Quit = 1,
86 };
87 
88 BEGIN_EVENT_TABLE(RunStitchFrame, wxFrame)
89  EVT_MENU(ID_Quit, RunStitchFrame::OnQuit)
90  EVT_MENU(ID_About, RunStitchFrame::OnAbout)
91  EVT_BUTTON(wxID_CANCEL, RunStitchFrame::OnCancel)
92  EVT_END_PROCESS(-1, RunStitchFrame::OnProcessTerminate)
93  EVT_COMMAND(wxID_ANY, EVT_QUEUE_PROGRESS, RunStitchFrame::OnProgress)
95 
96 RunStitchFrame::RunStitchFrame(wxWindow * parent, const wxString& title, const wxPoint& pos, const wxSize& size)
97  : wxFrame(parent, -1, title, pos, size), m_isStitching(false)
98 {
99  wxBoxSizer * topsizer = new wxBoxSizer( wxVERTICAL );
100  m_stitchPanel = new RunStitchPanel(this);
101 
102  topsizer->Add(m_stitchPanel, 1, wxEXPAND | wxALL, 2);
103 
104  wxBoxSizer* bottomsizer = new wxBoxSizer(wxHORIZONTAL);
105 #if wxCHECK_VERSION(3,1,0)
106  m_progress = new wxGauge(this, wxID_ANY, 100, wxDefaultPosition, wxDefaultSize, wxGA_HORIZONTAL | wxGA_PROGRESS);
107 #else
108  m_progress = new wxGauge(this, wxID_ANY, 100, wxDefaultPosition, wxDefaultSize, wxGA_HORIZONTAL);
109 #endif
110  bottomsizer->Add(m_progress, 1, wxEXPAND | wxALL, 10);
111  bottomsizer->Add( new wxButton(this, wxID_CANCEL, _("Cancel")),
112  0, wxALL, 10);
113  topsizer->Add(bottomsizer, 0, wxEXPAND);
114 
115 #ifdef __WXMSW__
116  // wxFrame does have a strange background color on Windows..
117  this->SetBackgroundColour(m_stitchPanel->GetBackgroundColour());
118 #endif
119 
120  SetSizer( topsizer );
121 // topsizer->SetSizeHints( this ); // set size hints to honour minimum size
122  m_deleteOnExit=false;
123 }
124 
125 void RunStitchFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
126 {
127  wxMessageBox(wxString::Format(_("HuginStitchProject. Application to stitch hugin project files.\n Version: %s"), hugin_utils::GetHuginVersion().c_str()),
128  wxT("About hugin_stitch_project"),
129  wxOK | wxICON_INFORMATION );
130 }
131 void RunStitchFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
132 {
133  DEBUG_TRACE("");
134  if (m_isStitching) {
136  m_isStitching = false;
137  }
138  Close();
139 }
140 
141 void RunStitchFrame::OnCancel(wxCommandEvent& WXUNUSED(event))
142 {
143  DEBUG_TRACE("");
144  if (m_isStitching) {
146  m_isStitching = false;
147  } else {
148  Close();
149  }
150 }
151 
152 void RunStitchFrame::OnProcessTerminate(wxProcessEvent & event)
153 {
154  if (! m_isStitching) {
155  // canceled stitch
156  // TODO: Cleanup files?
157  Close();
158  } else {
159  m_isStitching = false;
160  if (event.GetExitCode() != 0)
161  {
162  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?"),
163  _("Error during stitching"), wxICON_ERROR | wxYES_NO )==wxYES)
164  {
165  wxString defaultdir = wxConfigBase::Get()->Read(wxT("/actualPath"),wxT(""));
166  wxFileDialog dlg(this,
167  _("Specify log file"),
168  defaultdir, wxT(""),
169  _("Log files (*.log)|*.log|All files (*)|*"),
170  wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
171  dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
172  if (dlg.ShowModal() == wxID_OK)
173  {
174  wxConfig::Get()->Write(wxT("/actualPath"), dlg.GetDirectory()); // remember for later
175  m_stitchPanel->SaveLog(dlg.GetPath());
176  };
177  }
178  } else {
179  if(m_deleteOnExit)
180  {
181  wxRemoveFile(m_scriptFile);
182  };
183  Close();
184  }
185  }
186 }
187 
188 void RunStitchFrame::OnProgress(wxCommandEvent& event)
189 {
190  if (event.GetInt() >= 0)
191  {
192  m_progress->SetValue(event.GetInt());
193  };
194 };
195 
196 bool RunStitchFrame::StitchProject(const wxString& scriptFile, const wxString& outname, const wxString& userDefinedOutput, bool doDeleteOnExit)
197 {
198  if (! m_stitchPanel->StitchProject(scriptFile, outname, userDefinedOutput)) {
199  return false;
200  }
201  m_isStitching = true;
202  m_scriptFile=scriptFile;
203  m_deleteOnExit=doDeleteOnExit;
204  return true;
205 }
206 
207 void RunStitchFrame::SetOverwrite(bool doOverwrite)
208 {
209  m_stitchPanel->SetOverwrite(doOverwrite);
210 };
211 
212 // **********************************************************************
213 
214 
219 class stitchApp : public wxApp
220 {
221 public:
222 
225  stitchApp();
226 
229  virtual ~stitchApp();
230 
233  virtual bool OnInit();
234 
236  virtual int OnExit();
237 
238 #ifdef __WXMAC__
239 
240  void MacOpenFile(const wxString &fileName);
241 #endif
242 
243 private:
244  wxLocale m_locale;
245 #ifdef __WXMAC__
246  wxString m_macFileNameToOpenOnStart;
247 #endif
248 };
249 
251 {
252  // suppress tiff warnings
253  TIFFSetWarningHandler(0);
254 
255  DEBUG_TRACE("ctor");
256 }
257 
259 {
260  DEBUG_TRACE("dtor");
261  DEBUG_TRACE("dtor end");
262 }
263 
265 {
266  // Required to access the preferences of hugin
267  SetAppName(wxT("hugin"));
268 #if defined __WXGTK__ && wxCHECK_VERSION(3,1,1)
269  CheckConfigFilename();
270 #endif
271 
272  // need to explicitly initialize locale for C++ library/runtime
273  setlocale(LC_ALL, "");
274  // initialize i18n
275 #if defined __WXMSW__
276  int localeID = wxConfigBase::Get()->Read(wxT("language"), (long) wxLANGUAGE_DEFAULT);
277  m_locale.Init(localeID);
278 #else
279  m_locale.Init(wxLANGUAGE_DEFAULT);
280 #endif
281 
282  // setup the environment for the different operating systems
283 #if defined __WXMSW__
284  wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
285  exePath.RemoveLastDir();
286  // locale setup
287  m_locale.AddCatalogLookupPathPrefix(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + wxT("share\\locale"));
288 
289 #elif defined UNIX_SELF_CONTAINED_BUNDLE
290  // initialize paths
291  {
292  wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
293  exePath.RemoveLastDir();
294  const wxString huginRoot=exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
295  // add the locale directory specified during configure
296  m_locale.AddCatalogLookupPathPrefix(huginRoot + wxT("share/locale"));
297  }
298 #else
299  // add the locale directory specified during configure
300  m_locale.AddCatalogLookupPathPrefix(wxT(INSTALL_LOCALE_DIR));
301 #endif
302 
303  // set the name of locale recource to look for
304  m_locale.AddCatalog(wxT("hugin"));
305 
306  // parse arguments
307  static const wxCmdLineEntryDesc cmdLineDesc[] =
308  {
309  //On wxWidgets 2.9, wide characters don't work here.
310  //On previous versions, the wxT macro is required for unicode builds.
311  { wxCMD_LINE_SWITCH, "h", "help", "show this help message",
312  wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
313  { wxCMD_LINE_OPTION, "o", "output", "output prefix" },
314  { wxCMD_LINE_SWITCH, "d", "delete", "delete pto file after stitching" },
315  { wxCMD_LINE_SWITCH, "w", "overwrite", "overwrite existing files" },
316  { wxCMD_LINE_OPTION, "u", "user-defined-output", "use user defined output" },
317  { wxCMD_LINE_PARAM, NULL, NULL, "<project>",
318  wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
319  { wxCMD_LINE_NONE }
320  };
321 
322  wxCmdLineParser parser(cmdLineDesc, argc, argv);
323 
324  switch ( parser.Parse() ) {
325  case -1: // -h or --help was given, and help displayed so exit
326  return false;
327  break;
328  case 0: // all is well
329  break;
330  default:
331  wxLogError(_("Syntax error in parameters detected, aborting."));
332  return false;
333  break;
334  }
335 
336  wxString scriptFile;
337 #ifdef __WXMAC__
338  m_macFileNameToOpenOnStart = wxT("");
339  wxYield();
340  scriptFile = m_macFileNameToOpenOnStart;
341 
342  // bring myself front (for being called from command line)
343  {
344  ProcessSerialNumber selfPSN;
345  OSErr err = GetCurrentProcess(&selfPSN);
346  if (err == noErr)
347  {
348  SetFrontProcess(&selfPSN);
349  }
350  }
351 #endif
352 
353  wxString userDefinedOutput;
354  parser.Found(wxT("u"), &userDefinedOutput);
355  if (!userDefinedOutput.IsEmpty())
356  {
357  if (!wxFileName::FileExists(userDefinedOutput))
358  {
359  wxMessageBox(wxString::Format(_("Could not find the specified user output file \"%s\"."), userDefinedOutput.c_str()),
360  _("Error"), wxOK | wxICON_EXCLAMATION);
361  return false;
362  };
363  };
364  if( parser.GetParamCount() == 0 && wxIsEmpty(scriptFile))
365  {
366  wxString defaultdir = wxConfigBase::Get()->Read(wxT("/actualPath"),wxT(""));
367  wxFileDialog dlg(0,
368  _("Specify project source project file"),
369  defaultdir, wxT(""),
370  _("Project files (*.pto)|*.pto|All files (*)|*"),
371  wxFD_OPEN, wxDefaultPosition);
372 
373  dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
374  if (dlg.ShowModal() == wxID_OK) {
375  wxConfig::Get()->Write(wxT("/actualPath"), dlg.GetDirectory()); // remember for later
376  scriptFile = dlg.GetPath();
377  } else { // bail
378  return false;
379  }
380  } else if(wxIsEmpty(scriptFile)) {
381  scriptFile = parser.GetParam(0);
382  std::cout << "********************* script file: " << (const char *)scriptFile.mb_str(wxConvLocal) << std::endl;
383  if (! wxIsAbsolutePath(scriptFile)) {
384  scriptFile = wxGetCwd() + wxFileName::GetPathSeparator() + scriptFile;
385  }
386  }
387 
388  std::cout << "input file is " << (const char *)scriptFile.mb_str(wxConvLocal) << std::endl;
389 
390  wxString outname;
391 
392  if ( !parser.Found(wxT("o"), &outname) ) {
393  // ask for output.
394  wxFileDialog dlg(0,_("Specify output prefix"),
395  wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")),
396  wxT(""), wxT(""),
397  wxFD_SAVE, wxDefaultPosition);
398  dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
399  if (dlg.ShowModal() == wxID_OK) {
400  while(containsInvalidCharacters(dlg.GetPath()))
401  {
402  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()),
403  _("Error"),wxOK | wxICON_EXCLAMATION);
404  if(dlg.ShowModal()!=wxID_OK)
405  return false;
406  };
407  wxFileName prefix(dlg.GetPath());
408  while (!prefix.IsDirWritable())
409  {
410  wxMessageBox(wxString::Format(_("You have no permissions to write in folder \"%s\".\nPlease select another folder for the final output."), prefix.GetPath().c_str()),
411 #ifdef __WXMSW__
412  wxT("Hugin_stitch_project"),
413 #else
414  wxT(""),
415 #endif
416  wxOK | wxICON_INFORMATION);
417  if (dlg.ShowModal() != wxID_OK)
418  {
419  return false;
420  };
421  prefix = dlg.GetPath();
422  };
423 
424  wxConfig::Get()->Write(wxT("/actualPath"), dlg.GetDirectory()); // remember for later
425  outname = dlg.GetPath();
426  } else { // bail
427 // wxLogError( _("No project files specified"));
428  return false;
429  }
430  }
431 
432  // check output filename
433  wxFileName outfn(outname);
434  wxString ext = outfn.GetExt();
435  // remove extension if it indicates an image file
436  if (ext.CmpNoCase(wxT("jpg")) == 0 || ext.CmpNoCase(wxT("jpeg")) == 0||
437  ext.CmpNoCase(wxT("tif")) == 0|| ext.CmpNoCase(wxT("tiff")) == 0 ||
438  ext.CmpNoCase(wxT("png")) == 0 || ext.CmpNoCase(wxT("exr")) == 0 ||
439  ext.CmpNoCase(wxT("pnm")) == 0 || ext.CmpNoCase(wxT("hdr")))
440  {
441  outfn.ClearExt();
442  outname = outfn.GetFullPath();
443  }
444 
445  RunStitchFrame *frame = new RunStitchFrame(NULL, wxT("Hugin Stitcher"), wxDefaultPosition, wxSize(640,600) );
446  frame->Show( true );
447  SetTopWindow( frame );
448 
449  wxFileName basename(scriptFile);
450  frame->SetTitle(wxString::Format(_("%s - Stitching"), basename.GetName().c_str()));
451  frame->SetOverwrite(parser.Found(wxT("w")));
452  bool n = frame->StitchProject(scriptFile, outname, userDefinedOutput, parser.Found(wxT("d")));
453  return n;
454 }
455 
456 
458 {
459  DEBUG_TRACE("");
460  return 0;
461 }
462 
463 
464 #ifdef __WXMAC__
465 // wx calls this method when the app gets "Open file" AppleEvent
466 void stitchApp::MacOpenFile(const wxString &fileName)
467 {
468  m_macFileNameToOpenOnStart = fileName;
469 }
470 #endif
471 
472 // make wxwindows use this class as the main application
473 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
END_EVENT_TABLE()
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:920
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)