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     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 _WIN32
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         std::cout << "Batch is empty." << std::endl;
00353     }
00354     else
00355     {
00356         std::cout << "List of projects in batch:" << std::endl <<
00357              "[ID] [project path] [output filename] [status]" << std::endl <<
00358              "-------------------------------------" << std::endl;
00359         for(unsigned int i=0; i<m_projList.GetCount(); i++)
00360         {
00361             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()
00362                  << "  " << (const char*)m_projList.Item(i).GetStatusText().char_str() << std::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                     // setting int to 1 to indicate we are finished
00533                     e.SetInt(1);
00534                     GetParent()->GetEventHandler()->AddPendingEvent(e);
00535                 }
00536                 else
00537                 {
00538                     ((wxFrame*)GetParent())->SetStatusText(_("Batch completed with errors."));
00539                     if(atEnd==DO_NOTHING)
00540                     {
00541                         //notify parent, that at least one project failed
00542                         // show dialog only if we don't shutdown the computer or end PTBatcherGUI
00543                         wxCommandEvent e(EVT_BATCH_FAILED,wxID_ANY);
00544                         GetParent()->GetEventHandler()->AddPendingEvent(e);
00545                     };
00546                 };
00547                 if (atEnd != DO_NOTHING)        //after we are finished we turn off the computer if checked
00548                 {
00549                     switch (atEnd)
00550                     {
00551                         case CLOSE_PTBATCHERGUI:
00552                             GetParent()->Close();
00553                             break;
00554                         case SHUTDOWN:
00555                             {
00556                                 wxProgressDialog progress(_("Initializing shutdown..."), _("Shutting down..."), 49, this,
00557                                     wxPD_AUTO_HIDE | wxPD_SMOOTH | wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_CAN_SKIP);
00558                                 progress.Fit();
00559                                 int i = 0;
00560                                 bool skip = false;
00561                                 while (progress.Update(i, _("Shutting down..."), &skip))
00562                                 {
00563                                     if (skip || i == 50)
00564                                     {
00565                                         wxShutdown(wxSHUTDOWN_POWEROFF);
00566                                     }
00567                                     i++;
00568     #if defined __WXMSW__
00569                                     Sleep(200);
00570     #else
00571                                     sleep(200);
00572     #endif
00573                                 }
00574                                 progress.Close();
00575                             }
00576                             break;
00577                         case SUSPEND:
00578                         case HIBERNATE:
00579 #ifdef __WXMSW__
00580                             {
00581                                 wxString progressCaption(_("Prepare to hibernate..."));
00582                                 wxString progressLabel(_("Initializing hibernating..."));
00583                                 if (atEnd == SUSPEND)
00584                                 {
00585                                     progressCaption = wxString(_("Prepare to suspend..."));
00586                                     progressLabel = wxString(_("Initializing suspend mode..."));
00587                                 };
00588                                 wxProgressDialog progress(progressLabel, progressCaption, 49, this,
00589                                     wxPD_AUTO_HIDE | wxPD_SMOOTH | wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_CAN_SKIP);
00590                                 progress.Fit();
00591                                 int i = 0;
00592                                 bool skip = false;
00593                                 while (progress.Update(i, progressCaption, &skip))
00594                                 {
00595                                     if (skip || i == 50)
00596                                     {
00597                                         SetSuspendState(atEnd==HIBERNATE, false, false);
00598                                         break;
00599                                     }
00600                                     i++;
00601                                     Sleep(200);
00602                                 }
00603                                 progress.Close();
00604                             };
00605 #endif
00606                             break;
00607                     };
00608                 };
00609             }
00610             else
00611             {
00612                 RunNextInBatch();
00613             }
00614         }
00615         else
00616         {
00617             //after all processes have ended on a cancel, we reset the boolean back to false
00618             //if(stitchFrames.GetCount()==0)
00619             if(GetRunningCount()==0)
00620             {
00621                 m_cancelled=false;
00622             }
00623         }
00624     }
00625 }
00626 
00627 bool Batch::OnStitch(wxString scriptFile, wxString outname, int id)
00628 {
00629     // delete the existing wxConfig to force reloading of settings from file/registy
00630     delete wxConfigBase::Set((wxConfigBase*)NULL);
00631     wxConfigBase* config = wxConfigBase::Get();
00632     if(wxIsEmpty(scriptFile))
00633     {
00634         wxString defaultdir = config->Read(wxT("/actualPath"),wxT(""));
00635         wxFileDialog dlg(0,
00636                          _("Specify project source project file"),
00637                          defaultdir, wxT(""),
00638                          _("Project files (*.pto)|*.pto|All files (*)|*"),
00639                          wxFD_OPEN, wxDefaultPosition);
00640 
00641         dlg.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
00642         if (dlg.ShowModal() == wxID_OK)
00643         {
00644             config->Write(wxT("/actualPath"), dlg.GetDirectory());  // remember for later
00645             config->Flush();
00646             wxFileDialog dlg2(0,_("Specify output prefix"),
00647                               wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")),
00648                               wxT(""), wxT(""),
00649                               wxFD_SAVE, wxDefaultPosition);
00650             dlg2.SetDirectory(wxConfigBase::Get()->Read(wxT("/actualPath"),wxT("")));
00651             if (dlg2.ShowModal() == wxID_OK)
00652             {
00653                 outname = dlg2.GetPath();
00654             }
00655             else     // bail
00656             {
00657                 wxLogError( _("No output prefix specified"));
00658                 return false;
00659             }
00660             scriptFile = dlg.GetPath();
00661         }
00662         else     // bail
00663         {
00664             wxLogError(_("No project files specified"));
00665             return false;
00666         }
00667     }
00668 
00669     // check output filename
00670     wxFileName outfn(outname);
00671     wxString ext = outfn.GetExt();
00672     // remove extension if it indicates an image file
00673     if (ext.CmpNoCase(wxT("jpg")) == 0 || ext.CmpNoCase(wxT("jpeg")) == 0 ||
00674             ext.CmpNoCase(wxT("tif")) == 0 || ext.CmpNoCase(wxT("tiff")) == 0 ||
00675             ext.CmpNoCase(wxT("png")) == 0 || ext.CmpNoCase(wxT("exr")) == 0 ||
00676             ext.CmpNoCase(wxT("pnm")) == 0 || ext.CmpNoCase(wxT("hdr")) == 0)
00677     {
00678         outfn.ClearExt();
00679         outname = outfn.GetFullPath();
00680     }
00681 
00682     RunStitchFrame* stitchFrame = new RunStitchFrame(this, wxT("Hugin Stitcher"), wxDefaultPosition, wxSize(640,600));
00683     stitchFrame->SetProjectId(id);
00684     if(verbose)
00685     {
00686         stitchFrame->Show( true );
00687         wxTheApp->SetTopWindow( stitchFrame );
00688     }
00689 
00690     wxFileName basename(scriptFile);
00691     stitchFrame->SetTitle(wxString::Format(_("%s - Stitching"), basename.GetName().c_str()));
00692     if(overwrite)
00693     {
00694         stitchFrame->m_stitchPanel->SetOverwrite(true);
00695     }
00696 
00697     bool n = stitchFrame->StitchProject(scriptFile, outname);
00698     if(n)
00699     {
00700         m_stitchFrames.Add(stitchFrame);
00701     }
00702     else
00703     {
00704         stitchFrame->Close();
00705     }
00706     return n;
00707 
00708 }
00709 
00710 bool Batch::OnDetect(wxString scriptFile, int id)
00711 {
00712     // delete the existing wxConfig to force reloading of settings from file/registy
00713     delete wxConfigBase::Set((wxConfigBase*)NULL);
00714     RunStitchFrame* stitchFrame = new RunStitchFrame(this, wxT("Hugin Assistant"), wxDefaultPosition, wxSize(640, 600));
00715     stitchFrame->SetProjectId(id);
00716     if(verbose)
00717     {
00718         stitchFrame->Show( true );
00719         wxTheApp->SetTopWindow( stitchFrame );
00720     }
00721 
00722     wxFileName basename(scriptFile);
00723     stitchFrame->SetTitle(wxString::Format(_("%s - Assistant"), basename.GetName().c_str()));
00724 
00725     bool n = stitchFrame->DetectProject(scriptFile);
00726     if(n)
00727     {
00728         m_stitchFrames.Add(stitchFrame);
00729     }
00730     else
00731     {
00732         stitchFrame->Close();
00733     }
00734     return n;
00735 
00736 }
00737 
00738 void Batch::PauseBatch()
00739 {
00740     if(!m_paused)
00741     {
00742         m_paused = true;
00743         for(int i=0; i<GetRunningCount(); i++)
00744         {
00745             m_stitchFrames.Item(i)->m_stitchPanel->PauseStitch();
00746         }
00747         for(unsigned int i=0; i<m_projList.GetCount(); i++)
00748         {
00749             if(m_projList.Item(i).status==Project::RUNNING)
00750             {
00751                 m_projList.Item(i).status=Project::PAUSED;
00752             }
00753         }
00754     }
00755     else
00756     {
00757         m_paused = false;
00758         for(int i=0; i<GetRunningCount(); i++)
00759         {
00760             m_stitchFrames.Item(i)->m_stitchPanel->ContinueStitch();
00761         }
00762         for(unsigned int i=0; i<m_projList.GetCount(); i++)
00763         {
00764             if(m_projList.Item(i).status==Project::PAUSED)
00765             {
00766                 m_projList.Item(i).status=Project::RUNNING;
00767             }
00768         }
00769     }
00770 }
00771 
00772 void Batch::RemoveProject(int id)
00773 {
00774     if(GetIndex(id) != -1)
00775     {
00776         RemoveProjectAtIndex(GetIndex(id));
00777     }
00778     else
00779     {
00780         wxMessageBox(wxString::Format(_("Error removing, project with id %d is not in list."),id),_("Error!"),wxOK | wxICON_INFORMATION );
00781     }
00782 }
00783 
00784 void Batch::RemoveProjectAtIndex(int selIndex)
00785 {
00786     //we delete only successful project files and no applications
00787     if(deleteFiles
00788             && m_projList.Item(selIndex).id>=0
00789             && m_projList.Item(selIndex).status==Project::FINISHED)
00790     {
00791         wxFileName file(m_projList.Item(selIndex).path);
00792         if(file.FileExists())
00793         {
00794             if(!wxRemoveFile(file.GetFullPath()))
00795             {
00796                 wxMessageBox( _("Error: Could not delete project file ")+file.GetFullPath(),_("Error!"),wxOK | wxICON_INFORMATION );
00797             }
00798         }
00799     }
00800     m_projList.RemoveAt(selIndex);
00801     if(m_projList.GetCount()==0) //reset the id generator on empty list
00802     {
00803         Project::idGenerator=1;
00804     }
00805 }
00806 
00807 void Batch::RunBatch()
00808 {
00809     if(!m_running)
00810     {
00811         m_failedProjects.clear();
00812         ((wxFrame*)GetParent())->SetStatusText(_("Running batch..."));
00813         m_running = true;
00814         RunNextInBatch();
00815     }
00816     else
00817     {
00818         ((wxFrame*)GetParent())->SetStatusText(_("Batch already in progress."));
00819     }
00820 }
00821 
00822 void Batch::RunNextInBatch()
00823 {
00824     bool value;
00825     bool repeat = true;
00826     unsigned int i;
00827     while(((i=GetFirstAvailable())!=-1) && repeat)
00828     {
00829         //execute command line instructions
00830         if(m_projList.Item(i).id<0)
00831         {
00832             SetStatusText(wxString::Format(_("Running command \"%s\""), m_projList.Item(i).path.c_str()));
00833             m_projList.Item(i).status=Project::RUNNING;
00834             //we create a fake stitchFrame, so program waits for app to complete
00835             if(wxExecute(m_projList.Item(i).path, wxEXEC_SYNC)==0)
00836             {
00837                 m_projList.Item(i).status=Project::FINISHED;
00838             }
00839             else
00840             {
00841                 m_projList.Item(i).status=Project::FAILED;
00842             }
00843         }
00844         else
00845         {
00846             m_projList.Item(i).status=Project::RUNNING;
00847             m_running = true;
00848             if(m_projList.Item(i).target==Project::STITCHING)
00849             {
00850                 wxCommandEvent e(EVT_INFORMATION,wxID_ANY);
00851                 e.SetString(wxString::Format(_("Now stitching: %s"),m_projList.Item(i).path.c_str()));
00852                 GetParent()->GetEventHandler()->AddPendingEvent(e);
00853                 value = OnStitch(m_projList.Item(i).path, m_projList.Item(i).prefix, m_projList.Item(i).id);
00854             }
00855             else
00856             {
00857                 wxCommandEvent e(EVT_INFORMATION,wxID_ANY);
00858                 e.SetString(wxString::Format(_("Now detecting: %s"),m_projList.Item(i).path.c_str()));
00859                 GetParent()->GetEventHandler()->AddPendingEvent(e);
00860                 value = OnDetect(m_projList.Item(i).path,m_projList.Item(i).id);
00861             };
00862             if(!value)
00863             {
00864                 m_projList.Item(i).status=Project::FAILED;
00865             }
00866             else
00867             {
00868                 repeat = false;
00869             }
00870         }
00871     }
00872     if(AllDone())
00873     {
00874         m_running = false;
00875     }
00876 }
00877 
00878 void Batch::SaveBatchFile(wxString file)
00879 {
00880     wxFileOutputStream fileStream(file);
00881 #ifdef __WXMSW__
00882     wxTextOutputStream textStream(fileStream, wxEOL_NATIVE, wxConvLocal);
00883 #else
00884     wxTextOutputStream textStream(fileStream);
00885 #endif
00886     //we write current idGenerator to file
00887     wxString line = _T("");
00888     line << Project::idGenerator;
00889     textStream.WriteString(line+_T("\n"));
00890     //then for each project: project path, prefix, id, status, skip
00891     for(unsigned int i = 0; i< m_projList.GetCount(); i++)
00892     {
00893         textStream.WriteString(m_projList.Item(i).path+_T("\n"));
00894         if(m_projList.Item(i).target==Project::STITCHING)
00895         {
00896             textStream.WriteString(m_projList.Item(i).prefix+_T("\n"));
00897         }
00898         else
00899         {
00900             textStream.WriteString(_T("\n"));
00901         };
00902         line = _T("");
00903         line << m_projList.Item(i).id;
00904         textStream.WriteString(line+_T("\n"));
00905         line = _T("");
00906         line << m_projList.Item(i).status;
00907         textStream.WriteString(line+_T("\n"));
00908         if(m_projList.Item(i).skip)
00909         {
00910             textStream.WriteString(_T("T\n"));
00911         }
00912         else
00913         {
00914             textStream.WriteString(_T("F\n"));
00915         }
00916     }
00917     fileStream.Close();
00918     m_lastFile = file;
00919     wxFileName aFile(file);
00920     aFile.GetTimes(NULL,NULL,&m_lastmod);
00921 }
00922 
00923 void Batch::SaveTemp()
00924 {
00925     wxDir* workingDir = new wxDir(wxStandardPaths::Get().GetUserConfigDir());
00926     wxString fileTemp = _T(".ptbt*");
00927     //we get the old temp file
00928     fileTemp = workingDir->FindFirst(workingDir->GetName(),fileTemp,wxDIR_FILES | wxDIR_HIDDEN);
00929     wxFileName oldFile(fileTemp);
00930     //we alternate between 0 and 1
00931     wxString suffix;
00932     if(fileTemp.EndsWith(_T("0")))
00933     {
00934         suffix = _T("1");
00935     }
00936     else
00937     {
00938         suffix = _T("0");
00939     }
00940     SaveBatchFile(wxStandardPaths::Get().GetUserConfigDir()+wxFileName::GetPathSeparator()+_T(".ptbt")+suffix);
00941     //we remove the previous temp file
00942     if(oldFile.FileExists())
00943     {
00944         wxRemoveFile(fileTemp);
00945     }
00946 }
00947 
00948 void Batch::SetStatus(int index,Project::Status status)
00949 {
00950     if((unsigned int)index<m_projList.GetCount())
00951     {
00952         m_projList.Item(index).status = status;
00953     }
00954     else
00955     {
00956         wxMessageBox(wxString::Format(_("Error: Could not set status, project with index %d is not in list."),index),_("Error!"),wxOK | wxICON_INFORMATION );
00957     }
00958 }
00959 
00960 void Batch::SwapProject(int index)
00961 {
00962     Project* proj = m_projList.Detach(index+1);
00963     m_projList.Insert(proj,index);
00964 }
00965 
00966 void Batch::ShowOutput(bool isVisible)
00967 {
00968     for(unsigned int i=0; i<m_stitchFrames.Count(); i++)
00969     {
00970         m_stitchFrames.Item(i)->Show(isVisible);
00971     };
00972 };
00973 
00974 wxString Batch::GetFailedProjectName(unsigned int i)
00975 {
00976     if(i<m_failedProjects.size())
00977     {
00978         return m_failedProjects[i].project;
00979     }
00980     else
00981     {
00982         return wxEmptyString;
00983     }
00984 };
00985 
00986 wxString Batch::GetFailedProjectLog(unsigned int i)
00987 {
00988     if(i<m_failedProjects.size())
00989     {
00990         return m_failedProjects[i].logfile;
00991     }
00992     else
00993     {
00994         return wxEmptyString;
00995     }
00996 };

Generated on 6 Feb 2016 for Hugintrunk by  doxygen 1.4.7