28 #include "wx/msw/wrapwin.h"
31 #include <wx/stdpaths.h>
35 #pragma comment(lib, "PowrProf.lib")
43 BEGIN_EVENT_TABLE(
Batch, wxFrame)
44 EVT_END_PROCESS(-1,
Batch::OnProcessTerminate)
47 #if defined _WIN32 && defined Hugin_shared
48 DEFINE_LOCAL_EVENT_TYPE(EVT_BATCH_FAILED)
49 DEFINE_LOCAL_EVENT_TYPE(EVT_INFORMATION)
50 DEFINE_LOCAL_EVENT_TYPE(EVT_UPDATE_PARENT)
52 DEFINE_EVENT_TYPE(EVT_BATCH_FAILED)
53 DEFINE_EVENT_TYPE(EVT_INFORMATION)
54 DEFINE_EVENT_TYPE(EVT_UPDATE_PARENT)
57 Batch::Batch(wxFrame* parent) : wxFrame(parent, wxID_ANY, _T(
"Batch"))
62 #if wxCHECK_VERSION(3,1,0)
78 #if wxCHECK_VERSION(3,1,0)
79 if (m_resBlocker != NULL)
94 wxFileName projectName(projectFile);
95 wxFileName outName(outputFile);
96 projectName.Normalize(wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS | wxPATH_NORM_TILDE | wxPATH_NORM_SHORTCUT);
97 outName.Normalize(wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS | wxPATH_NORM_TILDE | wxPATH_NORM_SHORTCUT);
101 Project* proj =
new Project(projectName.GetFullPath(), outName.GetFullPath(), userDefinedSequence, target);
107 Project* proj =
new Project(projectName.GetFullPath(), wxEmptyString, userDefinedSequence);
114 for(
unsigned int i=0; i<
m_projList.GetCount(); i++)
130 wxFileInputStream fileStream(file);
131 wxFileConfig batchFile(fileStream);
133 const long idGenTemp = batchFile.ReadLong(
"/Main/CurrentID", 1l);
134 const long projCount = batchFile.ReadLong(
"/Main/Count", 0l);
140 for (
long i = 1; i <= projCount; ++i)
142 const wxString group = wxString::Format(
"Project_%ld", i);
143 if (batchFile.HasGroup(group))
145 batchFile.SetPath(group);
146 const wxString projectName = batchFile.Read(
"Project", wxEmptyString);
147 const wxString type = batchFile.Read(
"Type",
"Stitching");
148 const long id = batchFile.ReadLong(
"Id", 1);
150 const bool skip = batchFile.ReadBool(
"Skip",
false);
160 const wxString userDefinedSequence = batchFile.Read(
"UserDefinedSequence", wxEmptyString);
161 if (type.CmpNoCase(
"Stitching") == 0)
163 const wxString prefix = batchFile.Read(
"Prefix", wxEmptyString);
168 if (type.CmpNoCase(
"Detecting") == 0)
186 m_projList.Last().skip = batchFile.ReadBool(
"Skip",
false);
187 batchFile.SetPath(
"/");
203 #if wxCHECK_VERSION(3,1,0)
204 if (m_resBlocker != NULL)
214 wxCommandEvent event;
232 m_projList.Item(index).userDefindSequence = newUserDefined;
239 wxMessageDialog message(
this, _(
"Cannot clear batch in progress.\nDo you want to cancel it?"),
245 wxYES_NO | wxICON_INFORMATION);
246 if(message.ShowModal()==wxID_YES)
254 ((wxFrame*)GetParent())->SetStatusText(_(
"Cleared batch."));
264 ((wxFrame*)GetParent())->SetStatusText(_(
"Cleared batch."));
301 for(
unsigned int i=0; i<
m_projList.GetCount(); i++)
324 for(
unsigned int i=0; i<
m_projList.GetCount(); i++)
347 wxMessageBox(wxString::Format(_(
"Error: Could not get status, project with index %d is not in list."),index),_(
"Error!"),wxOK | wxICON_INFORMATION );
370 else if(clearCode==2)
377 wxMessageBox(_(
"Error: Could not load batch file."));
395 for(
unsigned int i=0; i<
m_projList.GetCount(); i++)
432 wxString savedLogfile=wxEmptyString;
433 if(
saveLog || event.GetExitCode() != 0 ||
event.GetTimestamp()==-1)
437 logFile.MakeAbsolute();
438 logFile.SetExt(wxT(
"log"));
439 wxString name=logFile.GetName();
441 while(logFile.FileExists() && i<1000)
443 logFile.SetName(wxString::Format(wxT(
"%s_%d"),name.c_str(),i));
449 if((static_cast<RunStitchFrame*>(event.GetEventObject()))->SaveLog(logFile.GetFullPath()))
451 savedLogfile=logFile.GetFullPath();
455 if (event.GetExitCode() != 0 ||
event.GetTimestamp()==-1)
460 failedProject.
logfile=savedLogfile;
470 bool notifyParent=
false;
485 wxCommandEvent e(EVT_UPDATE_PARENT,wxID_ANY);
486 GetParent()->GetEventHandler()->AddPendingEvent(e);
496 #if wxCHECK_VERSION(3,1,0)
497 if (m_resBlocker != NULL)
505 wxCommandEvent e(EVT_INFORMATION,wxID_ANY);
506 e.SetString(_(
"Batch successfully completed."));
509 GetParent()->GetEventHandler()->AddPendingEvent(e);
513 ((wxFrame*)GetParent())->SetStatusText(_(
"Batch completed with errors."));
518 wxCommandEvent e(EVT_BATCH_FAILED,wxID_ANY);
519 GetParent()->GetEventHandler()->AddPendingEvent(e);
528 GetParent()->Close();
532 wxProgressDialog progress(_(
"Initializing shutdown..."), _(
"Shutting down..."), 49,
this,
533 wxPD_AUTO_HIDE | wxPD_SMOOTH | wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_CAN_SKIP);
537 while (progress.Update(i, _(
"Shutting down..."), &skip))
541 wxShutdown(wxSHUTDOWN_POWEROFF);
544 #if defined __WXMSW__
557 wxString progressCaption(_(
"Prepare to hibernate..."));
558 wxString progressLabel(_(
"Initializing hibernating..."));
561 progressCaption = wxString(_(
"Prepare to suspend..."));
562 progressLabel = wxString(_(
"Initializing suspend mode..."));
564 wxProgressDialog progress(progressLabel, progressCaption, 49,
this,
565 wxPD_AUTO_HIDE | wxPD_SMOOTH | wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_CAN_SKIP);
569 while (progress.Update(i, progressCaption, &skip))
602 bool Batch::OnStitch(wxString scriptFile, wxString outname, wxString userDefinedOutput,
int id)
605 delete wxConfigBase::Set((wxConfigBase*)NULL);
606 wxConfigBase* config = wxConfigBase::Get();
607 if(wxIsEmpty(scriptFile))
609 wxString defaultdir = config->Read(wxT(
"/actualPath"),wxT(
""));
611 _(
"Specify project file"),
613 _(
"Project files (*.pto)|*.pto|All files (*)|*"),
614 wxFD_OPEN, wxDefaultPosition);
616 dlg.SetDirectory(wxConfigBase::Get()->Read(wxT(
"/actualPath"),wxT(
"")));
617 if (dlg.ShowModal() == wxID_OK)
619 config->Write(wxT(
"/actualPath"), dlg.GetDirectory());
621 wxFileDialog dlg2(0,_(
"Specify output prefix"),
622 wxConfigBase::Get()->Read(wxT(
"/actualPath"),wxT(
"")),
624 wxFD_SAVE, wxDefaultPosition);
625 dlg2.SetDirectory(wxConfigBase::Get()->Read(wxT(
"/actualPath"),wxT(
"")));
626 if (dlg2.ShowModal() == wxID_OK)
628 outname = dlg2.GetPath();
632 wxLogError( _(
"No output prefix specified"));
635 scriptFile = dlg.GetPath();
639 wxLogError(_(
"No project files specified"));
645 wxFileName outfn(outname);
646 wxString ext = outfn.GetExt();
648 if (ext.CmpNoCase(wxT(
"jpg")) == 0 || ext.CmpNoCase(wxT(
"jpeg")) == 0 ||
649 ext.CmpNoCase(wxT(
"tif")) == 0 || ext.CmpNoCase(wxT(
"tiff")) == 0 ||
650 ext.CmpNoCase(wxT(
"png")) == 0 || ext.CmpNoCase(wxT(
"exr")) == 0 ||
651 ext.CmpNoCase(wxT(
"pnm")) == 0 || ext.CmpNoCase(wxT(
"hdr")) == 0)
654 outname = outfn.GetFullPath();
661 stitchFrame->Show(
true );
662 wxTheApp->SetTopWindow( stitchFrame );
665 wxFileName basename(scriptFile);
666 stitchFrame->SetTitle(wxString::Format(_(
"%s - Stitching"), basename.GetName().c_str()));
672 bool n = stitchFrame->
StitchProject(scriptFile, outname, userDefinedOutput);
679 stitchFrame->Close();
688 delete wxConfigBase::Set((wxConfigBase*)NULL);
693 stitchFrame->Show(
true );
694 wxTheApp->SetTopWindow( stitchFrame );
697 wxFileName basename(scriptFile);
698 stitchFrame->SetTitle(wxString::Format(_(
"%s - Assistant"), basename.GetName().c_str()));
700 bool n = stitchFrame->
DetectProject(scriptFile, userDefinedAssistant);
707 stitchFrame->Close();
722 for(
unsigned int i=0; i<
m_projList.GetCount(); i++)
737 for(
unsigned int i=0; i<
m_projList.GetCount(); i++)
755 wxMessageBox(wxString::Format(_(
"Error removing, project with id %d is not in list."),
id),_(
"Error!"),wxOK | wxICON_INFORMATION );
766 wxFileName file(
m_projList.Item(selIndex).path);
767 if(file.FileExists())
769 if(!wxRemoveFile(file.GetFullPath()))
771 wxMessageBox(wxString::Format(_(
"Error: Could not delete project file %s"), file.GetFullPath()),_(
"Error!"),wxOK | wxICON_INFORMATION );
787 ((wxFrame*)GetParent())->SetStatusText(_(
"Running batch..."));
789 #if wxCHECK_VERSION(3,1,0)
790 m_resBlocker =
new wxPowerResourceBlocker(wxPOWER_RESOURCE_SYSTEM, _(
"PTBatcherGUI is stitching"));
796 ((wxFrame*)GetParent())->SetStatusText(_(
"Batch already in progress."));
810 SetStatusText(wxString::Format(_(
"Running command \"%s\""),
m_projList.Item(i).path.c_str()));
813 if(wxExecute(
m_projList.Item(i).path, wxEXEC_SYNC)==0)
829 if (!
m_projList.Item(i).userDefindSequence.empty())
843 wxCommandEvent e(EVT_INFORMATION,wxID_ANY);
844 e.SetString(wxString::Format(_(
"Now stitching: %s"),
m_projList.Item(i).path.c_str()));
845 GetParent()->GetEventHandler()->AddPendingEvent(e);
850 wxCommandEvent e(EVT_INFORMATION,wxID_ANY);
851 e.SetString(wxString::Format(_(
"Now detecting: %s"),
m_projList.Item(i).path.c_str()));
852 GetParent()->GetEventHandler()->AddPendingEvent(e);
873 wxFileConfig batchFile;
876 batchFile.Write(
"/Main/Count",
m_projList.GetCount());
878 for (
unsigned int i = 0; i <
m_projList.GetCount(); i++)
880 batchFile.SetPath(wxString::Format(
"/Project_%u", i + 1));
881 batchFile.Write(
"Project",
m_projList.Item(i).path);
885 batchFile.Write(
"Type",
"Stitching");
886 batchFile.Write(
"Prefix",
m_projList.Item(i).prefix);
889 batchFile.Write(
"Type",
"Detecting");
892 if (!
m_projList.Item(i).userDefindSequence.IsEmpty())
894 batchFile.Write(
"UserDefinedSequence",
m_projList.Item(i).userDefindSequence);
897 batchFile.Write(
"Status", (
long)
m_projList.Item(i).status);
900 batchFile.Write(
"Skip",
m_projList.Item(i).skip);
903 wxFileOutputStream fileStream(file);
904 batchFile.Save(fileStream);
911 if (userDataDir.IsEmpty())
915 userDataDir = wxStandardPaths::Get().GetUserConfigDir();
917 return wxFileName(userDataDir, _T(
"PTBatcherQueue.ptq")).GetFullPath();
933 wxMessageBox(wxString::Format(_(
"Error: Could not set status, project with index %d is not in list."),index),_(
"Error!"),wxOK | wxICON_INFORMATION );
959 return wxEmptyString;
971 return wxEmptyString;
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.
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.
void ChangeUserDefined(int index, wxString newUserDefined)
Changes user defined sequence for project at index.