Batch.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00027 #include "Batch.h"
00028 #include <wx/stdpaths.h>
00029 #ifdef __WXMSW__
00030 #include <powrprof.h>
00031 #pragma comment(lib, "PowrProf.lib")
00032 #endif
00033 
00034 BEGIN_EVENT_TABLE(Batch, wxFrame)
00035     EVT_END_PROCESS(-1, Batch::OnProcessTerminate)
00036 END_EVENT_TABLE()
00037 
00038 #if defined _WIN32 && defined Hugin_shared
00039 DEFINE_LOCAL_EVENT_TYPE(EVT_BATCH_FAILED)
00040 DEFINE_LOCAL_EVENT_TYPE(EVT_INFORMATION)
00041 DEFINE_LOCAL_EVENT_TYPE(EVT_UPDATE_PARENT)
00042 #else
00043 DEFINE_EVENT_TYPE(EVT_BATCH_FAILED)
00044 DEFINE_EVENT_TYPE(EVT_INFORMATION)
00045 DEFINE_EVENT_TYPE(EVT_UPDATE_PARENT)
00046 #endif
00047 
00048 Batch::Batch(wxFrame* parent) : wxFrame(parent, wxID_ANY, _T("Batch"))
00049 {
00050     //default flag settings
00051     deleteFiles = false;
00052     atEnd = DO_NOTHING;
00053 #if wxCHECK_VERSION(3,1,0)
00054     m_resBlocker = NULL;
00055 #endif
00056     overwrite = true;
00057     verbose = false;
00058     autoremove = false;
00059     autostitch = false;
00060     saveLog = false;
00061     m_cancelled = false;
00062     m_paused = false;
00063     m_running = false;
00064     m_clearedInProgress = false;
00065     m_lastFile = wxT("");
00066 
00067     // Required to access the preferences of hugin
00068     //SetAppName(wxT("hugin"));
00069 
00070 }
00071 
00072 Batch::~Batch()
00073 {
00074 #if wxCHECK_VERSION(3,1,0)
00075     if (m_resBlocker != NULL)
00076     {
00077         delete m_resBlocker;
00078     };
00079 #endif
00080 }
00081 
00082 void Batch::AddAppToBatch(wxString app)
00083 {
00084     Project* newApp = new Project(app);
00085     m_projList.Add(newApp);
00086 }
00087 
00088 void Batch::AddProjectToBatch(wxString projectFile, wxString outputFile,Project::Target target)
00089 {
00090     wxFileName projectName(projectFile);
00091     wxFileName outName(outputFile);
00092     projectName.Normalize();
00093     outName.Normalize();
00094 
00095     if(outputFile.Cmp(_T(""))!=0 || target==Project::DETECTING)
00096     {
00097         Project* proj = new Project(projectName.GetFullPath(),outName.GetFullPath(),target);
00098         m_projList.Add(proj);
00099     }
00100     else
00101     {
00102         //on output set as "", it defaults to same path and name as project file
00103         Project* proj = new Project(projectName.GetFullPath(),wxT(""));
00104         m_projList.Add(proj);
00105     }
00106 }
00107 
00108 bool Batch::AllDone()
00109 {
00110     for(unsigned int i=0; i<m_projList.GetCount(); i++)
00111     {
00112         if(m_projList.Item(i).status==Project::WAITING ||
00113                 m_projList.Item(i).status==Project::RUNNING ||
00114                 m_projList.Item(i).status==Project::PAUSED)
00115         {
00116             return false;
00117         }
00118     }
00119     return true;
00120 }
00121 
00122 void Batch::AppendBatchFile(wxString file)
00123 {
00124     wxFileName aFile(file);
00125     if(aFile.FileExists())
00126     {
00127         m_lastFile = file;
00128         aFile.GetTimes(NULL,NULL,&m_lastmod);
00129         wxFileInputStream fileStream(file);
00130         wxString projectName = _T("");
00131 #ifdef __WXMSW__
00132         wxTextInputStream textStream(fileStream, wxT(" \t"), wxConvLocal);
00133 #else
00134         wxTextInputStream textStream(fileStream);
00135 #endif
00136 
00137         //TO-DO: batch file error checking?
00138         //first line in file is idGenerator, we save it a temp variable, cause it gets set when adding projects
00139         long idGenTemp = 1;
00140         if (fileStream.Eof())
00141         {
00142             return;
00143         };
00144         textStream.ReadLine().ToLong(&idGenTemp);
00145         //then for each project: project path, prefix, id, status, skip
00146         if (fileStream.Eof())
00147         {
00148             return;
00149         };
00150         while((projectName = textStream.ReadLine()).Cmp(wxT(""))!=0)
00151         {
00152             // read all line, check before reading
00153             if (fileStream.Eof())
00154             {
00155                 break;
00156             };
00157             wxString line=textStream.ReadLine();
00158             if (fileStream.Eof())
00159             {
00160                 break;
00161             };
00162             long id;
00163             textStream.ReadLine().ToLong(&id);
00164             long status;
00165             if (fileStream.Eof())
00166             {
00167                 break;
00168             };
00169             textStream.ReadLine().ToLong(&status);
00170             if (fileStream.Eof())
00171             {
00172                 break;
00173             };
00174             const bool skip = textStream.ReadLine().StartsWith(_T("T"));
00175 
00176             //we add project to internal list
00177             if (line.IsEmpty())
00178             {
00179                 AddProjectToBatch(projectName,wxT(""),Project::DETECTING);
00180             }
00181             else
00182             {
00183                 AddProjectToBatch(projectName,line);
00184             };
00185             //if status was RUNNING or PAUSED, we set it to FAILED
00186             if(status==(long)Project::RUNNING || status==(long)Project::PAUSED)
00187             {
00188                 status=(long)Project::FAILED;
00189             }
00190             m_projList.Last().id = id;
00191             m_projList.Last().status = (Project::Status)status;
00192             if(skip)
00193             {
00194                 m_projList.Last().skip = true;
00195             };
00196 
00197             if (fileStream.Eof())
00198             {
00199                 break;
00200             };
00201         }
00202         //we set the id generator we got from file
00203         Project::idGenerator = idGenTemp;
00204     }
00205 }
00206 
00207 void Batch::CancelBatch()
00208 {
00209     m_cancelled = true;
00210     for(int i=0; i<GetRunningCount(); i++)
00211     {
00212         CancelProject(i);
00213     }
00214 #if wxCHECK_VERSION(3,1,0)
00215     if (m_resBlocker != NULL)
00216     {
00217         delete m_resBlocker;
00218         m_resBlocker = NULL;
00219     };
00220 #endif
00221     m_running = false;
00222 }
00223 void Batch::CancelProject(int index)
00224 {
00225     wxCommandEvent event;
00226     if(GetRunningCount()==1)
00227     {
00228         m_paused = false;
00229     }
00230     m_stitchFrames.Item(index)->OnCancel(event);
00231     if(GetRunningCount()==0)
00232     {
00233         m_running = false;
00234     }
00235 }
00236 void Batch::ChangePrefix(int index, wxString newPrefix)
00237 {
00238     m_projList.Item(index).prefix = newPrefix;
00239 }
00240 
00241 int Batch::ClearBatch()
00242 {
00243     if(m_stitchFrames.GetCount()!=0)
00244     {
00245         wxMessageDialog message(this, _("Cannot clear batch in progress.\nDo you want to cancel it?"),
00246 #ifdef _WIN32
00247                                 _("PTBatcherGUI"),
00248 #else
00249                                 wxT(""),
00250 #endif
00251                                 wxYES_NO | wxICON_INFORMATION);
00252         if(message.ShowModal()==wxID_YES)
00253         {
00254             CancelBatch();
00255 
00256             //we set a flag so we don't process terminating events
00257             m_clearedInProgress = true;
00258             Project::idGenerator=1;
00259             m_projList.Clear();
00260             ((wxFrame*)GetParent())->SetStatusText(_("Cleared batch."));
00261             return 2;
00262         }
00263         return 1;
00264         //TO-DO: return
00265     }
00266     else
00267     {
00268         Project::idGenerator=1;
00269         m_projList.Clear();
00270         ((wxFrame*)GetParent())->SetStatusText(_("Cleared batch."));
00271         return 0;
00272     }
00273 }
00274 
00275 bool Batch::CompareProjectsInLists(int stitchListIndex, int batchListIndex)
00276 {
00277     return m_stitchFrames.Item(stitchListIndex)->GetProjectId() == m_projList.Item(batchListIndex).id;
00278 }
00279 
00280 int Batch::GetFirstAvailable()
00281 {
00282     unsigned int i = 0;
00283     while(i<m_projList.Count())
00284     {
00285         if(m_projList.Item(i).skip || m_projList.Item(i).status!=Project::WAITING)
00286         {
00287             i++;
00288         }
00289         else
00290         {
00291             break;
00292         }
00293     }
00294     if((m_projList.Count() == 0) || (i == m_projList.Count()))
00295     {
00296         //no projects are available anymore
00297         return -1;
00298     }
00299     else
00300     {
00301         return i;
00302     }
00303 }
00304 
00305 int Batch::GetIndex(int id)
00306 {
00307     for(unsigned int i=0; i<m_projList.GetCount(); i++)
00308     {
00309         if(m_projList.Item(i).id==id)
00310         {
00311             return i;
00312         }
00313     }
00314     return -1;
00315 }
00316 
00317 Project* Batch::GetProject(int index)
00318 {
00319     return (Project*)&m_projList.Item(index);
00320 }
00321 
00322 int Batch::GetProjectCount()
00323 {
00324     return m_projList.GetCount();
00325 }
00326 
00327 int Batch::GetProjectCountByPath(wxString path)
00328 {
00329     int count = 0;
00330     for(unsigned int i=0; i<m_projList.GetCount(); i++)
00331     {
00332         if(!m_projList.Item(i).skip && (path.Cmp(m_projList.Item(i).path)==0))
00333         {
00334             count++;
00335         }
00336     }
00337     return count;
00338 }
00339 
00340 int Batch::GetRunningCount()
00341 {
00342     return m_stitchFrames.GetCount();
00343 }
00344 
00345 Project::Status Batch::GetStatus(int index)
00346 {
00347     if((unsigned int)index<m_projList.GetCount())
00348     {
00349         return m_projList.Item(index).status;
00350     }
00351     else
00352     {
00353         wxMessageBox(wxString::Format(_("Error: Could not get status, project with index %d is not in list."),index),_("Error!"),wxOK | wxICON_INFORMATION );
00354     }
00355     return Project::MISSING;
00356 }
00357 
00358 bool Batch::IsRunning()
00359 {
00360     return m_running;
00361 };
00362 
00363 bool Batch::IsPaused()
00364 {
00365     return m_paused;
00366 }
00367 
00368 void Batch::ListBatch()
00369 {
00370     if(m_projList.GetCount() == 0)
00371     {
00372         std::cout << "Batch is empty." << std::endl;
00373     }
00374     else
00375     {
00376         std::cout << "List of projects in batch:" << std::endl <<
00377              "[ID] [project path] [output filename] [status]" << std::endl <<
00378              "-------------------------------------" << std::endl;
00379         for(unsigned int i=0; i<m_projList.GetCount(); i++)
00380         {
00381             std::cout << m_projList.Item(i).id << "  "  << (const char*)m_projList.Item(i).path.char_str()  << "  " << (const char*)m_projList.Item(i).prefix.char_str()
00382                  << "  " << (const char*)m_projList.Item(i).GetStatusText().char_str() << std::endl;
00383         }
00384     }
00385 }
00386 
00387 int Batch::LoadBatchFile(wxString file)
00388 {
00389     int clearCode = ClearBatch();
00390     if(clearCode==0)
00391     {
00392         AppendBatchFile(file);
00393         return 0;
00394     }
00395     else if(clearCode==2)
00396     {
00397         AppendBatchFile(file);
00398         return 2;
00399     }
00400     else
00401     {
00402         wxMessageBox(_("Error: Could not load batch file."));
00403     };
00404     return 1;
00405 }
00406 
00407 int Batch::LoadTemp()
00408 {
00409     wxDir* workingDir = new wxDir(wxStandardPaths::Get().GetUserConfigDir());
00410     wxString pending;
00411     wxString fileTemp = _T(".ptbt*");
00412     wxString temp = _T("");
00413     //we check for existing temporary files
00414     if(workingDir->GetFirst(&temp,fileTemp,wxDIR_FILES | wxDIR_HIDDEN))
00415     {
00416         //we find the last existing tempfile (there should be at most two, but we check for multiple just in case)
00417         while(workingDir->GetNext(&pending))
00418         {
00419             wxFileName tempFile(temp);
00420             wxFileName pendingFile(pending);
00421             wxDateTime* create1 = new wxDateTime();
00422             wxDateTime* create2 = new wxDateTime();
00423             if(tempFile.FileExists() && pendingFile.FileExists())
00424             {
00425                 tempFile.GetTimes(NULL,NULL,create1);
00426                 pendingFile.GetTimes(NULL,NULL,create2);
00427                 if(create2->IsLaterThan(*create1))
00428                 {
00429                     wxRemoveFile(temp);
00430                     temp=wxString(pending);
00431                 }
00432             }
00433             else
00434             {
00435                 //wxMessageBox( _T("Error reading temporary file"),_T("Error!"),wxOK | wxICON_INFORMATION );
00436                 return 1;
00437             }
00438         }
00439     }
00440     //we load the data from the temp file
00441     AppendBatchFile(workingDir->GetName()+wxFileName::GetPathSeparator()+temp);
00442     return 0;
00443 }
00444 
00445 bool Batch::NoErrors()
00446 {
00447     for(unsigned int i=0; i<m_projList.GetCount(); i++)
00448     {
00449         if(m_projList.Item(i).status==Project::FAILED)
00450         {
00451             return false;
00452         }
00453     }
00454     return true;
00455 }
00456 
00457 void Batch::OnProcessTerminate(wxProcessEvent& event)
00458 {
00459     //we find the right pointer to remove
00460     unsigned int i = 0;
00461     while(i < m_stitchFrames.GetCount() &&
00462             m_stitchFrames.Item(i)->GetProjectId()!=event.GetId())
00463     {
00464         i++;
00465     }
00466     m_stitchFrames.RemoveAt(i);
00467     if(m_clearedInProgress)
00468     {
00469         if(m_stitchFrames.GetCount()==0)
00470         {
00471             m_paused = false;
00472             m_running = false;
00473             m_cancelled = false;
00474             m_clearedInProgress = false;
00475         }
00476     }
00477     else
00478     {
00479         if(m_stitchFrames.GetCount()==0)
00480         {
00481             m_paused = false;
00482         }
00483         i = GetIndex(event.GetId());
00484         wxString savedLogfile=wxEmptyString;
00485         if(saveLog || event.GetExitCode() != 0 || event.GetTimestamp()==-1)
00486         {
00487             //get filename for automatic saving of log file
00488             wxFileName logFile(m_projList.Item(i).path);
00489             logFile.MakeAbsolute();
00490             logFile.SetExt(wxT("log"));
00491             wxString name=logFile.GetName();
00492             unsigned int i=1;
00493             while(logFile.FileExists() && i<1000)
00494             {
00495                 logFile.SetName(wxString::Format(wxT("%s_%d"),name.c_str(),i));
00496                 i++;
00497             };
00498             if(i<1000)
00499             {
00500                 //now save log file
00501                 if((static_cast<RunStitchFrame*>(event.GetEventObject()))->SaveLog(logFile.GetFullPath()))
00502                 {
00503                     savedLogfile=logFile.GetFullPath();
00504                 }
00505             };
00506         };
00507         if (event.GetExitCode() != 0 || event.GetTimestamp()==-1) //timestamp is used as a fake exit code because it cannot be set manually
00508         {
00509             m_projList.Item(i).status=Project::FAILED;
00510             struct FailedProject failedProject;
00511             failedProject.project=m_projList.Item(i).path;
00512             failedProject.logfile=savedLogfile;
00513             //remember failed project
00514             m_failedProjects.push_back(failedProject);
00515         }
00516         else
00517         {
00518             m_projList.Item(i).status=Project::FINISHED;
00519             // don't sent event for command app
00520             if(m_projList.Item(i).id>=0)
00521             {
00522                 bool notifyParent=false;
00523                 if(autostitch && m_projList.Item(i).target==Project::DETECTING)
00524                 {
00525                     wxFileName name(m_projList.Item(i).path);
00526                     AddProjectToBatch(m_projList.Item(i).path,name.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + name.GetName(),Project::STITCHING);
00527                     notifyParent=true;
00528                 };
00529                 if(autoremove)
00530                 {
00531                     RemoveProjectAtIndex(i);
00532                     SaveTemp();
00533                     notifyParent=true;
00534                 };
00535                 if(notifyParent)
00536                 {
00537                     wxCommandEvent e(EVT_UPDATE_PARENT,wxID_ANY);
00538                     GetParent()->GetEventHandler()->AddPendingEvent(e);
00539                 };
00540             };
00541         }
00542         if(!m_cancelled && !m_paused)
00543         {
00544             if(AllDone())
00545             {
00546                 SaveTemp();
00547                 m_running = false;
00548 #if wxCHECK_VERSION(3,1,0)
00549                 if (m_resBlocker != NULL)
00550                 {
00551                     delete m_resBlocker;
00552                     m_resBlocker = NULL;
00553                 };
00554 #endif
00555                 if(NoErrors())
00556                 {
00557                     wxCommandEvent e(EVT_INFORMATION,wxID_ANY);
00558                     e.SetString(_("Batch successfully completed."));
00559                     // setting int to 1 to indicate we are finished
00560                     e.SetInt(1);
00561                     GetParent()->GetEventHandler()->AddPendingEvent(e);
00562                 }
00563                 else
00564                 {
00565                     ((wxFrame*)GetParent())->SetStatusText(_("Batch completed with errors."));
00566                     if(atEnd==DO_NOTHING)
00567                     {
00568                         //notify parent, that at least one project failed
00569                         // show dialog only if we don't shutdown the computer or end PTBatcherGUI
00570                         wxCommandEvent e(EVT_BATCH_FAILED,wxID_ANY);
00571                         GetParent()->GetEventHandler()->AddPendingEvent(e);
00572                     };
00573                 };
00574                 switch (atEnd)
00575                 {
00576                     case DO_NOTHING:
00577                         // no action needed
00578                         break;
00579                     case CLOSE_PTBATCHERGUI:
00580                         GetParent()->Close();
00581                         break;
00582                     case SHUTDOWN:
00583                         {
00584                             wxProgressDialog progress(_("Initializing shutdown..."), _("Shutting down..."), 49, this,
00585                                 wxPD_AUTO_HIDE | wxPD_SMOOTH | wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_CAN_SKIP);
00586                             progress.Fit();
00587                             int i = 0;
00588                             bool skip = false;
00589                             while (progress.Update(i, _("Shutting down..."), &skip))
00590                             {
00591                                 if (skip || i == 50)
00592                                 {
00593                                     wxShutdown(wxSHUTDOWN_POWEROFF);
00594                                 }
00595                                 i++;
00596 #if defined __WXMSW__
00597                                 Sleep(200);
00598 #else
00599                                 sleep(200);
00600 #endif
00601                             }
00602                             progress.Close();
00603                         }
00604                         break;
00605                     case SUSPEND:
00606                     case HIBERNATE:
00607 #ifdef __WXMSW__
00608                         {
00609                             wxString progressCaption(_("Prepare to hibernate..."));
00610                             wxString progressLabel(_("Initializing hibernating..."));
00611                             if (atEnd == SUSPEND)
00612                             {
00613                                 progressCaption = wxString(_("Prepare to suspend..."));
00614                                 progressLabel = wxString(_("Initializing suspend mode..."));
00615                             };
00616                             wxProgressDialog progress(progressLabel, progressCaption, 49, this,
00617                                 wxPD_AUTO_HIDE | wxPD_SMOOTH | wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_CAN_SKIP);
00618                             progress.Fit();
00619                             int i = 0;
00620                             bool skip = false;
00621                             while (progress.Update(i, progressCaption, &skip))
00622                             {
00623                                 if (skip || i == 50)
00624                                 {
00625                                     SetSuspendState(atEnd==HIBERNATE, false, false);
00626                                     break;
00627                                 }
00628                                 i++;
00629                                 Sleep(200);
00630                             }
00631                             progress.Close();
00632                         };
00633 #endif
00634                         break;
00635                 };
00636             }
00637             else
00638             {
00639                 RunNextInBatch();
00640             }
00641         }
00642         else
00643         {
00644             //after all processes have ended on a cancel, we reset the boolean back to false
00645             //if(stitchFrames.GetCount()==0)
00646             if(GetRunningCount()==0)
00647             {
00648                 m_cancelled=false;
00649             }
00650         }
00651     }
00652 }
00653 
00654 bool Batch::OnStitch(wxString scriptFile, wxString outname, int id)
00655 {
00656     // delete the existing wxConfig to force reloading of settings from file/registy
00657     delete wxConfigBase::Set((wxConfigBase*)NULL);
00658     wxConfigBase* config = wxConfigBase::Get();
00659     if(wxIsEmpty(scriptFile))
00660     {
00661         wxString defaultdir = config->Read(wxT("/actualPath"),wxT(""));
00662         wxFileDialog dlg(0,
00663                          _("Specify project file"),
00664                          defaultdir, wxT(""),
00665                          _("Project files (*.pto)|*.pto|All files (*)|*"),
00666                          wxFD_OPEN, wxDefaultPosition);
00667 
00668         dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
00669         if (dlg.ShowModal() == wxID_OK)
00670         {
00671             config->Write(wxT("/actualPath"), dlg.GetDirectory());  // remember for later
00672             config->Flush();
00673             wxFileDialog dlg2(0,_("Specify output prefix"),
00674                               wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")),
00675                               wxT(""), wxT(""),
00676                               wxFD_SAVE, wxDefaultPosition);
00677             dlg2.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
00678             if (dlg2.ShowModal() == wxID_OK)
00679             {
00680                 outname = dlg2.GetPath();
00681             }
00682             else     // bail
00683             {
00684                 wxLogError( _("No output prefix specified"));
00685                 return false;
00686             }
00687             scriptFile = dlg.GetPath();
00688         }
00689         else     // bail
00690         {
00691             wxLogError(_("No project files specified"));
00692             return false;
00693         }
00694     }
00695 
00696     // check output filename
00697     wxFileName outfn(outname);
00698     wxString ext = outfn.GetExt();
00699     // remove extension if it indicates an image file
00700     if (ext.CmpNoCase(wxT("jpg")) == 0 || ext.CmpNoCase(wxT("jpeg")) == 0 ||
00701             ext.CmpNoCase(wxT("tif")) == 0 || ext.CmpNoCase(wxT("tiff")) == 0 ||
00702             ext.CmpNoCase(wxT("png")) == 0 || ext.CmpNoCase(wxT("exr")) == 0 ||
00703             ext.CmpNoCase(wxT("pnm")) == 0 || ext.CmpNoCase(wxT("hdr")) == 0)
00704     {
00705         outfn.ClearExt();
00706         outname = outfn.GetFullPath();
00707     }
00708 
00709     RunStitchFrame* stitchFrame = new RunStitchFrame(this, wxT("Hugin Stitcher"), wxDefaultPosition, wxSize(640,600));
00710     stitchFrame->SetProjectId(id);
00711     if(verbose)
00712     {
00713         stitchFrame->Show( true );
00714         wxTheApp->SetTopWindow( stitchFrame );
00715     }
00716 
00717     wxFileName basename(scriptFile);
00718     stitchFrame->SetTitle(wxString::Format(_("%s - Stitching"), basename.GetName().c_str()));
00719     if(overwrite)
00720     {
00721         stitchFrame->m_stitchPanel->SetOverwrite(true);
00722     }
00723 
00724     bool n = stitchFrame->StitchProject(scriptFile, outname);
00725     if(n)
00726     {
00727         m_stitchFrames.Add(stitchFrame);
00728     }
00729     else
00730     {
00731         stitchFrame->Close();
00732     }
00733     return n;
00734 
00735 }
00736 
00737 bool Batch::OnDetect(wxString scriptFile, int id)
00738 {
00739     // delete the existing wxConfig to force reloading of settings from file/registy
00740     delete wxConfigBase::Set((wxConfigBase*)NULL);
00741     RunStitchFrame* stitchFrame = new RunStitchFrame(this, wxT("Hugin Assistant"), wxDefaultPosition, wxSize(640, 600));
00742     stitchFrame->SetProjectId(id);
00743     if(verbose)
00744     {
00745         stitchFrame->Show( true );
00746         wxTheApp->SetTopWindow( stitchFrame );
00747     }
00748 
00749     wxFileName basename(scriptFile);
00750     stitchFrame->SetTitle(wxString::Format(_("%s - Assistant"), basename.GetName().c_str()));
00751 
00752     bool n = stitchFrame->DetectProject(scriptFile);
00753     if(n)
00754     {
00755         m_stitchFrames.Add(stitchFrame);
00756     }
00757     else
00758     {
00759         stitchFrame->Close();
00760     }
00761     return n;
00762 
00763 }
00764 
00765 void Batch::PauseBatch()
00766 {
00767     if(!m_paused)
00768     {
00769         m_paused = true;
00770         for(int i=0; i<GetRunningCount(); i++)
00771         {
00772             m_stitchFrames.Item(i)->m_stitchPanel->PauseStitch();
00773         }
00774         for(unsigned int i=0; i<m_projList.GetCount(); i++)
00775         {
00776             if(m_projList.Item(i).status==Project::RUNNING)
00777             {
00778                 m_projList.Item(i).status=Project::PAUSED;
00779             }
00780         }
00781     }
00782     else
00783     {
00784         m_paused = false;
00785         for(int i=0; i<GetRunningCount(); i++)
00786         {
00787             m_stitchFrames.Item(i)->m_stitchPanel->ContinueStitch();
00788         }
00789         for(unsigned int i=0; i<m_projList.GetCount(); i++)
00790         {
00791             if(m_projList.Item(i).status==Project::PAUSED)
00792             {
00793                 m_projList.Item(i).status=Project::RUNNING;
00794             }
00795         }
00796     }
00797 }
00798 
00799 void Batch::RemoveProject(int id)
00800 {
00801     if(GetIndex(id) != -1)
00802     {
00803         RemoveProjectAtIndex(GetIndex(id));
00804     }
00805     else
00806     {
00807         wxMessageBox(wxString::Format(_("Error removing, project with id %d is not in list."),id),_("Error!"),wxOK | wxICON_INFORMATION );
00808     }
00809 }
00810 
00811 void Batch::RemoveProjectAtIndex(int selIndex)
00812 {
00813     //we delete only successful project files and no applications
00814     if(deleteFiles
00815             && m_projList.Item(selIndex).id>=0
00816             && m_projList.Item(selIndex).status==Project::FINISHED)
00817     {
00818         wxFileName file(m_projList.Item(selIndex).path);
00819         if(file.FileExists())
00820         {
00821             if(!wxRemoveFile(file.GetFullPath()))
00822             {
00823                 wxMessageBox( _("Error: Could not delete project file ")+file.GetFullPath(),_("Error!"),wxOK | wxICON_INFORMATION );
00824             }
00825         }
00826     }
00827     m_projList.RemoveAt(selIndex);
00828     if(m_projList.GetCount()==0) //reset the id generator on empty list
00829     {
00830         Project::idGenerator=1;
00831     }
00832 }
00833 
00834 void Batch::RunBatch()
00835 {
00836     if(!m_running)
00837     {
00838         m_failedProjects.clear();
00839         ((wxFrame*)GetParent())->SetStatusText(_("Running batch..."));
00840         m_running = true;
00841 #if wxCHECK_VERSION(3,1,0)
00842         m_resBlocker = new wxPowerResourceBlocker(wxPOWER_RESOURCE_SYSTEM, _("PTBatcherGUI is stitching"));
00843 #endif
00844         RunNextInBatch();
00845     }
00846     else
00847     {
00848         ((wxFrame*)GetParent())->SetStatusText(_("Batch already in progress."));
00849     }
00850 }
00851 
00852 void Batch::RunNextInBatch()
00853 {
00854     bool value;
00855     bool repeat = true;
00856     unsigned int i;
00857     while(((i=GetFirstAvailable())!=-1) && repeat)
00858     {
00859         //execute command line instructions
00860         if(m_projList.Item(i).id<0)
00861         {
00862             SetStatusText(wxString::Format(_("Running command \"%s\""), m_projList.Item(i).path.c_str()));
00863             m_projList.Item(i).status=Project::RUNNING;
00864             //we create a fake stitchFrame, so program waits for app to complete
00865             if(wxExecute(m_projList.Item(i).path, wxEXEC_SYNC)==0)
00866             {
00867                 m_projList.Item(i).status=Project::FINISHED;
00868             }
00869             else
00870             {
00871                 m_projList.Item(i).status=Project::FAILED;
00872             }
00873         }
00874         else
00875         {
00876             m_projList.Item(i).status=Project::RUNNING;
00877             m_running = true;
00878             if(m_projList.Item(i).target==Project::STITCHING)
00879             {
00880                 wxCommandEvent e(EVT_INFORMATION,wxID_ANY);
00881                 e.SetString(wxString::Format(_("Now stitching: %s"),m_projList.Item(i).path.c_str()));
00882                 GetParent()->GetEventHandler()->AddPendingEvent(e);
00883                 value = OnStitch(m_projList.Item(i).path, m_projList.Item(i).prefix, m_projList.Item(i).id);
00884             }
00885             else
00886             {
00887                 wxCommandEvent e(EVT_INFORMATION,wxID_ANY);
00888                 e.SetString(wxString::Format(_("Now detecting: %s"),m_projList.Item(i).path.c_str()));
00889                 GetParent()->GetEventHandler()->AddPendingEvent(e);
00890                 value = OnDetect(m_projList.Item(i).path,m_projList.Item(i).id);
00891             };
00892             if(!value)
00893             {
00894                 m_projList.Item(i).status=Project::FAILED;
00895             }
00896             else
00897             {
00898                 repeat = false;
00899             }
00900         }
00901     }
00902     if(AllDone())
00903     {
00904         m_running = false;
00905     }
00906 }
00907 
00908 void Batch::SaveBatchFile(wxString file)
00909 {
00910     wxFileOutputStream fileStream(file);
00911 #ifdef __WXMSW__
00912     wxTextOutputStream textStream(fileStream, wxEOL_NATIVE, wxConvLocal);
00913 #else
00914     wxTextOutputStream textStream(fileStream);
00915 #endif
00916     //we write current idGenerator to file
00917     wxString line = _T("");
00918     line << Project::idGenerator;
00919     textStream.WriteString(line+_T("\n"));
00920     //then for each project: project path, prefix, id, status, skip
00921     for(unsigned int i = 0; i< m_projList.GetCount(); i++)
00922     {
00923         textStream.WriteString(m_projList.Item(i).path+_T("\n"));
00924         if(m_projList.Item(i).target==Project::STITCHING)
00925         {
00926             textStream.WriteString(m_projList.Item(i).prefix+_T("\n"));
00927         }
00928         else
00929         {
00930             textStream.WriteString(_T("\n"));
00931         };
00932         line = _T("");
00933         line << m_projList.Item(i).id;
00934         textStream.WriteString(line+_T("\n"));
00935         line = _T("");
00936         line << m_projList.Item(i).status;
00937         textStream.WriteString(line+_T("\n"));
00938         if(m_projList.Item(i).skip)
00939         {
00940             textStream.WriteString(_T("T\n"));
00941         }
00942         else
00943         {
00944             textStream.WriteString(_T("F\n"));
00945         }
00946     }
00947     fileStream.Close();
00948     m_lastFile = file;
00949     wxFileName aFile(file);
00950     aFile.GetTimes(NULL,NULL,&m_lastmod);
00951 }
00952 
00953 void Batch::SaveTemp()
00954 {
00955     wxDir* workingDir = new wxDir(wxStandardPaths::Get().GetUserConfigDir());
00956     wxString fileTemp = _T(".ptbt*");
00957     //we get the old temp file
00958     fileTemp = workingDir->FindFirst(workingDir->GetName(),fileTemp,wxDIR_FILES | wxDIR_HIDDEN);
00959     wxFileName oldFile(fileTemp);
00960     //we alternate between 0 and 1
00961     wxString suffix;
00962     if(fileTemp.EndsWith(_T("0")))
00963     {
00964         suffix = _T("1");
00965     }
00966     else
00967     {
00968         suffix = _T("0");
00969     }
00970     SaveBatchFile(wxStandardPaths::Get().GetUserConfigDir()+wxFileName::GetPathSeparator()+_T(".ptbt")+suffix);
00971     //we remove the previous temp file
00972     if(oldFile.FileExists())
00973     {
00974         wxRemoveFile(fileTemp);
00975     }
00976 }
00977 
00978 void Batch::SetStatus(int index,Project::Status status)
00979 {
00980     if((unsigned int)index<m_projList.GetCount())
00981     {
00982         m_projList.Item(index).status = status;
00983     }
00984     else
00985     {
00986         wxMessageBox(wxString::Format(_("Error: Could not set status, project with index %d is not in list."),index),_("Error!"),wxOK | wxICON_INFORMATION );
00987     }
00988 }
00989 
00990 void Batch::SwapProject(int index)
00991 {
00992     Project* proj = m_projList.Detach(index+1);
00993     m_projList.Insert(proj,index);
00994 }
00995 
00996 void Batch::ShowOutput(bool isVisible)
00997 {
00998     for(unsigned int i=0; i<m_stitchFrames.Count(); i++)
00999     {
01000         m_stitchFrames.Item(i)->Show(isVisible);
01001     };
01002 };
01003 
01004 wxString Batch::GetFailedProjectName(unsigned int i)
01005 {
01006     if(i<m_failedProjects.size())
01007     {
01008         return m_failedProjects[i].project;
01009     }
01010     else
01011     {
01012         return wxEmptyString;
01013     }
01014 };
01015 
01016 wxString Batch::GetFailedProjectLog(unsigned int i)
01017 {
01018     if(i<m_failedProjects.size())
01019     {
01020         return m_failedProjects[i].logfile;
01021     }
01022     else
01023     {
01024         return wxEmptyString;
01025     }
01026 };

Generated on 30 Apr 2016 for Hugintrunk by  doxygen 1.4.7