Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

dlgBatchCreate.cpp

Go to the documentation of this file.
00001 /* 00002 * wxChecksums 00003 * Copyright (C) 2003-2004 Julien Couot 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public License 00007 * as published by the Free Software Foundation; either version 2 00008 * of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 */ 00019 00020 /** 00021 * \file dlgBatchCreate.cpp 00022 * Dialog for creating one checksums' file for each selected file. 00023 */ 00024 00025 00026 //--------------------------------------------------------------------------- 00027 // For compilers that support precompilation, includes "wx.h". 00028 #include <wx/wxprec.h> 00029 00030 #ifdef __BORLANDC__ 00031 #pragma hdrstop 00032 #endif 00033 00034 #ifndef WX_PRECOMP 00035 // Include your minimal set of headers here, or wx.h 00036 #include <wx/wx.h> 00037 #endif 00038 00039 #include <wx/config.h> 00040 #include <wx/datetime.h> 00041 #include <wx/filename.h> 00042 00043 #include <climits> 00044 00045 #include "dlgBatchCreate.hpp" 00046 #include "appprefs.hpp" 00047 #include "bytedisp.hpp" 00048 #include "checksum.hpp" 00049 #include "checksumfactory.hpp" 00050 #include "checksumutil.hpp" 00051 #include "comdefs.hpp" 00052 #include "fileutil.hpp" 00053 #include "osdep.hpp" 00054 #include "sumfile.hpp" 00055 #include "utils.hpp" 00056 00057 #include "compat.hpp" 00058 //--------------------------------------------------------------------------- 00059 00060 00061 /// The C++ standard namespace. 00062 using namespace std; 00063 00064 00065 //########################################################################### 00066 // dlgBatchCreation::Options methods 00067 //########################################################################### 00068 00069 /** 00070 * Facility constructor. 00071 * 00072 * @param iOvrCkFileWhenItExists If <CODE>true</CODE>, when a checksums' file 00073 * already exists it is overwritten. Otherwise 00074 * the creation of the checksums' file is 00075 * skipped. 00076 * @param iReplaceExtension If <CODE>true</CODE> the name of the 00077 * checksums' file will be made by replacing the 00078 * extension of the source file with the 00079 * extension of the type of the checksums' file. 00080 * Otherwise, the name of the checksums' file 00081 * will be made by adding the extension of the 00082 * type of checksums' file to the name of the 00083 * source file. 00084 * @param iVerbosity Report's Verbosity. 00085 */ 00086 dlgBatchCreation::Options::Options(const bool iOvrCkFileWhenItExists, 00087 const bool iReplaceExtension, 00088 const dlgBatchCreation::Verbosity iVerbosity) 00089 { 00090 // Put an initial value in case iVerbosity contains a bad value. 00091 verbosity = dlgBatchCreation::vNormal; 00092 setVerbosity(iVerbosity); 00093 ovrCkFileWhenItExists = iOvrCkFileWhenItExists; 00094 replaceExtension = iReplaceExtension; 00095 } 00096 //--------------------------------------------------------------------------- 00097 00098 00099 /** 00100 * Gets the report's verbosity. 00101 * 00102 * @return The report's verbosity. 00103 */ 00104 dlgBatchCreation::Verbosity dlgBatchCreation::Options::getVerbosity() const 00105 { 00106 return verbosity; 00107 } 00108 //--------------------------------------------------------------------------- 00109 00110 00111 /** 00112 * Sets the report's verbosity. 00113 * 00114 * If the given parameter has an invalid value, the value of the instance isn't 00115 * changed. 00116 * 00117 * @param newVerbosity The new verbosity of the report. 00118 */ 00119 void dlgBatchCreation::Options::setVerbosity(const dlgBatchCreation::Verbosity newVerbosity) 00120 { 00121 if (newVerbosity >= Verbosity_Min && newVerbosity <= Verbosity_Max) 00122 verbosity = newVerbosity; 00123 } 00124 //--------------------------------------------------------------------------- 00125 00126 00127 00128 //########################################################################### 00129 // dlgBatchCreation::FilesStatistics methods 00130 //########################################################################### 00131 00132 /** 00133 * Statistics on the files. 00134 */ 00135 class dlgBatchCreation::FilesStatistics 00136 { 00137 public: 00138 unsigned int FCorrect; ///< Correct read files. 00139 unsigned int FReadError; ///< Errors while reading the file. 00140 unsigned int FNotFound; ///< Files not found. 00141 unsigned int FNotOpened; ///< Files not opened. 00142 unsigned int FSkipped; ///< Files skipped. 00143 00144 unsigned int CKSkipped; ///< Checksums' files skipped. 00145 unsigned int CKOverwritten; ///< Checksums' files overwritten. 00146 unsigned int CKCreated; ///< Checksums' files created. 00147 unsigned int CKWriteError; ///< Errors while writing the checksums' file. 00148 00149 /// Constructor. 00150 FilesStatistics() 00151 { 00152 FCorrect = 0; 00153 FReadError = 0; 00154 FNotFound = 0; 00155 FNotOpened = 0; 00156 FSkipped = 0; 00157 CKSkipped = 0; 00158 CKOverwritten = 0; 00159 CKCreated = 0; 00160 CKWriteError = 0; 00161 } 00162 00163 /// Gets the total of checksum's files checked. 00164 int getNbProcessedFiles() const 00165 { 00166 return FCorrect + FReadError + FNotFound + FNotOpened + FSkipped; 00167 } 00168 00169 /// Says if all the files in the checksums' file are corrects. 00170 bool allFileAreCorrects() const 00171 { 00172 return FReadError == 0 && FNotFound == 0 && FNotOpened == 0; 00173 } 00174 00175 /// Gets the number of checksums' files written 00176 int getNbProcessedChecksumsFiles() const 00177 { 00178 return CKOverwritten + CKCreated + CKSkipped + CKWriteError; 00179 } 00180 00181 /// Says if all the checksums' files are corrects. 00182 bool allChecksumsFilesAreCorrects() const 00183 { 00184 return CKWriteError == 0; 00185 } 00186 }; 00187 //--------------------------------------------------------------------------- 00188 00189 00190 00191 //########################################################################### 00192 // A progression updater for the ChecksumFileCalculator class 00193 //########################################################################### 00194 00195 /** 00196 * Displays the progression of the process of computing of a checksum. 00197 */ 00198 class dlgBatchCreation::ChecksumProgress : public ::ChecksumProgress 00199 { 00200 protected: 00201 BytesDisplayer current; ///< numbers of preceeded bytes. 00202 wxTimeSpan timeSpan; ///< Time between to updates of the progress dialog. 00203 wxDateTime lt; ///< Last saved time. 00204 wxDateTime ct; ///< Current time. 00205 dlgBatchCreation* progress; ///< Progress dialog (don't delete it!). 00206 00207 /// Default constructor. Don't call it. 00208 ChecksumProgress() { init(); }; 00209 00210 // Initializes the instance. 00211 void init(); 00212 00213 public: 00214 // Constructor. 00215 ChecksumProgress(dlgBatchCreation* progressDlg, const BytesDisplayer& total); 00216 00217 // Updates the progression of the computing of a checksum. 00218 virtual void update(size_t read, bool& canceled); 00219 00220 // Indicates that the process is finished (hides the progress dialog). 00221 void finished(); 00222 }; 00223 //--------------------------------------------------------------------------- 00224 00225 00226 /** 00227 * Initializes the instance. 00228 */ 00229 void dlgBatchCreation::ChecksumProgress::init() 00230 { 00231 progress = NULL; 00232 } 00233 //--------------------------------------------------------------------------- 00234 00235 00236 /** 00237 * Constructor. 00238 * 00239 * @param progressDlg Progress dialog to update. 00240 * @param total Total of bytes to process. 00241 */ 00242 dlgBatchCreation::ChecksumProgress::ChecksumProgress(dlgBatchCreation* progressDlg, const BytesDisplayer& total) 00243 { 00244 init(); 00245 00246 timeSpan = wxTimeSpan(0, 0, 0, UPDATE_PROGRESS_DLG); 00247 lt = wxDateTime::UNow() - timeSpan; 00248 progress = progressDlg; 00249 00250 // Display information 00251 progress->setReadBytes(current); 00252 progress->setTotalBytes(total); 00253 } 00254 //--------------------------------------------------------------------------- 00255 00256 00257 /** 00258 * Updates the progression of the computing of a checksum. 00259 * 00260 * @param read Number of bytes read. 00261 * @param canceled Set it to <CODE>true</CODE> if the user want to cancel 00262 * the calculation. The caller should call it with its value 00263 * set to <CODE>false</CODE>. 00264 */ 00265 void dlgBatchCreation::ChecksumProgress::update(size_t read, bool& canceled) 00266 { 00267 current += static_cast<unsigned long>(read); 00268 ct = wxDateTime::UNow(); 00269 if (ct.IsLaterThan(lt)) 00270 { 00271 progress->setReadBytes(current); 00272 ::wxYield(); 00273 lt = ct + timeSpan; 00274 } 00275 00276 // Pause ? 00277 while (progress->getState() == dlgBatchCreation::paused) 00278 ::wxYield(); 00279 00280 // Canceled ? 00281 if (progress->getState() == dlgBatchCreation::canceled) 00282 canceled = true; 00283 } 00284 //--------------------------------------------------------------------------- 00285 00286 00287 /** 00288 * Indicates that the process is finished (hides the progress dialog). 00289 */ 00290 void dlgBatchCreation::ChecksumProgress::finished() 00291 { 00292 progress->setReadBytes(current); 00293 ::wxYield(); 00294 } 00295 //--------------------------------------------------------------------------- 00296 00297 00298 00299 //########################################################################### 00300 // dlgBatchCreation methods 00301 //########################################################################### 00302 00303 IMPLEMENT_DYNAMIC_CLASS(dlgBatchCreation, dlgResultsProgress) 00304 00305 00306 /// Gauges limits 00307 #define GAUGE_MAX SHRT_MAX 00308 00309 /// Gauges limits (double value) 00310 #define DGAUGE_MAX static_cast<double>(GAUGE_MAX) 00311 //--------------------------------------------------------------------------- 00312 00313 00314 /** 00315 * Creates a new dialog. 00316 */ 00317 dlgBatchCreation::dlgBatchCreation() : dlgResultsProgress() 00318 { 00319 winDisabler = NULL; 00320 createControls(); 00321 } 00322 //--------------------------------------------------------------------------- 00323 00324 00325 /** 00326 * Creates a new dialog. 00327 * 00328 * @param parent Parent of the dialog. 00329 */ 00330 dlgBatchCreation::dlgBatchCreation(wxWindow* parent) : 00331 dlgResultsProgress(parent, -1, _("Batch creation of checksums' files"), 00332 wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) 00333 { 00334 createControls(); 00335 Fit(); 00336 00337 // Change the size of the dialog. 00338 wxSize s = AppPrefs::get()->readSize(prBC_WINDOW_SIZE); 00339 if (s.GetWidth() == -1 || s.GetHeight() == -1) 00340 { 00341 if (GetParent() != NULL) 00342 SetSize(GetParent()->GetSize()); 00343 } 00344 else 00345 SetSize(s); 00346 Centre(); 00347 00348 Show(true); 00349 Enable(true); 00350 ::wxYield(); 00351 #ifdef __WXMAC__ 00352 MacUpdateImmediately(); 00353 #endif 00354 } 00355 //--------------------------------------------------------------------------- 00356 00357 00358 /** 00359 * Creates and initializes the controls of the dialog. 00360 */ 00361 void dlgBatchCreation::createControls() 00362 { 00363 // Creates the controls 00364 wxClientDC dc(txtResults); 00365 wxSize labelSize(dc.GetCharWidth() * 20, -1); 00366 00367 wxStaticText* lblCurTotal = new wxStaticText(this, -1, _("Creating:")); 00368 lblTotal = new wxStaticText(this, -1, wxEmptyString, wxDefaultPosition, 00369 labelSize, wxALIGN_RIGHT | wxST_NO_AUTORESIZE); 00370 gauTotal = new wxGauge(this, -1, 0, wxDefaultPosition, wxSize(-1, lblTotal->GetSize().GetHeight()), 00371 wxGA_HORIZONTAL | wxGA_SMOOTH); 00372 gauTotal->SetRange(GAUGE_MAX); 00373 wxStaticText* lblCurFile = new wxStaticText(this, -1, _("Current file:")); 00374 lblFile = new wxStaticText(this, -1, wxEmptyString, wxDefaultPosition, 00375 labelSize, wxALIGN_RIGHT | wxST_NO_AUTORESIZE); 00376 gauFile = new wxGauge(this, -1, 0, wxDefaultPosition, wxSize(-1, lblFile->GetSize().GetHeight()), 00377 wxGA_HORIZONTAL | wxGA_SMOOTH); 00378 gauFile->SetRange(GAUGE_MAX); 00379 00380 //------------------------------------------------------------------------- 00381 // Creates the dialog sizers 00382 00383 // Progress section 00384 wxFlexGridSizer* progressSizer = new wxFlexGridSizer(3, CONTROL_SPACE / 2, CONTROL_SPACE); 00385 infoSizer->Add(progressSizer, 0, wxTOP | wxGROW, 3 * CONTROL_SPACE / 2); 00386 progressSizer->AddGrowableCol(2); 00387 progressSizer->Add(lblCurTotal, 0, wxALIGN_CENTER_VERTICAL); 00388 progressSizer->Add(lblTotal, 0, wxALIGN_CENTER_VERTICAL); 00389 progressSizer->Add(gauTotal, 1, wxALIGN_CENTER_VERTICAL | wxGROW); 00390 progressSizer->Add(lblCurFile, 0, wxALIGN_CENTER_VERTICAL); 00391 progressSizer->Add(lblFile, 0, wxALIGN_CENTER_VERTICAL); 00392 progressSizer->Add(gauFile, 1, wxALIGN_CENTER_VERTICAL | wxGROW); 00393 00394 // Set on the auto-layout feature 00395 this->SetAutoLayout(true); 00396 this->Layout(); 00397 00398 00399 //------------------------------------------------------------------------- 00400 // Initializes the controls 00401 setFilesToProcess(0); 00402 setTotalBytes(BytesDisplayer(0UL)); 00403 } 00404 //--------------------------------------------------------------------------- 00405 00406 00407 /** 00408 * Processes button Cancel. 00409 * 00410 * @param event The event's parameters 00411 */ 00412 void dlgBatchCreation::btnCancelClick(wxCommandEvent& event) 00413 { 00414 if (getState() == finished) 00415 { 00416 // Save the dialog size. 00417 AppPrefs::get()->write(prBC_WINDOW_SIZE, GetSize()); 00418 } 00419 00420 // Let the default handler do the job. 00421 event.Skip(); 00422 } 00423 //--------------------------------------------------------------------------- 00424 00425 00426 /** 00427 * Gets the number of files to process. 00428 * 00429 * @return The number of files to process. 00430 */ 00431 unsigned long dlgBatchCreation::getFilesToProcess() const 00432 { 00433 return filesToProcess; 00434 } 00435 //--------------------------------------------------------------------------- 00436 00437 00438 /** 00439 * // Sets the number of files to process. 00440 * 00441 * @param nbTotalFiles Number of files to process. 00442 */ 00443 void dlgBatchCreation::setFilesToProcess(unsigned long nbTotalFiles) 00444 { 00445 filesToProcess = nbTotalFiles; 00446 if (getFileToBeProcessed() > getFilesToProcess()) 00447 setFileToBeProcessed(getFilesToProcess()); 00448 00449 updateTotalFiles(); 00450 } 00451 //--------------------------------------------------------------------------- 00452 00453 00454 /** 00455 * Gets the number of the current file to be processed. 00456 * 00457 * @return The number of the current file to be processed. 00458 */ 00459 unsigned long dlgBatchCreation::getFileToBeProcessed() const 00460 { 00461 return fileProcessed; 00462 } 00463 //--------------------------------------------------------------------------- 00464 00465 00466 /** 00467 * Sets the number of the file to be processed. 00468 * 00469 * @param nbFiles The number of the current file to process. 00470 */ 00471 void dlgBatchCreation::setFileToBeProcessed(unsigned long nbFiles) 00472 { 00473 fileProcessed = (getFilesToProcess() >= nbFiles) ? nbFiles : getFilesToProcess(); 00474 updateTotalFiles(); 00475 } 00476 //--------------------------------------------------------------------------- 00477 00478 00479 /** 00480 * Gets the number of bytes of the current processed file. 00481 * 00482 * @return The number of bytes of the current processed file. 00483 */ 00484 BytesDisplayer dlgBatchCreation::getTotalBytes() const 00485 { 00486 return totalBytes; 00487 } 00488 //--------------------------------------------------------------------------- 00489 00490 00491 /** 00492 * Sets the number of bytes of the current processed file. 00493 * 00494 * @param bytes The number of bytes of the current processed file. 00495 */ 00496 void dlgBatchCreation::setTotalBytes(const BytesDisplayer& bytes) 00497 { 00498 totalBytes = bytes; 00499 if (getReadBytes().toDouble() > getTotalBytes().toDouble()) 00500 setReadBytes(getTotalBytes()); 00501 00502 updateCurrentProcessedFile(); 00503 } 00504 //--------------------------------------------------------------------------- 00505 00506 00507 /** 00508 * Gets the number of bytes read of the current processed file. 00509 * 00510 * @return The number of bytes read of the current processed file. 00511 */ 00512 BytesDisplayer dlgBatchCreation::getReadBytes() const 00513 { 00514 return bytesRead; 00515 } 00516 //--------------------------------------------------------------------------- 00517 00518 00519 /** 00520 * Sets the number of bytes read of the current processed file. 00521 * 00522 * @param bytes The number of bytes read of the current processed file. 00523 */ 00524 void dlgBatchCreation::setReadBytes(const BytesDisplayer& bytes) 00525 { 00526 bytesRead = (getTotalBytes().toDouble() >= bytes.toDouble()) ? bytes : getTotalBytes(); 00527 updateCurrentProcessedFile(); 00528 } 00529 //--------------------------------------------------------------------------- 00530 00531 00532 /** 00533 * Update the information of the total of the files to be processed. 00534 */ 00535 void dlgBatchCreation::updateTotalFiles() 00536 { 00537 lblTotal->SetLabel(wxString::Format(_("%d/%d"), getFileToBeProcessed(), getFilesToProcess())); 00538 double gauTotalValue = (getFileToBeProcessed() > 0) ? static_cast<double>(getFileToBeProcessed() - 1) : 0.0; 00539 00540 if (getFilesToProcess() > 0) 00541 gauTotal->SetValue(static_cast<int>(gauTotalValue * DGAUGE_MAX / static_cast<double>(getFilesToProcess()))); 00542 else 00543 gauTotal->SetValue(0); 00544 00545 // Refresh the dialog 00546 refreshDialog(); 00547 } 00548 //--------------------------------------------------------------------------- 00549 00550 00551 /** 00552 * Update the information of the current processed file. 00553 */ 00554 void dlgBatchCreation::updateCurrentProcessedFile() 00555 { 00556 // Updating current file label 00557 lblFile->SetLabel(wxString::Format(_("%s/%s"), getReadBytes().toString().c_str(), getTotalBytes().toString().c_str())); 00558 00559 // Computing gauges initial values (in interval [0.0...1.0]) 00560 double gauFileValue = (getTotalBytes().toDouble() > 0.0) ? getReadBytes().toDouble() / getTotalBytes().toDouble() : 0.0; 00561 00562 double gauTotalValue = (getFileToBeProcessed() > 0) ? static_cast<double>(getFileToBeProcessed() - 1) : 0.0; 00563 gauTotalValue += gauFileValue; 00564 gauTotalValue = (getFilesToProcess() > 0) ? gauTotalValue / static_cast<double>(getFilesToProcess()) : 0.0; 00565 00566 // Changing gauges values 00567 int intFileValue = static_cast<int>(gauFileValue * DGAUGE_MAX); 00568 int intTotal = static_cast<int>(gauTotalValue * DGAUGE_MAX); 00569 00570 if (gauFile->GetValue() != intFileValue) 00571 gauFile->SetValue(intFileValue); 00572 if (gauTotal->GetValue() != intTotal) 00573 gauTotal->SetValue(intTotal); 00574 00575 // Refresh the dialog 00576 refreshDialog(); 00577 } 00578 //--------------------------------------------------------------------------- 00579 00580 00581 /** 00582 * Gets the names of the checksums' files to create. 00583 * 00584 * @param srcFileName Name of the source file. 00585 * @param options Options for the batch creation of the checksums' files. 00586 * @param ckSumsTypes Array of checksums' file types to create. 00587 * @return A array of strings which contains the names of the checksums' files 00588 * to create. 00589 */ 00590 wxArrayString dlgBatchCreation::getChecksumsFileNames(const wxString& srcFileName, 00591 const dlgBatchCreation::Options& options, 00592 const wxArrayInt& ckSumsTypes) 00593 { 00594 wxArrayString res; 00595 00596 for (size_t i = 0; i < ckSumsTypes.GetCount(); i++) 00597 { 00598 if (options.replaceExtension) 00599 { 00600 wxFileName fn(srcFileName); 00601 fn.SetExt(SumFileFactory::getSumFileExtension(ckSumsTypes[i])); 00602 res.Add(fn.GetFullPath()); 00603 } 00604 else 00605 res.Add(srcFileName + wxT('.') + SumFileFactory::getSumFileExtension(ckSumsTypes[i])); 00606 } 00607 00608 return res; 00609 } 00610 //--------------------------------------------------------------------------- 00611 00612 00613 /** 00614 * Indicates if all the checksums' files exist. 00615 * 00616 * @param srcFileName Name of the source file. 00617 * @param options Options for the batch creation of the checksums' files. 00618 * @param ckSumsTypes Array of checksums' file types to create. 00619 * @return <CODE>true</CODE> if all the checksums' files exist, 00620 * <CODE>false</CODE> otherwise. 00621 */ 00622 bool dlgBatchCreation::allChecksumsFileNamesExist(const wxString& srcFileName, 00623 const dlgBatchCreation::Options& options, 00624 const wxArrayInt& ckSumsTypes) 00625 { 00626 wxArrayString fileNames = getChecksumsFileNames(srcFileName, options, ckSumsTypes); 00627 00628 bool oneDontExist = false; 00629 size_t i = 0; 00630 while (!oneDontExist && i < fileNames.GetCount()) 00631 if (::wxFileExists(fileNames[i])) 00632 i++; 00633 else 00634 oneDontExist = true; 00635 00636 return !oneDontExist; 00637 } 00638 //--------------------------------------------------------------------------- 00639 00640 00641 /** 00642 * Saves the given sums in checksums files. 00643 * 00644 * @param srcFileName Name of the source file. 00645 * @param options Options for the batch creation of the checksums' files. 00646 * @param ckSumsTypes Array of checksums' file types to create. 00647 * @param sumFiles Array of <CODE>SumFile</CODE> for each checksum type. 00648 * @param sums Checksums values for each checksum type. 00649 * @param fstats Statistics on the files. 00650 * @param dlgPrg Progression dialog. 00651 */ 00652 void dlgBatchCreation::saveChecksumsInFiles(const wxString& srcFileName, 00653 const dlgBatchCreation::Options& options, 00654 const wxArrayInt& ckSumsTypes, 00655 const ArraySumFile& sumFiles, 00656 const wxArrayString& sums, 00657 dlgBatchCreation::FilesStatistics& fstats, 00658 dlgBatchCreation* dlgPrg) 00659 { 00660 wxArrayString fileNames = getChecksumsFileNames(srcFileName, options, ckSumsTypes); 00661 00662 for (size_t i = 0; i < ckSumsTypes.GetCount(); i++) 00663 { 00664 bool fileExists = ::wxFileExists(fileNames[i]); 00665 if (fileExists && !options.ovrCkFileWhenItExists) 00666 { 00667 // The checksums' file already exists, skipping. 00668 if (options.getVerbosity() >= dlgBatchCreation::vWarnings) 00669 dlgPrg->addResultLine(wxString::Format(_("'%s' already exists. Skipping.\n"), fileNames[i].c_str()), 1U, getColour(prBC_WARNING_COLOUR)); 00670 fstats.CKSkipped++; 00671 } 00672 else // create or overwrite the checksums' file. 00673 { 00674 sumFiles[i]->setFileName(fileNames[i]); 00675 sumFiles[i]->addChecksumData(ChecksumData(srcFileName, sums[i], ChecksumData::Verified)); 00676 00677 if (sumFiles[i]->write(fileNames[i])) 00678 // The checksums' file has been successfully created. 00679 { 00680 wxColour c; 00681 bool addNewLine = false; 00682 if (fileExists) 00683 // The checksums' file has been overwritten. 00684 { 00685 if (options.getVerbosity() >= dlgBatchCreation::vWarnings) 00686 { 00687 c = getColour(prBC_WARNING_COLOUR); 00688 dlgPrg->addResultLine(wxString::Format(_("'%s' has been overwritten."), fileNames[i].c_str()), 1U, c); 00689 addNewLine = true; 00690 } 00691 fstats.CKOverwritten++; 00692 } 00693 else // the checksums' file has been created. 00694 { 00695 if (options.getVerbosity() >= dlgBatchCreation::vNormal) 00696 { 00697 c = getColour(prBC_SUCCESS_COLOUR); 00698 dlgPrg->addResultLine(wxString::Format(_("'%s' has been created."), fileNames[i].c_str()), 1U, c); 00699 addNewLine = true; 00700 } 00701 fstats.CKCreated++; 00702 } 00703 if (options.getVerbosity() >= dlgBatchCreation::vTalkative) 00704 dlgPrg->addResultLine(wxString::Format(wxString(wxT(' ')) + _("(Checksum value : %s)."), sums[i].c_str()), 0U, c); 00705 if (addNewLine) 00706 dlgPrg->addResultLine(wxString::Format(wxT("\n"), sums[i].c_str()), 0U, c); 00707 } 00708 else // error while creating the checksums' file. 00709 { 00710 if (options.getVerbosity() >= dlgBatchCreation::vErrors) 00711 dlgPrg->addResultLine(wxString::Format(_("Error while writing '%s'.\n"), fileNames[i].c_str()), 1U, getColour(prBC_ERROR_COLOUR)); 00712 fstats.CKWriteError++; 00713 } 00714 } 00715 } 00716 } 00717 //--------------------------------------------------------------------------- 00718 00719 00720 /** 00721 * Checks multiple checksums' files. 00722 * 00723 * @param files List of the files from which the checksums' files will 00724 * be created. 00725 * @param options Options for the batch creation of the checksums' files. 00726 * @param ckSumsTypes Array of checksums' file types to create. 00727 * @param parent Parent of the dialog that will be created. 00728 */ 00729 void dlgBatchCreation::batchCreation(const wxArrayString& files, 00730 const Options& options, 00731 wxArrayInt ckSumsTypes, 00732 wxWindow* parent) 00733 { 00734 FilesStatistics fstats; 00735 dlgBatchCreation dlgPrg(parent); 00736 wxArrayString sums; 00737 ArraySumFile sumFiles; 00738 ArrayChecksum checksums; 00739 size_t i, j; 00740 wxString msg; 00741 00742 // No log 00743 wxLogNull logNo; 00744 00745 // Suppressing invalids values in ckSumsTypes 00746 i = 0; 00747 while (i < ckSumsTypes.GetCount()) 00748 if (SumFileFactory::exists(ckSumsTypes[i])) 00749 i++; 00750 else 00751 ckSumsTypes.RemoveAt(i); 00752 00753 dlgPrg.setFilesToProcess(files.GetCount()); 00754 i = 0; 00755 while (i < files.GetCount() && dlgPrg.canContinue()) 00756 { 00757 // Initialize parameters that will be used to compute the checksums 00758 wxFileName fn(files[i]); 00759 for (j = 0; j < ckSumsTypes.GetCount(); j++) 00760 { 00761 sumFiles.Add(SumFileFactory::getSumFileNewInstance(ckSumsTypes[j])); 00762 checksums.Add(sumFiles[j]->getChecksumCalculator()); 00763 } 00764 00765 // Display information 00766 dlgPrg.addResultLine(wxString::Format(_("Processing '%s'.\n"), files[i].c_str()), 0U, getColour(prBC_NORMAL_COLOUR)); 00767 dlgPrg.setFileToBeProcessed(i + 1); 00768 00769 // Checks if all the target checksums' files exists 00770 if (allChecksumsFileNamesExist(fn.GetFullPath(), options, ckSumsTypes) && 00771 !options.ovrCkFileWhenItExists) 00772 { 00773 fstats.FSkipped++; 00774 fstats.CKSkipped += static_cast<unsigned int>(ckSumsTypes.GetCount()); 00775 if (options.getVerbosity() >= dlgBatchCreation::vWarnings) 00776 dlgPrg.addResultLine(_("All the checksums' files exist. Skipping.\n"), 1U, getColour(prBC_WARNING_COLOUR)); 00777 } 00778 else // creating the checksums' files. 00779 { 00780 wxCOff_t fs; // size of the file to read. 00781 BytesDisplayer total; // total of bytes to process. 00782 ChecksumFileCalculator::State retState; // state returned by the checksum' calculator. 00783 00784 fs = wxCGetFileLength(fn.GetFullPath()); // get the length of the file to read 00785 total = (fs == static_cast<wxCOff_t>(wxInvalidOffset)) ? 0.0 : static_cast<double>(fs); 00786 00787 ChecksumProgress progressUpdater(&dlgPrg, total); 00788 ChecksumFileCalculator cfc; 00789 cfc.setChecksumProgress(&progressUpdater); 00790 00791 // Check the file. 00792 retState = cfc.calculate(fn.GetFullPath(), checksums, sums); 00793 00794 // Update the progress dialog 00795 progressUpdater.finished(); 00796 00797 switch (retState) 00798 { 00799 case ChecksumFileCalculator::Ok : // Checksum has been calculated. 00800 fstats.FCorrect++; 00801 saveChecksumsInFiles(fn.GetFullPath(), options, ckSumsTypes, 00802 sumFiles, sums, fstats, &dlgPrg); 00803 break; 00804 00805 case ChecksumFileCalculator::ReadError : // Error while reading the stream. 00806 fstats.FNotFound++; 00807 if (options.getVerbosity() >= dlgBatchCreation::vErrors) 00808 dlgPrg.addResultLine(wxString::Format(_("Error while reading '%s'.\n"), fn.GetFullPath().c_str()), 1U, getColour(prBC_ERROR_COLOUR)); 00809 break; 00810 00811 case ChecksumFileCalculator::FileNotFound : // The file has been not found. 00812 fstats.FNotFound++; 00813 if (options.getVerbosity() >= dlgBatchCreation::vErrors) 00814 dlgPrg.addResultLine(wxString::Format(_("'%s': File not found.\n"), fn.GetFullPath().c_str()), 1U, getColour(prBC_ERROR_COLOUR)); 00815 break; 00816 00817 case ChecksumFileCalculator::CantOpenFile : // Can't open the stream. 00818 fstats.FNotOpened++; 00819 if (options.getVerbosity() >= dlgBatchCreation::vErrors) 00820 dlgPrg.addResultLine(wxString::Format(_("'%s': File cannot be opened.\n"), fn.GetFullPath().c_str()), 1U, getColour(prBC_ERROR_COLOUR)); 00821 break; 00822 } 00823 } 00824 00825 // Adds an end of line. 00826 dlgPrg.addResultLine(wxT("\n"), 0U, getColour(prBC_NORMAL_COLOUR)); 00827 00828 // Cleans-up the memory. 00829 WX_CLEAR_ARRAY(sumFiles) 00830 WX_CLEAR_ARRAY(checksums) 00831 00832 i++; 00833 } 00834 00835 if (dlgPrg.getState() != canceled) 00836 { 00837 // Some compilers don't like the ? : structure in function call, so using 00838 // this variable to store the result of ? : before the call. 00839 // Note : some versions of Borland C++ don't like nested ? : so using if else. 00840 wxColour colour; 00841 00842 // Display the global summary. 00843 dlgPrg.addResultLine(wxString::Format(_("Total file(s) processed: %d\n"), fstats.getNbProcessedFiles()), 0L, getColour(prBC_NORMAL_COLOUR)); 00844 if (fstats.allFileAreCorrects()) colour = getColour(prBC_SUCCESS_COLOUR); else if (fstats.FCorrect + fstats.FSkipped > 0 ) colour = getColour(prBC_WARNING_COLOUR); else colour = getColour(prBC_ERROR_COLOUR); 00845 dlgPrg.addResultLine(wxString::Format(_("Correct(s): %d"), fstats.FCorrect), 1L, colour); 00846 if (fstats.FSkipped > 0) 00847 dlgPrg.addResultLine(wxString::Format(wxString(wxT(' ')) + _("(Skipped: %d)"), fstats.FSkipped), 0L, getColour(prBC_WARNING_COLOUR)); 00848 dlgPrg.addResultLine(wxT("\n"), 0L, getColour(prBC_SUCCESS_COLOUR)); 00849 colour = (fstats.FNotFound == 0) ? getColour(prBC_SUCCESS_COLOUR) : getColour(prBC_ERROR_COLOUR); 00850 dlgPrg.addResultLine(wxString::Format(_("File(s) not found: %d\n"), fstats.FNotFound), 1U, colour); 00851 colour = (fstats.FNotOpened == 0) ? getColour(prBC_SUCCESS_COLOUR) : getColour(prBC_ERROR_COLOUR); 00852 dlgPrg.addResultLine(wxString::Format(_("File(s) not opened: %d\n"), fstats.FNotOpened), 1U, colour); 00853 colour = (fstats.FReadError == 0) ? getColour(prBC_SUCCESS_COLOUR) : getColour(prBC_ERROR_COLOUR); 00854 dlgPrg.addResultLine(wxString::Format(_("Error(s) while reading: %d\n"), fstats.FReadError), 1U, colour); 00855 00856 dlgPrg.addResultLine(wxString::Format(wxString(wxT('\n')) + _("Total checksums' file(s) processed: %d\n"), fstats.getNbProcessedChecksumsFiles()), 0L, getColour(prBC_NORMAL_COLOUR)); 00857 if (fstats.allChecksumsFilesAreCorrects()) colour = getColour(prBC_SUCCESS_COLOUR); else if (fstats.CKWriteError == fstats.getNbProcessedChecksumsFiles()) colour = getColour(prBC_ERROR_COLOUR); else colour = getColour(prBC_WARNING_COLOUR); 00858 dlgPrg.addResultLine(wxString::Format(_("Successfully processed: %d\n"), fstats.getNbProcessedChecksumsFiles() - fstats.CKWriteError), 1L, colour); 00859 if (fstats.CKCreated == fstats.getNbProcessedChecksumsFiles()) colour = getColour(prBC_SUCCESS_COLOUR); else if (fstats.CKCreated > 0 || (fstats.CKCreated == 0 && (fstats.CKSkipped > 0 || fstats.CKOverwritten > 0))) colour = getColour(prBC_WARNING_COLOUR); else colour = getColour(prBC_ERROR_COLOUR); 00860 dlgPrg.addResultLine(wxString::Format(_("Created: %d\n"), fstats.CKCreated), 2L, colour); 00861 if (fstats.CKSkipped == 0) if (fstats.CKCreated > 0 || fstats.CKOverwritten > 0) colour = getColour(prBC_SUCCESS_COLOUR); else colour = getColour(prBC_ERROR_COLOUR); else colour = getColour(prBC_WARNING_COLOUR); 00862 dlgPrg.addResultLine(wxString::Format(_("Skipped: %d\n"), fstats.CKSkipped), 2L, colour); 00863 if (fstats.CKOverwritten == 0) if (fstats.CKCreated > 0 || fstats.CKSkipped > 0) colour = getColour(prBC_SUCCESS_COLOUR); else colour = getColour(prBC_ERROR_COLOUR); else colour = getColour(prBC_WARNING_COLOUR); 00864 dlgPrg.addResultLine(wxString::Format(_("Overwritten: %d\n"), fstats.CKOverwritten), 2L, colour); 00865 colour = (fstats.CKWriteError == 0) ? getColour(prBC_SUCCESS_COLOUR) : getColour(prBC_ERROR_COLOUR); 00866 dlgPrg.addResultLine(wxString::Format(_("Error(s) while writing: %d\n"), fstats.CKWriteError), 1U, colour); 00867 00868 dlgPrg.Finished(); 00869 } 00870 } 00871 //--------------------------------------------------------------------------- 00872 00873 00874 BEGIN_EVENT_TABLE(dlgBatchCreation, dlgResultsProgress) 00875 EVT_BUTTON(wxID_CANCEL, dlgBatchCreation::btnCancelClick) 00876 END_EVENT_TABLE() 00877 //--------------------------------------------------------------------------- 00878

Generated on Sun May 30 13:37:44 2004 for wxChecksums by doxygen 1.3.7