28 #include "wx/msw/wrapwin.h" 
   31 #include <wx/stdpaths.h> 
   35 #pragma comment(lib, "PowrProf.lib") 
   48 Batch::Batch(wxFrame* parent) : wxFrame(parent, wxID_ANY, _T(
"Batch"))
 
   82     wxFileName projectName(projectFile);
 
   83     wxFileName outName(outputFile);
 
   84     projectName.Normalize(wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS | wxPATH_NORM_TILDE | wxPATH_NORM_SHORTCUT);
 
   85     outName.Normalize(wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS | wxPATH_NORM_TILDE | wxPATH_NORM_SHORTCUT);
 
   89         Project* proj = 
new Project(projectName.GetFullPath(), outName.GetFullPath(), userDefinedSequence, target);
 
   95         Project* proj = 
new Project(projectName.GetFullPath(), wxEmptyString, userDefinedSequence);
 
  102     for(
unsigned int i=0; i<
m_projList.GetCount(); i++)
 
  118         wxFileInputStream fileStream(file);
 
  119         wxFileConfig batchFile(fileStream);
 
  121         const long idGenTemp = batchFile.ReadLong(
"/Main/CurrentID", 1l);
 
  122         const long projCount = batchFile.ReadLong(
"/Main/Count", 0l);
 
  128             for (
long i = 1; i <= projCount; ++i)
 
  130                 const wxString group = wxString::Format(
"Project_%ld", i);
 
  131                 if (batchFile.HasGroup(group))
 
  133                     batchFile.SetPath(group);
 
  134                     const wxString projectName = batchFile.Read(
"Project", wxEmptyString);
 
  135                     const wxString type = batchFile.Read(
"Type", 
"Stitching");
 
  136                     const long id = batchFile.ReadLong(
"Id", 1);
 
  138                     const bool skip = batchFile.ReadBool(
"Skip", 
false);
 
  148                         const wxString userDefinedSequence = batchFile.Read(
"UserDefinedSequence", wxEmptyString);
 
  149                         if (type.CmpNoCase(
"Stitching") == 0)
 
  151                             const wxString prefix = batchFile.Read(
"Prefix", wxEmptyString);
 
  156                             if (type.CmpNoCase(
"Detecting") == 0)
 
  174                     m_projList.Last().skip = batchFile.ReadBool(
"Skip", 
false);
 
  175                     batchFile.SetPath(
"/");
 
  200     wxCommandEvent event;
 
  218     m_projList.Item(index).userDefindSequence = newUserDefined;
 
  225         if (
hugin_utils::HuginMessageBox(_(
"Cannot clear batch in progress.\nDo you want to cancel it?"), _(
"PTBatcherGUI"), wxYES_NO | wxICON_INFORMATION, wxGetActiveWindow()) == wxYES)
 
  233             ((wxFrame*)GetParent())->SetStatusText(_(
"Cleared batch."));
 
  243         ((wxFrame*)GetParent())->SetStatusText(_(
"Cleared batch."));
 
  280     for(
unsigned int i=0; i<
m_projList.GetCount(); i++)
 
  303     for(
unsigned int i=0; i<
m_projList.GetCount(); i++)
 
  326         hugin_utils::HuginMessageBox(wxString::Format(_(
"Error: Could not get status, project with index %d is not in list."), index), _(
"PTBatcherGUI"), wxOK | wxICON_INFORMATION, wxGetActiveWindow());
 
  349     else if(clearCode==2)
 
  374     for(
unsigned int i=0; i<
m_projList.GetCount(); i++)
 
  411         wxString savedLogfile=wxEmptyString;
 
  412         if(
saveLog || event.GetExitCode() != 0 || 
event.GetTimestamp()==-1)
 
  416             logFile.MakeAbsolute();
 
  417             logFile.SetExt(
"log");
 
  418             wxString name=logFile.GetName();
 
  420             while(logFile.FileExists() && i<1000)
 
  422                 logFile.SetName(wxString::Format(
"%s_%d",name.c_str(),i));
 
  428                 if((static_cast<RunStitchFrame*>(event.GetEventObject()))->SaveLog(logFile.GetFullPath()))
 
  430                     savedLogfile=logFile.GetFullPath();
 
  434         if (event.GetExitCode() != 0 || 
event.GetTimestamp()==-1) 
 
  439             failedProject.
logfile=savedLogfile;
 
  449                 bool notifyParent=
false;
 
  464                     wxCommandEvent e(EVT_UPDATE_PARENT,wxID_ANY);
 
  465                     GetParent()->GetEventHandler()->AddPendingEvent(e);
 
  482                     wxCommandEvent e(EVT_INFORMATION,wxID_ANY);
 
  483                     e.SetString(_(
"Batch successfully completed."));
 
  486                     GetParent()->GetEventHandler()->AddPendingEvent(e);
 
  490                     ((wxFrame*)GetParent())->SetStatusText(_(
"Batch completed with errors."));
 
  495                         wxCommandEvent e(EVT_BATCH_FAILED,wxID_ANY);
 
  496                         GetParent()->GetEventHandler()->AddPendingEvent(e);
 
  505                         GetParent()->Close();
 
  510                             wxGenericProgressDialog progress(_(
"Initializing shutdown..."), _(
"Shutting down..."), 49, 
this,
 
  511                                 wxPD_AUTO_HIDE | wxPD_SMOOTH | wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_CAN_SKIP);
 
  513                             wxProgressDialog progress(_(
"Initializing shutdown..."), _(
"Shutting down..."), 49, 
this,
 
  514                                 wxPD_AUTO_HIDE | wxPD_SMOOTH | wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_CAN_SKIP);
 
  519                             while (progress.Update(i, _(
"Shutting down..."), &skip))
 
  523                                     wxShutdown(wxSHUTDOWN_POWEROFF);
 
  526 #if defined __WXMSW__ 
  539                             wxString progressCaption(_(
"Prepare to hibernate..."));
 
  540                             wxString progressLabel(_(
"Initializing hibernating..."));
 
  543                                 progressCaption = wxString(_(
"Prepare to suspend..."));
 
  544                                 progressLabel = wxString(_(
"Initializing suspend mode..."));
 
  546                             wxGenericProgressDialog progress(progressLabel, progressCaption, 49, 
this,
 
  547                                 wxPD_AUTO_HIDE | wxPD_SMOOTH | wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_CAN_SKIP);
 
  551                             while (progress.Update(i, progressCaption, &skip))
 
  584 bool Batch::OnStitch(wxString scriptFile, wxString outname, wxString userDefinedOutput, 
int id)
 
  587     delete wxConfigBase::Set((wxConfigBase*)NULL);
 
  588     wxConfigBase* config = wxConfigBase::Get();
 
  589     if(wxIsEmpty(scriptFile))
 
  591         wxString defaultdir = config->Read(
"/actualPath",wxEmptyString);
 
  593                          _(
"Specify project file"),
 
  594                          defaultdir, wxEmptyString,
 
  595                          _(
"Project files (*.pto)|*.pto|All files (*)|*"),
 
  596                          wxFD_OPEN, wxDefaultPosition);
 
  598         dlg.SetDirectory(wxConfigBase::Get()->Read(
"/actualPath",wxEmptyString));
 
  599         if (dlg.ShowModal() == wxID_OK)
 
  601             config->Write(
"/actualPath", dlg.GetDirectory());  
 
  603             wxFileDialog dlg2(0,_(
"Specify output prefix"),
 
  604                               wxConfigBase::Get()->Read(
"/actualPath",wxEmptyString),
 
  605                               wxEmptyString, wxEmptyString,
 
  606                               wxFD_SAVE, wxDefaultPosition);
 
  607             dlg2.SetDirectory(wxConfigBase::Get()->Read(
"/actualPath",wxEmptyString));
 
  608             if (dlg2.ShowModal() == wxID_OK)
 
  610                 outname = dlg2.GetPath();
 
  614                 wxLogError( _(
"No output prefix specified"));
 
  617             scriptFile = dlg.GetPath();
 
  621             wxLogError(_(
"No project files specified"));
 
  627     wxFileName outfn(outname);
 
  628     wxString ext = outfn.GetExt();
 
  630     if (ext.CmpNoCase(
"jpg") == 0 || ext.CmpNoCase(
"jpeg") == 0 ||
 
  631             ext.CmpNoCase(
"tif") == 0 || ext.CmpNoCase(
"tiff") == 0 ||
 
  632             ext.CmpNoCase(
"png") == 0 || ext.CmpNoCase(
"exr") == 0 ||
 
  633             ext.CmpNoCase(
"pnm") == 0 || ext.CmpNoCase(
"hdr") == 0)
 
  636         outname = outfn.GetFullPath();
 
  643         stitchFrame->Show( 
true );
 
  644         wxTheApp->SetTopWindow( stitchFrame );
 
  647     wxFileName basename(scriptFile);
 
  648     stitchFrame->SetTitle(wxString::Format(_(
"%s - Stitching"), basename.GetName().c_str()));
 
  654     bool n = stitchFrame->
StitchProject(scriptFile, outname, userDefinedOutput);
 
  661         stitchFrame->Close();
 
  670     delete wxConfigBase::Set((wxConfigBase*)NULL);
 
  675         stitchFrame->Show( 
true );
 
  676         wxTheApp->SetTopWindow( stitchFrame );
 
  679     wxFileName basename(scriptFile);
 
  680     stitchFrame->SetTitle(wxString::Format(_(
"%s - Assistant"), basename.GetName().c_str()));
 
  682     bool n = stitchFrame->
DetectProject(scriptFile, userDefinedAssistant);
 
  689         stitchFrame->Close();
 
  704         for(
unsigned int i=0; i<
m_projList.GetCount(); i++)
 
  719         for(
unsigned int i=0; i<
m_projList.GetCount(); i++)
 
  737         hugin_utils::HuginMessageBox(wxString::Format(_(
"Error removing, project with id %d is not in list."), 
id), _(
"PTBatcherGUI"), wxOK | wxICON_INFORMATION, wxGetActiveWindow());
 
  748         wxFileName file(
m_projList.Item(selIndex).path);
 
  749         if(file.FileExists())
 
  751             if(!wxRemoveFile(file.GetFullPath()))
 
  753                 hugin_utils::HuginMessageBox(wxString::Format(_(
"Error: Could not delete project file %s"), file.GetFullPath()), _(
"PTBatcherGUI"), wxOK | wxICON_INFORMATION, wxGetActiveWindow());
 
  769         ((wxFrame*)GetParent())->SetStatusText(_(
"Running batch..."));
 
  771         m_resBlocker = 
new wxPowerResourceBlocker(wxPOWER_RESOURCE_SYSTEM, _(
"PTBatcherGUI is stitching"));
 
  776         ((wxFrame*)GetParent())->SetStatusText(_(
"Batch already in progress."));
 
  790             SetStatusText(wxString::Format(_(
"Running command \"%s\""), 
m_projList.Item(i).path.c_str()));
 
  793             if(wxExecute(
m_projList.Item(i).path, wxEXEC_SYNC)==0)
 
  809             if (!
m_projList.Item(i).userDefindSequence.empty())
 
  823                 wxCommandEvent e(EVT_INFORMATION,wxID_ANY);
 
  824                 e.SetString(wxString::Format(_(
"Now stitching: %s"),
m_projList.Item(i).path.c_str()));
 
  825                 GetParent()->GetEventHandler()->AddPendingEvent(e);
 
  830                 wxCommandEvent e(EVT_INFORMATION,wxID_ANY);
 
  831                 e.SetString(wxString::Format(_(
"Now detecting: %s"),
m_projList.Item(i).path.c_str()));
 
  832                 GetParent()->GetEventHandler()->AddPendingEvent(e);
 
  853     wxFileConfig batchFile;
 
  856     batchFile.Write(
"/Main/Count", 
m_projList.GetCount());
 
  858     for (
unsigned int i = 0; i < 
m_projList.GetCount(); i++)
 
  860         batchFile.SetPath(wxString::Format(
"/Project_%u", i + 1));
 
  861         batchFile.Write(
"Project", 
m_projList.Item(i).path);
 
  865                 batchFile.Write(
"Type", 
"Stitching");
 
  866                 batchFile.Write(
"Prefix", 
m_projList.Item(i).prefix);
 
  869                 batchFile.Write(
"Type", 
"Detecting");
 
  872         if (!
m_projList.Item(i).userDefindSequence.IsEmpty())
 
  874             batchFile.Write(
"UserDefinedSequence", 
m_projList.Item(i).userDefindSequence);
 
  877         batchFile.Write(
"Status", (
long)
m_projList.Item(i).status);
 
  880             batchFile.Write(
"Skip", 
m_projList.Item(i).skip);
 
  883     wxFileOutputStream fileStream(file);
 
  884     batchFile.Save(fileStream);
 
  891     if (userDataDir.IsEmpty())
 
  895         userDataDir = wxStandardPaths::Get().GetUserConfigDir();
 
  897     return wxFileName(userDataDir, _T(
"PTBatcherQueue.ptq")).GetFullPath();
 
  913         hugin_utils::HuginMessageBox(wxString::Format(_(
"Error: Could not set status, project with index %d is not in list."), index), _(
"PTBatcherGUI"), wxOK | wxICON_INFORMATION, wxGetActiveWindow());
 
  939         return wxEmptyString;
 
  951         return wxEmptyString;
 
wxDEFINE_EVENT(EVT_QUEUE_PROGRESS, wxCommandEvent)
 
bool NoErrors()
Returns true if there are no failed projects in batch. 
 
int GetRunningCount()
Returns number of projects currently in progress. 
 
int ClearBatch()
Clears batch list and returns 0 if succesful. 
 
int GetFirstAvailable()
Returns index of first waiting project in batch. 
 
bool FileExists(const std::string &filename)
checks if file exists 
 
void SwapProject(int index)
Swaps position in batch of project at index with project at index+1. 
 
void RemoveProjectAtIndex(int selIndex)
Removes project at index from batch list. 
 
int GetProjectCount()
Returns number of projects in batch list. 
 
FrameArray m_stitchFrames
 
RunStitchPanel * m_stitchPanel
 
int GetIndex(int id)
Returns index of project with selected id. 
 
void SetStatus(int index, Project::Status status)
Used internally to set status of selected project. 
 
void CancelBatch()
Stops batch run, failing projects in progress. 
 
bool OnDetect(wxString scriptFile, wxString userDefinedAssistant, int id)
called to start detecting 
 
void RemoveProject(int id)
Removes project with id from batch list. 
 
void AddProjectToBatch(wxString projectFile, wxString outputFile=wxEmptyString, wxString userDefinedSequence=wxEmptyString, Project::Target target=Project::STITCHING)
Adds a project entry in the batch list. 
 
void AddAppToBatch(wxString app)
Adds an application entry in the batch list. 
 
bool StitchProject(wxString scriptFile, wxString outname, wxString userDefinedOutput=wxEmptyString)
Starts stitching of project file. 
 
int LoadBatchFile(wxString file)
Clears current batch list and loads projects from batch file. 
 
bool IsPaused()
Returns true if batch execution is currently paused. 
 
void ChangePrefix(int index, wxString newPrefix)
Changes output prefix for project at index. 
 
void AppendBatchFile(wxString file)
Appends projects from file to batch list. 
 
bool DetectProject(wxString scriptFile, wxString userDefinedAssistant=wxEmptyString)
starts assistant of project file 
 
Project::Status GetStatus(int index)
Returns current status of project at index. 
 
bool IsRunning()
return true, if batch is running 
 
void RunNextInBatch()
Starts execution of next waiting project in batch. 
 
wxString GetFailedProjectName(unsigned int i)
returns project file name of failed project with index i 
 
void PauseBatch()
Pauses and continues batch execution. 
 
wxPowerResourceBlocker * m_resBlocker
 
void SaveTemp()
Saves batch list to temporary file. 
 
Project * GetProject(int index)
Returns project at index. 
 
void ShowOutput(bool isVisible=true)
Set visibility of all running projects. 
 
int GetProjectCountByPath(wxString path)
Returns number of projects in batch list with the input file path. 
 
void RunBatch()
Starts batch execution. 
 
std::vector< FailedProject > m_failedProjects
 
Batch(wxFrame *parent)
Main constructor. 
 
void SetOverwrite(bool over=true)
 
void CancelProject(int index)
Cancels project at index in batch, failing it. 
 
void SaveBatchFile(wxString file)
Saves batch list to file. 
 
bool CompareProjectsInLists(int stitchListIndex, int batchListIndex)
Compares two project at indexes in both lists and returns true if they have identical project ids...
 
std::string GetUserAppDataDir()
returns the directory for user specific Hugin settings, e.g. 
 
wxString GetBatchFilename()
returns the filename of the default queue file 
 
bool AllDone()
Returns true if there are no more projects pending execution. 
 
Batch processor for Hugin. 
 
void SetProjectId(int id)
Sets project id from batch. 
 
void OnProcessTerminate(wxProcessEvent &event)
Called internally when all running processes have completed and need to be removed from running list...
 
wxString GetFailedProjectLog(unsigned int i)
returns log file name of failed project with index i 
 
int LoadTemp()
Loads temporary batch file. 
 
bool OnStitch(wxString scriptFile, wxString outname, wxString userDefinedOutput, int id)
Called to start stitch of project with input scriptFile. 
 
int HuginMessageBox(const wxString &message, const wxString &caption, int style, wxWindow *parent)
 
void ChangeUserDefined(int index, wxString newUserDefined)
Changes user defined sequence for project at index.