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.