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

Generated on 23 May 2018 for Hugintrunk by  doxygen 1.4.7