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

Generated on 5 Sep 2015 for Hugintrunk by  doxygen 1.4.7