From: <mk...@us...> - 2008-08-16 03:27:37
|
Revision: 3324 http://hugin.svn.sourceforge.net/hugin/?rev=3324&view=rev Author: mkuder Date: 2008-08-16 03:27:33 +0000 (Sat, 16 Aug 2008) Log Message: ----------- - removed some duplicate files in console and GUI version - added check box for verbose mode (output window) on GUI - fixed delete key bug, where key was registered in main app even when text input box was open - changed some program command line switches to make them more similar in console and GUI version - arranged class methods in alphabetical order where appropriate - added comments to method declarations in all classes - added GPL license text to files - fixed inappropriate "added project *" verbose outputs Modified Paths: -------------- hugin/branches/gsoc2008_batch_processing/src/PTBatcher/Batch.cpp hugin/branches/gsoc2008_batch_processing/src/PTBatcher/Batch.h hugin/branches/gsoc2008_batch_processing/src/PTBatcher/CMakeLists.txt hugin/branches/gsoc2008_batch_processing/src/PTBatcher/PTBatcher.cpp hugin/branches/gsoc2008_batch_processing/src/PTBatcher/PTBatcher.h hugin/branches/gsoc2008_batch_processing/src/PTBatcher/ProjectArray.cpp hugin/branches/gsoc2008_batch_processing/src/PTBatcher/ProjectArray.h hugin/branches/gsoc2008_batch_processing/src/PTBatcher/RunStitchFrame.cpp hugin/branches/gsoc2008_batch_processing/src/PTBatcher/RunStitchFrame.h hugin/branches/gsoc2008_batch_processing/src/PTBatcherGUI/BatchFrame.cpp hugin/branches/gsoc2008_batch_processing/src/PTBatcherGUI/BatchFrame.h hugin/branches/gsoc2008_batch_processing/src/PTBatcherGUI/CMakeLists.txt hugin/branches/gsoc2008_batch_processing/src/PTBatcherGUI/DirTraverser.h hugin/branches/gsoc2008_batch_processing/src/PTBatcherGUI/PTBatcherGUI.cpp hugin/branches/gsoc2008_batch_processing/src/PTBatcherGUI/PTBatcherGUI.h hugin/branches/gsoc2008_batch_processing/src/PTBatcherGUI/ProjectListBox.cpp hugin/branches/gsoc2008_batch_processing/src/PTBatcherGUI/ProjectListBox.h Removed Paths: ------------- hugin/branches/gsoc2008_batch_processing/src/PTBatcher/DirTraverser.h hugin/branches/gsoc2008_batch_processing/src/PTBatcher/HostApp.h hugin/branches/gsoc2008_batch_processing/src/PTBatcher/ProjectListBox.cpp hugin/branches/gsoc2008_batch_processing/src/PTBatcher/ProjectListBox.h hugin/branches/gsoc2008_batch_processing/src/PTBatcherGUI/ProjectArray.cpp hugin/branches/gsoc2008_batch_processing/src/PTBatcherGUI/ProjectArray.h Property Changed: ---------------- hugin/branches/gsoc2008_batch_processing/src/PTBatcher/ hugin/branches/gsoc2008_batch_processing/src/PTBatcherGUI/ Property changes on: hugin/branches/gsoc2008_batch_processing/src/PTBatcher ___________________________________________________________________ Added: svn:ignore + DirTraverser2.h ProjectListBox2.cpp ProjectListBox2.h PTBatcher2.h Modified: hugin/branches/gsoc2008_batch_processing/src/PTBatcher/Batch.cpp =================================================================== --- hugin/branches/gsoc2008_batch_processing/src/PTBatcher/Batch.cpp 2008-08-15 22:27:21 UTC (rev 3323) +++ hugin/branches/gsoc2008_batch_processing/src/PTBatcher/Batch.cpp 2008-08-16 03:27:33 UTC (rev 3324) @@ -1,3 +1,29 @@ +// -*- c-basic-offset: 4 -*- + +/** @file Batch.cpp + * + * @brief Batch processor for Hugin + * + * @author Marko Kuder <mar...@gm...> + * + * $Id: Batch.cpp 3322 2008-08-16 5:00:07Z mkuder $ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + #include "Batch.h" BEGIN_EVENT_TABLE(Batch, wxFrame) @@ -60,113 +86,158 @@ m_locale.AddCatalog(wxT("hugin")); } -void Batch::ListBatch() +void Batch::AddAppToBatch(wxString app) { - if(m_projList.GetCount() == 0) - cout << "Batch is empty." << endl; - else - { - cout << "List of projects in batch:" << endl << - "[ID] [project path] [output filename] [status]" << endl << - "-------------------------------------" << endl; - for(unsigned int i=0; i<m_projList.GetCount(); i++) - { - cout << m_projList.Item(i).id << " " << m_projList.Item(i).path.char_str() << " " << m_projList.Item(i).prefix.char_str() << " " << m_projList.Item(i).GetStatusText().char_str() << endl; - } - } + Project *newApp = new Project(app); + m_projList.Add(newApp); } - void Batch::AddProjectToBatch(wxString projectFile, wxString outputFile) -{ - AddProjectToBatch(projectFile); +{ + wxFileName name(projectFile); + if(outputFile.Cmp(_T(""))!=0) - m_projList.Last().prefix = outputFile; - if(gui) - ((wxFrame*)GetParent())->SetStatusText(_T("Added project ")+projectFile+_T(" with output ")+outputFile); - else if(verbose) - cout << "Added project " << projectFile.c_str() << " with output " << outputFile.c_str() << endl; + { + Project *proj = new Project(projectFile,outputFile); + m_projList.Add(proj); + /*if(gui) + ((wxFrame*)GetParent())->SetStatusText(_T("Added project ")+projectFile+_T(" with output ")+outputFile); + else if(verbose) + cout << "Added project " << projectFile.char_str() << " with output " << outputFile.char_str() << endl;*/ + } + else + { + Project *proj = new Project(projectFile,name.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + name.GetName()); + m_projList.Add(proj); + /*if(gui) + ((wxFrame*)GetParent())->SetStatusText(_T("Added project ")+projectFile); + else if(verbose) + cout << "Added project " << projectFile.char_str() << endl;*/ + } } -bool Batch::AddProjectToBatch(wxString projectFile) +bool Batch::AllDone() { - wxFileName name(projectFile); - Project *proj = new Project(projectFile,name.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + name.GetName()); - m_projList.Add(proj); + for(unsigned int i=0; i<m_projList.GetCount(); i++) + { + if(m_projList.Item(i).status==Project::WAITING || + m_projList.Item(i).status==Project::RUNNING || + m_projList.Item(i).status==Project::PAUSED) + { + return false; + } + } + return true; +} - return true; +void Batch::AppendBatchFile(wxString file) +{ + if(wxFileName::FileExists(file)) + { + wxFileInputStream fileStream(file); + wxString projectName = _T(""); + wxTextInputStream textStream(fileStream); + + //TO-DO: batch file error checking? + //first line in file is idGenerator + long idGen = 1; + textStream.ReadLine().ToLong(&idGen); + //then for each project: project path, prefix, id, status, skip + while((projectName = textStream.ReadLine()).Cmp(_(""))!=0) + { + //we add project to internal list + AddProjectToBatch(projectName,textStream.ReadLine()); + textStream.ReadLine().ToLong(&m_projList.Last().id); + long status; + textStream.ReadLine().ToLong(&status); + //if status was RUNNING or PAUSED, we set it to FAILED + if(status==(long)Project::RUNNING || status==(long)Project::PAUSED) + status=(long)Project::FAILED; + //if(status==2 || status==5) + // status=3; + m_projList.Last().status = (Project::Status)status; + if(textStream.ReadLine().StartsWith(_T("T"))) + m_projList.Last().skip = true; + //after setting all values, we add project to the GUI list box + //wxGetApp().frame->projListBox->AppendProject(&wxGetApp().m_projList.Last()); + } + //we store the id generator + Project::idGenerator = idGen; + } } - -void Batch::AddAppToBatch(wxString app) -{ - Project *newApp = new Project(app); - m_projList.Add(newApp); + +void Batch::CancelBatch() +{ + m_cancelled = true; + for(int i=0; i<GetRunningCount(); i++) + CancelProject(i); + m_running = false; } - -void Batch::RemoveProject(int id) -{ - int index; - if((index=GetIndex(id)) != -1) - { - RemoveProjectAtIndex(GetIndex(id)); - } - else if(gui) - wxMessageBox( _T("Error removing, project with id ")+wxString::Format(_T("%d"),id)+_T(" is not in list."),_T("Error!"),wxOK | wxICON_INFORMATION ); - else if(verbose) - cout << "Error: Project with id " << id << " is not in list." << endl; -} -void Batch::RemoveProjectAtIndex(int selIndex) -{ - //we delete only successful project files and no applications - if(deleteFiles - && m_projList.Item(selIndex).id>=0 - && m_projList.Item(selIndex).status==Project::FINISHED) - { - wxFileName file(m_projList.Item(selIndex).path); - if(file.FileExists()) - { - if(!wxRemoveFile(file.GetFullPath())) - { - if(gui) - wxMessageBox( _T("Error: Could not delete project file ")+file.GetFullPath(),_T("Error!"),wxOK | wxICON_INFORMATION ); - else if(verbose) - cout << "Error: Could not delete project file " << file.GetFullPath().char_str() << endl; - } - } - } - m_projList.RemoveAt(selIndex); - if(m_projList.GetCount()==0) //reset the id generator on empty list - Project::idGenerator=1; +void Batch::CancelProject(int index) +{ + wxCommandEvent event; + m_stitchFrames.Item(index)->OnCancel(event); + m_paused = false; + if(GetRunningCount()==0) + m_running = false; } - void Batch::ChangePrefix(int index, wxString newPrefix) { m_projList.Item(index).prefix = newPrefix; } -Project::Status Batch::GetStatus(int index) -{ - if((unsigned int)index<m_projList.GetCount()) - return m_projList.Item(index).status; - else if(gui) - wxMessageBox( _T("Error: Could not get status, project with index ")+wxString::Format(_("%d"),index)+_T(" is not in list."),_T("Error!"),wxOK | wxICON_INFORMATION ); - else if(verbose) - cout << "Error: Could not get status, project with index " << index << " is not in list." << endl; - return Project::MISSING; -} -void Batch::SetStatus(int index,Project::Status status) +bool Batch::CheckProjectExistence() { - if((unsigned int)index<m_projList.GetCount()) - m_projList.Item(index).status = status; - else if(gui) - wxMessageBox( _T("Error: Could not set status, project with index ")+wxString::Format(_("%d"),index)+_T(" is not in list."),_T("Error!"),wxOK | wxICON_INFORMATION ); - else if(verbose) - cout << "Error: Could not set status, project with index " << index << " is not in list." << endl; + #ifdef __WXMSW__ + bool exist = true; + HANDLE process; + DWORD exitState; + while(exist) + { + exist = false; + + for(unsigned int i=0; i<m_stitchFrames.GetCount(); i++) + { + try + { + process = OpenProcess(PROCESS_QUERY_INFORMATION,true,m_stitchFrames.Item(i)->GetProcessId()); + GetExitCodeProcess(process,&exitState); + } + catch(::exception e) + { + exitState=1; + } + if(exitState==STILL_ACTIVE) + exist=true; + else if(exitState!=0) + SetStatus(GetIndex(m_stitchFrames.Item(i)->GetProjectId()),Project::FAILED); + CloseHandle(process); + } + wxSleep(1); + } + #else //not __WXMSW__ + int status; + int pid; + for(unsigned int i=0; i<m_stitchFrames.GetCount(); i++) + { + pid = m_stitchFrames.Item(i)->GetProcessId(); + if(waitpid(pid,&status,0)==-1) + SetStatus(GetIndex(m_stitchFrames.Item(i)->GetProjectId()),Project::FAILED); //we set to failed if waitpid terminated with an error + if(!WIFEXITED(status) || WEXITSTATUS(status)!=0) + SetStatus(GetIndex(m_stitchFrames.Item(i)->GetProjectId()),Project::FAILED); //we set to failed if child terminated abnormally or with a bad exit code + } + #endif + + wxProcessEvent event; + for(int i=m_stitchFrames.GetCount()-1; i>=0; i--) + { + event.SetId(m_stitchFrames.Item(i)->GetProjectId()); + if(GetStatus(GetIndex(m_stitchFrames.Item(i)->GetProjectId()))==Project::FAILED) + event.SetTimestamp(-1); //exit code cannot be set, so we fake it inside events timestamp + OnProcessTerminate(event); + } + return true; } -void Batch::SwapProject(int index) -{ - Project* proj = m_projList.Detach(index+1); - m_projList.Insert(proj,index); -} + int Batch::ClearBatch() { if(m_stitchFrames.GetCount()!=0) @@ -202,6 +273,123 @@ } } +bool Batch::CompareProjectsInLists(int stitchListIndex, int batchListIndex) +{ + return m_stitchFrames.Item(stitchListIndex)->GetProjectId() == m_projList.Item(batchListIndex).id; +} + +int Batch::GetFirstAvailable() +{ + unsigned int i = 0; + while(i<m_projList.Count()) + { + if(m_projList.Item(i).skip || m_projList.Item(i).status!=Project::WAITING) + { + i++; + } + else + { + break; + } + } + if((m_projList.Count() == 0) || (i == m_projList.Count())) + { + //frame->projListMutex->Unlock(); + return -1; + } + else + { + //frame->projListMutex->Unlock(); + return i; + } +} + +int Batch::GetIndex(int id) +{ + for(unsigned int i=0; i<m_projList.GetCount(); i++) + { + if(m_projList.Item(i).id==id) + return i; + } + return -1; +} + + +Project* Batch::GetProject(int index) +{ + return (Project*)&m_projList.Item(index); +} +int Batch::GetProjectCount() +{ + return m_projList.GetCount(); +} +int Batch::GetProjectCountByPath(wxString path) +{ + int count = 0; + for(unsigned int i=0; i<m_projList.GetCount(); i++) + { + if(!m_projList.Item(i).skip && (path.Cmp(m_projList.Item(i).path)==0)) + count++; + } + return count; +} + + +int Batch::GetRunningCount() +{ + /*int count = 0; + for(unsigned int i = 0; i<m_projList.GetCount(); i++) + { + if(m_projList.Item(i).status == Project::RUNNING) + count++; + } + return count;*/ + return m_stitchFrames.GetCount(); +} + +Project::Status Batch::GetStatus(int index) +{ + if((unsigned int)index<m_projList.GetCount()) + return m_projList.Item(index).status; + else if(gui) + wxMessageBox( _T("Error: Could not get status, project with index ")+wxString::Format(_("%d"),index)+_T(" is not in list."),_T("Error!"),wxOK | wxICON_INFORMATION ); + else if(verbose) + cout << "Error: Could not get status, project with index " << index << " is not in list." << endl; + return Project::MISSING; +} +bool Batch::IsPaused() +{ + return m_paused; +} + +void Batch::ListBatch() +{ + if(m_projList.GetCount() == 0) + cout << "Batch is empty." << endl; + else + { + cout << "List of projects in batch:" << endl << + "[ID] [project path] [output filename] [status]" << endl << + "-------------------------------------" << endl; + for(unsigned int i=0; i<m_projList.GetCount(); i++) + { + cout << m_projList.Item(i).id << " " << m_projList.Item(i).path.char_str() << " " << m_projList.Item(i).prefix.char_str() << " " << m_projList.Item(i).GetStatusText().char_str() << endl; + } + } +} + + +void Batch::LoadBatchFile(wxString file) +{ + if(ClearBatch()==0) + AppendBatchFile(file); + else if(gui) + wxMessageBox(_T("Error: Could not load batch file.")); + else if(verbose) + cout << "Error: Could not load batch file." << endl; +} + + int Batch::LoadTemp() { wxDir* workingDir = new wxDir(wxFileName::GetTempDir()); @@ -237,102 +425,141 @@ } //we load the data from the temp file AppendBatchFile(workingDir->GetName()+wxFileName::GetPathSeparator()+temp); + if(verbose && !gui) + cout << "Loaded temp file." << endl; return 0; } -void Batch::SaveTemp() -{ - //wxMessageBox( _T("saving temp file"),_T(""),wxOK | wxICON_INFORMATION ); - wxDir* workingDir = new wxDir(wxFileName::GetTempDir()); - wxString fileTemp = _T("~ptbt*"); - //we get the old temp file - fileTemp = workingDir->FindFirst(workingDir->GetName(),fileTemp,wxDIR_FILES); - wxFileName oldFile(fileTemp); - //we alternate between 0 and 1 - wxString suffix; - if(fileTemp.EndsWith(_T("0"))) - suffix = _T("1"); - else - suffix = _T("0"); - SaveBatchFile(wxFileName::GetTempDir()+wxFileName::GetPathSeparator()+_T("~ptbt")+suffix); - //we remove the previous temp file - if(oldFile.FileExists()) - wxRemoveFile(fileTemp); -} -void Batch::LoadBatchFile(wxString file) +bool Batch::NoErrors() { - if(ClearBatch()==0) - AppendBatchFile(file); - else if(gui) - wxMessageBox(_T("Error: Could not load batch file.")); - else if(verbose) - cout << "Error: Could not load batch file." << endl; -} - -void Batch::AppendBatchFile(wxString file) -{ - if(wxFileName::FileExists(file)) + for(unsigned int i=0; i<m_projList.GetCount(); i++) { - wxFileInputStream fileStream(file); - wxString projectName = _T(""); - wxTextInputStream textStream(fileStream); - - //TO-DO: batch file error checking? - //first line in file is idGenerator - long idGen = 1; - textStream.ReadLine().ToLong(&idGen); - //then for each project: project path, prefix, id, status, skip - while((projectName = textStream.ReadLine()).Cmp(_(""))!=0) + if(m_projList.Item(i).status==Project::FAILED) { - //we add project to internal list - AddProjectToBatch(projectName); - m_projList.Last().prefix = textStream.ReadLine(); - textStream.ReadLine().ToLong(&m_projList.Last().id); - long status; - textStream.ReadLine().ToLong(&status); - //if status was RUNNING or PAUSED, we set it to FAILED - if(status==(long)Project::RUNNING || status==(long)Project::PAUSED) - status=(long)Project::FAILED; - //if(status==2 || status==5) - // status=3; - m_projList.Last().status = (Project::Status)status; - if(textStream.ReadLine().StartsWith(_T("T"))) - m_projList.Last().skip = true; - //after setting all values, we add project to the GUI list box - //wxGetApp().frame->projListBox->AppendProject(&wxGetApp().m_projList.Last()); + return false; } - //we store the id generator - Project::idGenerator = idGen; } + return true; } -void Batch::SaveBatchFile(wxString file) +void Batch::OnProcessTerminate(wxProcessEvent & event) { - wxFileOutputStream fileStream(file); - wxTextOutputStream textStream(fileStream); - //we write current idGenerator to file - wxString line = _T(""); - line << Project::idGenerator; - textStream.WriteString(line+_T("\n")); - //then for each project: project path, prefix, id, status, skip - for(unsigned int i = 0; i< m_projList.GetCount(); i++) + //we find the right pointer to remove + unsigned int i = 0; + while(i < m_stitchFrames.GetCount() && + m_stitchFrames.Item(i)->GetProjectId()!=event.GetId()) { - textStream.WriteString(m_projList.Item(i).path+_T("\n")); - textStream.WriteString(m_projList.Item(i).prefix+_T("\n")); - line = _T(""); - line << m_projList.Item(i).id; - textStream.WriteString(line+_T("\n")); - line = _T(""); - line << m_projList.Item(i).status; - textStream.WriteString(line+_T("\n")); - if(m_projList.Item(i).skip) - textStream.WriteString(_T("T\n")); + i++; + } + m_stitchFrames.RemoveAt(i); + if(m_stitchFrames.GetCount()==0) + m_paused = false; + i = GetIndex(event.GetId()); + if (event.GetExitCode() != 0 || event.GetTimestamp()==-1) //timestamp is used as a fake exit code because it cannot be set manually + m_projList.Item(i).status=Project::FAILED; + else + m_projList.Item(i).status=Project::FINISHED; + if(!m_cancelled && !m_paused) + { + if(AllDone()) + { + m_running = false; + if(NoErrors()) + { + if(gui) + //SetStatusText(_T("Project \"")+m_projList.Item(i).path+_T("\" finished. Batch successfully completed.")); + SetStatusText(_T("Batch successfully completed.")); + else + //cout << "Project \"" << m_projList.Item(i).path.char_str() << "\" finished. Batch successfully completed." << endl; + cout << "Batch successfully completed." << endl; + } + else + { + if(gui) + //SetStatusText(_T("Project \""+m_projList.Item(i).path)+_T("\" finished. Batch completed with errors.")); + SetStatusText(_T("Batch completed with errors.")); + else + //cout << "Project \"" << m_projList.Item(i).path.char_str() << "\" finished. Batch completed with errors." << endl; + cout << "Batch completed with errors." << endl; + } + if(shutdown) //after we are finished we turn off the computer if checked + { + if(gui) + { + wxProgressDialog progress(_("Initializing shutdown..."), _T("Shutting down..."),49,m_parentFrame, + wxPD_AUTO_HIDE | wxPD_SMOOTH | wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_CAN_SKIP); + progress.Fit(); + int i = 0; + bool skip = false; + while(progress.Update(i, _T("Shutting down..."),&skip)) + { + if(skip || i==50) + { + /*wxMessageDialog message(this,_T("Krneksa")); + message.ShowModal(); + break;*/ + wxShutdown(wxSHUTDOWN_POWEROFF); + } + i++; + #if defined __WXMSW__ + Sleep(200); + #else + sleep(200); + #endif + } + progress.Close(); + } + else + { + if(!wxShutdown(wxSHUTDOWN_POWEROFF)) + { + if(gui) + #ifdef __WXMSW__ + wxMessageBox(_T("Error shutting down.")); + #else + wxMessageBox(_T("Error shutting down. Do you have root privileges?")); + #endif + else + #ifdef __WXMSW__ + cout << "Error shutting down." << endl; + #else + cout << "Error shutting down. Do you have root privileges?" << endl; + #endif + } + } + } + } else - textStream.WriteString(_T("F\n")); + { + if(parallel) //if we are running in parallel + { + //the last executed process in parallel runs next + if(GetRunningCount() == 0) + { + //SetStatusText(_T("Project \""+m_projList.Item(i).path)+_T("\" finished. Running next project...")); + RunNextInBatch(); + } + else + { + //SetStatusText(_T("Project \""+m_projList.Item(i).path)+_T("\" finished. Waiting for all in parallel to complete...")); + } + } + else + { + //SetStatusText(_T("Project \""+m_projList.Item(i).path)+_T("\" finished. Running next project...")); + RunNextInBatch(); + } + } } - fileStream.Close(); + else + { //after all processes have ended on a cancel, we reset the boolean back to false + //if(stitchFrames.GetCount()==0) + if(GetRunningCount()==0) + { + m_cancelled=false; + } + } } - bool Batch::OnStitch(wxString scriptFile, wxString outname, int id) //was previously without parameter { //if( parser.GetParamCount() == 0 && wxIsEmpty(scriptFile)) @@ -371,7 +598,7 @@ } if(verbose && !gui) - cout << "Starting stitch with input file " << (const char *)scriptFile.mb_str(wxConvLocal) << endl; + cout << "Stitching with input file " << (const char *)scriptFile.mb_str(wxConvLocal) << "..." << endl; // check output filename wxFileName outfn(outname); @@ -389,8 +616,11 @@ RunStitchFrame *stitchFrame = new RunStitchFrame(this, wxT("Hugin Stitcher"), wxDefaultPosition, wxSize(640,600)); //,wxGetApp().m_projList, projListBox ); //stitchFrame->SetEventHandler(this); stitchFrame->SetProjectId(id); - stitchFrame->Show( true ); - wxTheApp->SetTopWindow( stitchFrame ); + if(verbose && gui) + { + stitchFrame->Show( true ); + wxTheApp->SetTopWindow( stitchFrame ); + } wxFileName basename(scriptFile); stitchFrame->SetTitle(wxString::Format(_("%s - Stitching"), basename.GetName().c_str())); @@ -408,110 +638,76 @@ } -/*Returns the index of the first project that isn't marked to be skipped. If such a project does not exist, the function returns -1.*/ -int Batch::GetFirstAvailable() + + + +void Batch::PauseBatch() { - /*while(frame->projListMutex->TryLock()==wxMUTEX_BUSY) - {}*/ - unsigned int i = 0; - while(i<m_projList.Count()) + if(!m_paused) { - if(m_projList.Item(i).skip || m_projList.Item(i).status!=Project::WAITING) + m_paused = true; + for(int i=0; i<GetRunningCount(); i++) { - i++; + m_stitchFrames.Item(i)->m_stitchPanel->PauseStitch(); } - else + for(unsigned int i=0; i<m_projList.GetCount(); i++) { - break; + if(m_projList.Item(i).status==Project::RUNNING) + m_projList.Item(i).status=Project::PAUSED; } } - if((m_projList.Count() == 0) || (i == m_projList.Count())) - { - //frame->projListMutex->Unlock(); - return -1; - } else { - //frame->projListMutex->Unlock(); - return i; - } -} - -int Batch::GetProjectCount() -{ - return m_projList.GetCount(); -} -int Batch::GetRunningCount() -{ - /*int count = 0; - for(unsigned int i = 0; i<m_projList.GetCount(); i++) - { - if(m_projList.Item(i).status == Project::RUNNING) - count++; - } - return count;*/ - return m_stitchFrames.GetCount(); -} -int Batch::GetIndex(int id) -{ - for(unsigned int i=0; i<m_projList.GetCount(); i++) - { - if(m_projList.Item(i).id==id) - return i; - } - return -1; -} - -bool Batch::AllDone() -{ - for(unsigned int i=0; i<m_projList.GetCount(); i++) - { - if(m_projList.Item(i).status==Project::WAITING || - m_projList.Item(i).status==Project::RUNNING || - m_projList.Item(i).status==Project::PAUSED) + m_paused = false; + for(int i=0; i<GetRunningCount(); i++) { - return false; + m_stitchFrames.Item(i)->m_stitchPanel->ContinueStitch(); } + for(unsigned int i=0; i<m_projList.GetCount(); i++) + { + if(m_projList.Item(i).status==Project::PAUSED) + m_projList.Item(i).status=Project::RUNNING; + } } - return true; } -bool Batch::IsPaused() -{ - return m_paused; -} -bool Batch::NoErrors() -{ - for(unsigned int i=0; i<m_projList.GetCount(); i++) - { - if(m_projList.Item(i).status==Project::FAILED) - { - return false; +void Batch::RemoveProject(int id) +{ + int index; + if((index=GetIndex(id)) != -1) + { + RemoveProjectAtIndex(GetIndex(id)); + } + else if(gui) + wxMessageBox( _T("Error removing, project with id ")+wxString::Format(_T("%d"),id)+_T(" is not in list."),_T("Error!"),wxOK | wxICON_INFORMATION ); + else if(verbose) + cout << "Error: Project with id " << id << " is not in list." << endl; +} +void Batch::RemoveProjectAtIndex(int selIndex) +{ + //we delete only successful project files and no applications + if(deleteFiles + && m_projList.Item(selIndex).id>=0 + && m_projList.Item(selIndex).status==Project::FINISHED) + { + wxFileName file(m_projList.Item(selIndex).path); + if(file.FileExists()) + { + if(!wxRemoveFile(file.GetFullPath())) + { + if(gui) + wxMessageBox( _T("Error: Could not delete project file ")+file.GetFullPath(),_T("Error!"),wxOK | wxICON_INFORMATION ); + else if(verbose) + cout << "Error: Could not delete project file " << file.GetFullPath().char_str() << endl; + } } } - return true; + m_projList.RemoveAt(selIndex); + if(m_projList.GetCount()==0) //reset the id generator on empty list + Project::idGenerator=1; } - -int Batch::GetProjectCountByPath(wxString path) -{ - int count = 0; - for(unsigned int i=0; i<m_projList.GetCount(); i++) - { - if(!m_projList.Item(i).skip && (path.Cmp(m_projList.Item(i).path)==0)) - count++; - } - return count; -} - -bool Batch::CompareProjectsInLists(int stitchListIndex, int batchListIndex) -{ - return m_stitchFrames.Item(stitchListIndex)->GetProjectId() == m_projList.Item(batchListIndex).id; -} -Project* Batch::GetProject(int index) -{ - return (Project*)&m_projList.Item(index); -} + void Batch::RunBatch() { if(!m_running) @@ -551,51 +747,6 @@ } } -void Batch::PauseBatch() -{ - if(!m_paused) - { - m_paused = true; - for(int i=0; i<GetRunningCount(); i++) - { - m_stitchFrames.Item(i)->m_stitchPanel->PauseStitch(); - } - for(unsigned int i=0; i<m_projList.GetCount(); i++) - { - if(m_projList.Item(i).status==Project::RUNNING) - m_projList.Item(i).status=Project::PAUSED; - } - } - else - { - m_paused = false; - for(int i=0; i<GetRunningCount(); i++) - { - m_stitchFrames.Item(i)->m_stitchPanel->ContinueStitch(); - } - for(unsigned int i=0; i<m_projList.GetCount(); i++) - { - if(m_projList.Item(i).status==Project::PAUSED) - m_projList.Item(i).status=Project::RUNNING; - } - } -} -void Batch::CancelProject(int index) -{ - wxCommandEvent event; - m_stitchFrames.Item(index)->OnQuit(event); - m_paused = false; - if(GetRunningCount()==0) - m_running = false; -} -void Batch::CancelBatch() -{ - m_cancelled = true; - for(int i=0; i<GetRunningCount(); i++) - CancelProject(i); - m_running = false; -} -/*Runs next non-skipped project in batch list.*/ void Batch::RunNextInBatch() { //((wxToolBar*)FindWindow(TOOLBAR))->ToggleTool(TOOLPAUSE,false); @@ -671,174 +822,69 @@ CheckProjectExistence(); } -bool Batch::CheckProjectExistence() +void Batch::SaveBatchFile(wxString file) { - #ifdef __WXMSW__ - bool exist = true; - HANDLE process; - DWORD exitState; - while(exist) + wxFileOutputStream fileStream(file); + wxTextOutputStream textStream(fileStream); + //we write current idGenerator to file + wxString line = _T(""); + line << Project::idGenerator; + textStream.WriteString(line+_T("\n")); + //then for each project: project path, prefix, id, status, skip + for(unsigned int i = 0; i< m_projList.GetCount(); i++) { - exist = false; - - for(unsigned int i=0; i<m_stitchFrames.GetCount(); i++) - { - try - { - process = OpenProcess(PROCESS_QUERY_INFORMATION,true,m_stitchFrames.Item(i)->GetProcessId()); - GetExitCodeProcess(process,&exitState); - } - catch(::exception e) - { - exitState=1; - } - if(exitState==STILL_ACTIVE) - exist=true; - else if(exitState!=0) - SetStatus(GetIndex(m_stitchFrames.Item(i)->GetProjectId()),Project::FAILED); - CloseHandle(process); - } - wxSleep(1); + textStream.WriteString(m_projList.Item(i).path+_T("\n")); + textStream.WriteString(m_projList.Item(i).prefix+_T("\n")); + line = _T(""); + line << m_projList.Item(i).id; + textStream.WriteString(line+_T("\n")); + line = _T(""); + line << m_projList.Item(i).status; + textStream.WriteString(line+_T("\n")); + if(m_projList.Item(i).skip) + textStream.WriteString(_T("T\n")); + else + textStream.WriteString(_T("F\n")); } - #else //not __WXMSW__ - int status; - int pid; - for(unsigned int i=0; i<m_stitchFrames.GetCount(); i++) - { - pid = m_stitchFrames.Item(i)->GetProcessId(); - if(waitpid(pid,&status,0)==-1) - SetStatus(GetIndex(m_stitchFrames.Item(i)->GetProjectId()),Project::FAILED); //we set to failed if waitpid terminated with an error - if(!WIFEXITED(status) || WEXITSTATUS(status)!=0) - SetStatus(GetIndex(m_stitchFrames.Item(i)->GetProjectId()),Project::FAILED); //we set to failed if child terminated abnormally or with a bad exit code - } - #endif + fileStream.Close(); +} - wxProcessEvent event; - for(int i=m_stitchFrames.GetCount()-1; i>=0; i--) - { - event.SetId(m_stitchFrames.Item(i)->GetProjectId()); - if(GetStatus(GetIndex(m_stitchFrames.Item(i)->GetProjectId()))==Project::FAILED) - event.SetTimestamp(-1); //exit code cannot be set, so we fake it inside events timestamp - OnProcessTerminate(event); - } - return true; +void Batch::SaveTemp() +{ + //wxMessageBox( _T("saving temp file"),_T(""),wxOK | wxICON_INFORMATION ); + wxDir* workingDir = new wxDir(wxFileName::GetTempDir()); + wxString fileTemp = _T("~ptbt*"); + //we get the old temp file + fileTemp = workingDir->FindFirst(workingDir->GetName(),fileTemp,wxDIR_FILES); + wxFileName oldFile(fileTemp); + //we alternate between 0 and 1 + wxString suffix; + if(fileTemp.EndsWith(_T("0"))) + suffix = _T("1"); + else + suffix = _T("0"); + SaveBatchFile(wxFileName::GetTempDir()+wxFileName::GetPathSeparator()+_T("~ptbt")+suffix); + if(verbose && !gui) + cout << "Saved temp file." << endl; + //we remove the previous temp file + if(oldFile.FileExists()) + wxRemoveFile(fileTemp); } -void Batch::OnProcessTerminate(wxProcessEvent & event) + +void Batch::SetStatus(int index,Project::Status status) { - //we find the right pointer to remove - unsigned int i = 0; - while(i < m_stitchFrames.GetCount() && - m_stitchFrames.Item(i)->GetProjectId()!=event.GetId()) - { - i++; - } - m_stitchFrames.RemoveAt(i); - if(m_stitchFrames.GetCount()==0) - m_paused = false; - i = GetIndex(event.GetId()); - if (event.GetExitCode() != 0 || event.GetTimestamp()==-1) //timestamp is used as a fake exit code because it cannot be set manually - m_projList.Item(i).status=Project::FAILED; - else - m_projList.Item(i).status=Project::FINISHED; - if(!m_cancelled && !m_paused) - { - if(AllDone()) - { - m_running = false; - if(NoErrors()) - { - if(gui) - //SetStatusText(_T("Project \"")+m_projList.Item(i).path+_T("\" finished. Batch successfully completed.")); - SetStatusText(_T("Batch successfully completed.")); - else - //cout << "Project \"" << m_projList.Item(i).path.char_str() << "\" finished. Batch successfully completed." << endl; - cout << "Batch successfully completed." << endl; - } - else - { - if(gui) - //SetStatusText(_T("Project \""+m_projList.Item(i).path)+_T("\" finished. Batch completed with errors.")); - SetStatusText(_T("Batch completed with errors.")); - else - //cout << "Project \"" << m_projList.Item(i).path.char_str() << "\" finished. Batch completed with errors." << endl; - cout << "Batch completed with errors." << endl; - } - if(shutdown) //after we are finished we turn off the computer if checked - { - if(gui) - { - wxProgressDialog progress(_("Initializing shutdown..."), _T("Shutting down..."),49,m_parentFrame, - wxPD_AUTO_HIDE | wxPD_SMOOTH | wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_CAN_SKIP); - progress.Fit(); - int i = 0; - bool skip = false; - while(progress.Update(i, _T("Shutting down..."),&skip)) - { - if(skip || i==50) - { - /*wxMessageDialog message(this,_T("Krneksa")); - message.ShowModal(); - break;*/ - wxShutdown(wxSHUTDOWN_POWEROFF); - } - i++; - #if defined __WXMSW__ - Sleep(200); - #else - sleep(200); - #endif - } - progress.Close(); - } - else - { - if(!wxShutdown(wxSHUTDOWN_POWEROFF)) - { - if(gui) - #ifdef __WXMSW__ - wxMessageBox(_T("Error shutting down.")); - #else - wxMessageBox(_T("Error shutting down. Do you have root privileges?")); - #endif - else - #ifdef __WXMSW__ - cout << "Error shutting down." << endl; - #else - cout << "Error shutting down. Do you have root privileges?" << endl; - #endif - } - } - } - } - else - { - if(parallel) //if we are running in parallel - { - //the last executed process in parallel runs next - if(GetRunningCount() == 0) - { - //SetStatusText(_T("Project \""+m_projList.Item(i).path)+_T("\" finished. Running next project...")); - RunNextInBatch(); - } - else - { - //SetStatusText(_T("Project \""+m_projList.Item(i).path)+_T("\" finished. Waiting for all in parallel to complete...")); - } - } - else - { - //SetStatusText(_T("Project \""+m_projList.Item(i).path)+_T("\" finished. Running next project...")); - RunNextInBatch(); - } - } - } - else - { //after all processes have ended on a cancel, we reset the boolean back to false - //if(stitchFrames.GetCount()==0) - if(GetRunningCount()==0) - { - m_cancelled=false; - } - } -} \ No newline at end of file + if((unsigned int)index<m_projList.GetCount()) + m_projList.Item(index).status = status; + else if(gui) + wxMessageBox( _T("Error: Could not set status, project with index ")+wxString::Format(_("%d"),index)+_T(" is not in list."),_T("Error!"),wxOK | wxICON_INFORMATION ); + else if(verbose) + cout << "Error: Could not set status, project with index " << index << " is not in list." << endl; +} +void Batch::SwapProject(int index) +{ + Project* proj = m_projList.Detach(index+1); + m_projList.Insert(proj,index); +} + + Modified: hugin/branches/gsoc2008_batch_processing/src/PTBatcher/Batch.h =================================================================== --- hugin/branches/gsoc2008_batch_processing/src/PTBatcher/Batch.h 2008-08-15 22:27:21 UTC (rev 3323) +++ hugin/branches/gsoc2008_batch_processing/src/PTBatcher/Batch.h 2008-08-16 03:27:33 UTC (rev 3324) @@ -1,3 +1,29 @@ +// -*- c-basic-offset: 4 -*- + +/** @file Batch.h + * + * @brief Batch processor for Hugin + * + * @author Marko Kuder <mar...@gm...> + * + * $Id: Batch.h 3322 2008-08-16 5:00:07Z mkuder $ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + #ifndef BATCH_H #define BATCH_H @@ -26,60 +52,87 @@ bool verbose; bool gui; + //Main constructor Batch(wxFrame* parent, wxString path, bool bgui); - //virtual bool OnInit(); - //methods used for command line execution: - void ListBatch(); - - //void AddProject(Project proj); - void AddProjectToBatch(wxString projectFile, wxString outputFile); - bool AddProjectToBatch(wxString projectFile); - void AddAppToBatch(wxString app); - void RemoveProject(int id); - void RemoveProjectAtIndex(int selIndex); - void ChangePrefix(int index, wxString newPrefix); + //Adds an application entry in the batch list + void AddAppToBatch(wxString app); + //Adds a project entry in the batch list + void AddProjectToBatch(wxString projectFile, wxString outputFile = _T("")); + //Returns true if there are no more projects pending execution + bool AllDone(); + //Appends projects from file to batch list + void AppendBatchFile(wxString file); + //Stops batch run, failing projects in progress + void CancelBatch(); + //Cancels project at index in batch, failing it + void CancelProject(int index); + //Changes output prefix for project at index + void ChangePrefix(int index, wxString newPrefix); + //Called internally in console mode. Waits for running projects to complete and then runs next in batch + bool CheckProjectExistence(); + //Clears batch list and returns 0 if succesful + int ClearBatch(); + //Compares two project at indexes in both lists and returns true if they have identical project ids + bool CompareProjectsInLists(int stitchListIndex, int batchListIndex); + //Returns index of first waiting project in batch + int GetFirstAvailable(); + //Returns index of project with selected id + int GetIndex(int id); + //Returns project at index + Project* GetProject(int index); + //Returns number of projects in batch list + int GetProjectCount(); + //Returns number of projects in batch list with the input file path + int GetProjectCountByPath(wxString path); + //Returns number of projects currently in progress + int GetRunningCount(); + //Returns current status of project at index Project::Status GetStatus(int index); - void SetStatus(int index,Project::Status status); - void SwapProject(int index); + //Returns true if batch execution is currently paused + bool IsPaused(); + //Used in console mode. Prints out all projects and their statuses to the console + void ListBatch(); + //Clears current batch list and loads projects from batch file + void LoadBatchFile(wxString file); + //Loads temporary batch file + int LoadTemp(); + //Returns true if there are no failed projects in batch + bool NoErrors(); + //Called internally when all running processes have completed and need to be removed from running list + void OnProcessTerminate(wxProcessEvent & event); + //Called to start stitch of project with input scriptFile + bool OnStitch(wxString scriptFile, wxString outname, int id); + //Pauses and continues batch execution + void PauseBatch(); + //Removes project with id from batch list + void RemoveProject(int id); + //Removes project at index from batch list + void RemoveProjectAtIndex(int selIndex); + //Starts batch execution + void RunBatch(); + //Starts execution of next waiting project in batch + void RunNextInBatch(); + //Saves batch list to file + void SaveBatchFile(wxString file); + //Saves batch list to temporary file + void SaveTemp(); + //Used internally to set status of selected project + void SetStatus(int index,Project::Status status); + //Swaps position in batch of project at index with project at index+1 + void SwapProject(int index); - int ClearBatch(); - int LoadTemp(); - void SaveTemp(); - void LoadBatchFile(wxString file); - void AppendBatchFile(wxString file); - void SaveBatchFile(wxString file); - - bool OnStitch(wxString scriptFile, wxString outname, int id); - int GetFirstAvailable(); - int GetIndex(int id); - int GetProjectCount(); - int GetRunningCount(); - bool AllDone(); - bool IsPaused(); - bool NoErrors(); - int GetProjectCountByPath(wxString path); - bool CompareProjectsInLists(int stitchListIndex, int batchListIndex); - Project* GetProject(int index); - - void RunBatch(); - void PauseBatch(); - void CancelProject(int index); - void CancelBatch(); - void RunNextInBatch(); - bool CheckProjectExistence(); - void Batch::OnProcessTerminate(wxProcessEvent & event); - private: wxConfigBase* m_config; - wxLocale m_locale; - wxFrame* m_parentFrame; + wxLocale m_locale; + wxFrame* m_parentFrame; + ProjectArray m_projList; + FrameArray m_stitchFrames; + bool m_cancelled; bool m_paused; bool m_running; - - ProjectArray m_projList; - FrameArray m_stitchFrames; + PTPrograms progs; DECLARE_EVENT_TABLE() Modified: hugin/branches/gsoc2008_batch_processing/src/PTBatcher/CMakeLists.txt =================================================================== --- hugin/branches/gsoc2008_batch_processing/src/PTBatcher/CMakeLists.txt 2008-08-15 22:27:21 UTC (rev 3323) +++ hugin/branches/gsoc2008_batch_processing/src/PTBatcher/CMakeLists.txt 2008-08-16 03:27:33 UTC (rev 3324) @@ -2,7 +2,7 @@ set( PROGNAME PTBatcher ) -add_executable(PTBatcher PTBatcher.cpp PTBatcher.h PTBatcher_rc.rc Batch.cpp Batch.h RunStitchFrame.cpp RunStitchFrame.h ProjectArray.cpp ProjectArray.h ProjectListBox.cpp ProjectListBox.h DirTraverser.h HostApp.h) +add_executable(PTBatcher PTBatcher.cpp PTBatcher.h PTBatcher_rc.rc Batch.cpp Batch.h RunStitchFrame.cpp RunStitchFrame.h ProjectArray.cpp ProjectArray.h) target_link_libraries(${PROGNAME} huginbasewx ${common_libs} ${image_libs} ${wxWidgets_LIBRARIES}) install(TARGETS PTBatcher DESTINATION ${BINDIR}) \ No newline at end of file Deleted: hugin/branches/gsoc2008_batch_processing/src/PTBatcher/DirTraverser.h =================================================================== --- hugin/branches/gsoc2008_batch_processing/src/PTBatcher/DirTraverser.h 2008-08-15 22:27:21 UTC (rev 3323) +++ hugin/branches/gsoc2008_batch_processing/src/PTBatcher/DirTraverser.h 2008-08-16 03:27:33 UTC (rev 3324) @@ -1,35 +0,0 @@ -#include <wx/dir.h> -#include <wx/filename.h> -#include <wx/msgdlg.h> - -class DirTraverser : public wxDirTraverser -{ -public: - DirTraverser():wxDirTraverser(){ } - - virtual wxDirTraverseResult OnFile(const wxString& file) - { - wxFileName fileName(file); - wxString ext = fileName.GetExt(); - //we add all project files to array - if (ext.CmpNoCase(wxT("pto")) == 0 || ext.CmpNoCase(wxT("ptp")) == 0|| - ext.CmpNoCase(wxT("pts")) == 0|| ext.CmpNoCase(wxT("oto")) == 0) - projectFiles.Add(file); - - //TO-DO: include image file heuristics to detect potential projects - return wxDIR_CONTINUE; - } - - virtual wxDirTraverseResult OnDir(const wxString& WXUNUSED(dir)) - { - return wxDIR_CONTINUE; - } - - wxArrayString GetProjectFiles() - { - return projectFiles; - } -private: - wxArrayString projectFiles; -}; - Deleted: hugin/branches/gsoc2008_batch_processing/src/PTBatcher/HostApp.h =================================================================== --- hugin/branches/gsoc2008_batch_processing/src/PTBatcher/HostApp.h 2008-08-15 22:27:21 UTC (rev 3323) +++ hugin/branches/gsoc2008_batch_processing/src/PTBatcher/HostApp.h 2008-08-16 03:27:33 UTC (rev 3324) @@ -1,20 +0,0 @@ -#include "Batch.h" - -class HostApp : public wxApp -{ -public: - virtual bool OnInit() - { - return true; - }; - void InitBatch(wxString path){ - batch = new Batch(NULL,path,false); - }; - Batch* batch; -}; - -IMPLEMENT_APP(HostApp) - -//BEGIN_EVENT_TABLE(HostApp, wxApp) - //EVT_END_PROCESS(-1, HostApp::OnProcessTerminate) -//END_EVENT_TABLE() \ No newline at end of file Modified: hugin/branches/gsoc2008_batch_processing/src/PTBatcher/PTBatcher.cpp =================================================================== --- hugin/branches/gsoc2008_batch_processing/src/PTBatcher/PTBatcher.cpp 2008-08-15 22:27:21 UTC (rev 3323) +++ hugin/branches/gsoc2008_batch_processing/src/PTBatcher/PTBatcher.cpp 2008-08-16 03:27:33 UTC (rev 3324) @@ -1,53 +1,44 @@ -/*************************************************************************** - * Copyright (C) 2007 by Zoran Mesec * - * zor...@gm... * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -//#define USE_OPENCV -//#define USE_QT -/*#define USE_VIGRA +// -*- c-basic-offset: 4 -*- + +/** @file PTBatcher.cpp + * + * @brief Batch processor for Hugin + * + * @author Marko Kuder <mar...@gm...> + * + * $Id: PTBatcher.cpp 3322 2008-08-16 5:00:07Z mkuder $ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <iostream> -#include <stdlib.h> -#include <math.h> -#include <ctime> -#include <algorithm>*/ - #include <string> #include "getopt.h" -//#include <limits> - #ifdef WIN32 #include <getopt.h> #else #include <unistd.h> #endif -#include "HostApp.h" +#include "PTBatcher.h" using namespace std; +//Prints out help text void usage() { cout << "PTBatcher: panotools batch stitcher" << endl @@ -73,9 +64,6 @@ int main(int argc, char *argv[]) { - //clock_t start,finish; - //double time; - //a character that defines the type of options //encountered, so only logical combinations are used char type = 'n'; @@ -83,11 +71,10 @@ bool optionError = false; bool prefix = false; - //Batch batch(NULL, wxString::FromAscii(argv[0])); - //batch.OnInit(); + //create application and batch objects HostApp app; app.InitBatch(wxString::FromAscii(argv[0])); - // parse arguments + //parse arguments const char * optstring = "haolxrbpdsvc"; char c; while ((c = getopt (argc, argv, optstring)) != -1) @@ -166,6 +153,10 @@ } app.batch->LoadTemp(); app.batch->AddProjectToBatch(wxString::FromAscii(input.c_str()),wxString::FromAscii(output.c_str())); + if(output == "") + cout << "Added project " << input << " with output " << output << endl; + else + cout << "Added project " << input << endl; app.batch->SaveTemp(); } else if(type == 'l') @@ -232,7 +223,6 @@ #endif } app.batch->SaveTemp(); - //app.batch->SaveTemp(); } return EXIT_SUCCESS; Modified: hugin/branches/gsoc2008_batch_processing/src/PTBatcher/PTBatcher.h =================================================================== --- hugin/branches/gsoc2008_batch_processing/src/PTBatcher/PTBatcher.h 2008-08-15 22:27:21 UTC (rev 3323) +++ hugin/branches/gsoc2008_batch_processing/src/PTBatcher/PTBatcher.h 2008-08-16 03:27:33 UTC (rev 3324) @@ -1,148 +1,45 @@ -//#include <hugin_config.h> -//#include <hugin_version.h> -//#include "panoinc_WX.h" -//#include "panoinc.h" +// -*- c-basic-offset: 4 -*- -//#include <wx/wfstream.h> - - -//#include <fstream> -//#include <sstream> -//#include <vigra/error.hxx> -//#include <vigra_ext/MultiThreadOperations.h> -//#include "PT/Panorama.h" -//#include "PT/utils.h" -//#include "base_wx/RunStitchPanel.h" -//#include "base_wx/huginConfig.h" -//#include "base_wx/MyProgressDialog.h" -//#include "base_wx/MyExternalCmdExecDialog.h" -//#include "base_wx/platform.h" -//#include "common/wxPlatform.h" - - -#include "RunStitchFrame.h" -//#include "FilePoller.h" -//#include "ProjectArray.h" -#include "ProjectListBox.h" -#include <wx/dir.h> -#include <wx/wfstream.h> -#include <wx/filefn.h> - -class BatchFrame : public wxFrame, wxThreadHelper -{ -public: - //old listBox implementation, if new one fails to build - //wxListBox *projListBox; - ProjectListBox *projListBox; - BatchFrame(const wxString& title); - void OnButtonAddToList(wxCommandEvent &event); - void OnButtonAddCommand(wxCommandEvent &event); - void OnButtonRemoveFromList(wxCommandEvent &event); - void OnButtonRemoveComplete(wxCommandEvent &event); - void OnButtonClear(wxCommandEvent &event); - void OnButtonChangePrefix(wxCommandEvent &event); - void OnButtonRunBatch(wxCommandEvent &event); - void OnButtonReset(wxCommandEvent &event); - void OnButtonResetAll(wxCommandEvent &event); - void OnButtonOpenWithHugin(wxCommandEvent &event); - void OnButtonMoveUp(wxCommandEvent &event); - void OnButtonMoveDown(wxCommandEvent &event); - void OnButtonPause(wxCommandEvent &event); - void OnButtonSkip(wxCommandEvent &event); - void OnButtonCancel(wxCommandEvent &event); - void OnButtonOpenBatch(wxCommandEvent &event); - void OnButtonSaveBatch(wxCommandEvent &event); - void OnButtonAddDir(wxCommandEvent &event); - void AddProjectsInDir(wxString dir); - void OnCheckParallel(wxCommandEvent &event); - void OnCheckDelete(wxCommandEvent &event); - void OnCheckShutdown(wxCommandEvent &event); - void OnCheckOverwrite(wxCommandEvent &event); - void RunBatch(); - - void RunNextInBatch(); - - int Execute(const wxString & cmd); - bool AddProjectToList(wxString projectFile, bool AppendToListBox = true); - void SwapProject(int index); - //PanoramaOptions readOptions(wxString projectFile); - //the polling thread function - void *Entry(); - //void OnKeyDown(wxKeyEvent &event); - - //temp - wxMutex* projListMutex; -private: - bool m_cancelled; - bool m_paused; - wxGauge* m_gauge; - void OnSizeChange(wxSizeEvent &event); - void OnProcessTerminate(wxProcessEvent & event); - DECLARE_EVENT_TABLE() - //PTPrograms progs; -}; - -//component IDs -const int BUTTONADD = 1; -const int BUTTONREMOVE = 2; -const int BUTTONRUN = 3; -const int PROJLISTBOX = 4; -const int MENUADD = 5; -const int STATUSBAR = 6; -const int CHECKPARALLEL = 7; -const int CHECKDELETE = 8; -const int BUTTONHUGIN = 9; -const int BUTTONUP = 10; -const int BUTTONDOWN = 11; -const int BUTTONCOMMAND = 12; -const int BUTTONPREFIX = 13; -const int BUTTONCOMPLETE = 14; -const int TOOLRUN = 15; -const int TOOLPAUSE = 16; -const int TOOLSKIP = 17; -const int TOOLCANCEL = 18; -const int TOOLBAR = 19; -const int TOOLADD = 20; -const int TOOLREMOVE = 21; -const int BUTTONRESET = 22; -const int BUTTONRESETALL = 23; -const int BUTTONCLEAR = 24; -const int CHECKSHUTDOWN = 25; -const int CHECKOVERWRITE = 26; -const int TOOLOPEN = 27; -const int TOOLSAVE = 28; -const int TOOLCLEAR = 29; -const int TOOLADDDIR = 30; - -BEGIN_EVENT_TABLE(BatchFrame, wxFrame) - EVT_TOOL(TOOLRUN,BatchFrame::OnButtonRunBatch) - EVT_TOOL(TOOLPAUSE,BatchFrame::OnButtonPause) - EVT_TOOL(TOOLSKIP,BatchFrame::OnButtonSkip) - EVT_TOOL(TOOLCANCEL,BatchFrame::OnButtonCancel) - EVT_TOOL(TOOLADD,BatchFrame::OnButtonAddToList) - EVT_TOOL(TOOLREMOVE,BatchFrame::OnButtonRemoveFromList) - EVT_TOOL(TOOLOPEN,BatchFrame::OnButtonOpenBatch) - EVT_TOOL(TOOLSAVE,BatchFrame::OnButtonSaveBatch) - EVT_TOOL(TOOLCLEAR,BatchFrame::OnButtonClear) - EVT_TOOL(TOOLADDDIR,BatchFrame::OnButtonAddDir) - EVT_BUTTON(BUTTONADD, BatchFrame::OnButtonAddToList) - EVT_BUTTON(BUTTONCOMMAND, BatchFrame::OnButtonAddCommand) - EVT_BUTTON(BUTTONREMOVE, BatchFrame::OnButtonRemoveFromList) - EVT_BUTTON(BUTTONCOMPLETE, BatchFrame::OnButtonRemoveComplete) - EVT_BUTTON(BUTTONCLEAR, BatchFrame::OnButtonClear) - EVT_BUTTON(BUTTONPREFIX, BatchFrame::OnButtonChangePrefix) - EVT_BUTTON(BUTTONRUN, BatchFrame::OnButtonRunBatch) - EVT_BUTTON(BUTTONRESET, BatchFrame::OnButtonReset) - EVT_BUTTON(BUTTONRESETALL, BatchFrame::OnButtonResetAll) - EVT_BUTTON(BUTTONHUGIN, BatchFrame::OnButtonOpenWithHugin) - EVT_BUTTON(BUTTONUP, BatchFrame::OnButtonMoveUp) - EVT_BUTTON(BUTTONDOWN, BatchFrame::OnButtonMoveDown) - EVT_MENU(MENUADD, BatchFrame::OnButtonAddToList) - EVT_CHECKBOX(CHECKPARALLEL, BatchFrame::OnCheckParallel) - EVT_CHECKBOX(CHECKDELETE, BatchFrame::OnCheckDelete) - EVT_CHECKBOX(CHECKSHUTDOWN, BatchFrame::OnCheckShutdown) - EVT_CHECKBOX(CHECKOVERWRITE, BatchFrame::OnCheckOverwrite) - EVT_SIZE(BatchFrame::OnSizeChange) - EVT_END_PROCESS(-1, BatchFrame::OnProcessTerminate) -END_EVENT_TABLE() - +/** @file PTBatcher.h + * + * @brief Batch processor for Hugin + * + * @author Marko Kuder <mar...@gm...> + * + * $Id: PTBatcher.h 3322 2008-08-16 5:00:07Z mkuder $ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "Batch.h" + +//Host application needed to use wxWidgets frame objects in console +class HostApp : public wxApp +{ +public: + //Pseudo constructor + virtual bool OnInit() + { + return true; + }; + //Initializes batch object + void InitBatch(wxString path){ + batch = new Batch(NULL,path,false); + }; + Batch* batch; +}; + +IMPLEMENT_APP(HostApp) \ No newline at end of file Modified: hugin/branches/gsoc2008_batch_processing/src/PTBatcher/ProjectArray.cpp =================================================================== --- hugin/branches/gsoc2008_batch_processing/src/PTBatcher/ProjectArray.cpp 2008-08-15 22:27:21 UTC (rev 3323) +++ hugin/branches/gsoc2008_batch_processing/src/PTBatcher/ProjectArray.cpp 2008-08-16 03:27:33 UTC (rev 3324) @@ -1,3 +1,29 @@ +// -*- c-basic-offset: 4 -*- + +/** @file ProjectArray.cpp + * + * @brief Batch processor for Hugin + * + * @author Marko Kuder <mar...@gm...> + * + * $Id: ProjectArray.cpp 3322 2008-08-16 5:00:07Z mkuder $ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + #include "ProjectArray.h" #include <wx/arrimpl.cpp> #include <fstream> @@ -7,7 +33,6 @@ long Project::idGenerator=1; -/*constructor for normal panorama project file*/ Project::Project(wxString pth,wxString pfx) { id = Project::idGenerator; @@ -17,12 +42,11 @@ wxFileName file(path); if(file.FileExists()) file.GetTimes(NULL,&modDate,NULL); - options = readOptions(pth); + options = ReadOptions(pth); skip = false; status = WAITING; } -/*constructor for command line instruction*/ Project::Project(wxString command) { path = command; @@ -32,8 +56,29 @@ status = WAITING; } -PanoramaOptions Project::readOptions(wxString projectFile) +wxString Project::GetStatusText() { + switch(status) + { + case WAITING: + return _T("Waiting"); + case RUNNING: + return _T("In progress"); + case FINISHED: + return _T("Complete"); + case FAILED: + return _T("Failed"); + case MISSING: + return _T("File missing"); + case PAUSED: + return _T("Paused"); + default: + return _T(""); + } +} + +PanoramaOptions Project::ReadOptions(wxString projectFile) +{ ifstream prjfile((const char *)projectFile.mb_str(HUGIN_CONV_FILENAME)); if (prjfile.bad()) { wxLogError( wxString::Format(_("could not open script : %s"), projectFile.c_str()) ); @@ -51,8 +96,8 @@ if (ptoVersion < 2) { HuginBase::PanoramaOptions opts = pano.getOptions(); //needed to access config data - wxConfig config(wxT("hugin")); - wxConfigBase::Set(&config); + wxConfig* config = new wxConfig(wxT("hugin")); + wxConfigBase::Set(config); // no options stored in file, use default arguments in config opts.enblendOptions = wxConfigBase::Get()->Read(wxT("/Enblend/Args"), wxT("")).mb_str(wxConvLocal); opts.enfuseOptions = wxConfigBase::Get()->Read(wxT("/Enfuse/Args"), wxT("")).mb_str(wxConvLocal); @@ -66,34 +111,15 @@ return opts; } -void Project::resetOptions() +void Project::ResetOptions() { wxFileName file(path); if(file.FileExists()) file.GetTimes(NULL,&modDate,NULL); - options = readOptions(path); + options = ReadOptions(path); } -wxString Project::GetStatusText() -{ - switch(status) - { - case WAITING: - return _T("Waiting"); - case RUNNING: - return _T("In progress"); - case FINISHED: - return _T("Complete"); - case FAILED: - return _T("Failed"); - case MISSING: - return _T("File missing"); - case PAUSED: - return _T("Paused"); - default: - return _T(""); - } -} + WX_DEFINE_OBJARRAY(ProjectArray); //define the array in ProjectArray.h Modified: hugin/branches/gsoc2008_batch_processing/src/PTBatcher/ProjectArray.h =================================================================== --- hugin/branches/gsoc2008_batch_processing/src/PTBatcher/ProjectArray.h 2008-08-15 22:27:21 UTC (rev 3323) +++ hugin/branches/gsoc2008_batch_processing/src/PTBatcher/ProjectArray.h 2008-08-16 03:27:33 UTC (rev 3324) @@ -1,3 +1,29 @@ +// -*- c-basic-offset: 4 -*- + +/** @file ProjectArray.h + * + * @brief Batch processor for Hugin + * + * @author Marko Kuder <mar...@gm...> + * + * $Id: ProjectArray.h 3322 2008-08-16 5:00:07Z mkuder $ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License,... [truncated message content] |