00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
#include <wx/wxprec.h>
00029 
00030 
#ifdef __BORLANDC__
00031 
#pragma hdrstop
00032 
#endif
00033 
00034 
#ifndef WX_PRECOMP
00035 
00036 
#include <wx/wx.h>
00037 
#endif
00038 
00039 
#if wxUSE_DRAG_AND_DROP
00040 
#include <wx/dnd.h>
00041 
#endif  // wxUSE_DRAG_AND_DROP
00042 
#include <wx/datetime.h>
00043 
#include <wx/imaglist.h>
00044 
00045 
#include "lvwSums.hpp"
00046 
#include "dlgAddMatchFiles.hpp"
00047 
#include "dlgInvalidFiles.hpp"
00048 
#include "dlgProgress.hpp"
00049 
00050 
#include "appprefs.hpp"
00051 
#include "bytedisp.hpp"
00052 
#include "checksumutil.hpp"
00053 
#include "comdefs.hpp"
00054 
#include "fileutil.hpp"
00055 
#include "fdftlmk.hpp"
00056 
#include "osdep.hpp"
00057 
#include "sumfile.hpp"
00058 
#include "utils.hpp"
00059 
00060 
#include "bitmaps/lvw_sums_notverified.xpm"
00061 
#include "bitmaps/lvw_sums_verified.xpm"
00062 
#include "bitmaps/lvw_sums_invalid.xpm"
00063 
#include "bitmaps/lvw_sums_notfound.xpm"
00064 
#include "bitmaps/hi16_action_fileadd.xpm"
00065 
#include "bitmaps/hi16_action_directoryadd.xpm"
00066 
#include "bitmaps/hi16_action_addmatchingfiles.xpm"
00067 
#include "bitmaps/hi16_action_fileremove.xpm"
00068 
00069 
#include "compat.hpp"
00070 
00071 
00072 
00073 
00074 
using namespace std;
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 BEGIN_DECLARE_EVENT_TYPES()
00087     DECLARE_EVENT_TYPE(EVENT_DNDFILES_COMMAND, 10001)
00088 END_DECLARE_EVENT_TYPES()
00089 
00090 DEFINE_EVENT_TYPE(EVENT_DNDFILES_COMMAND)
00091 
00092 
00093 
00094 
00095 
00096 
00097 DEFINE_LOCAL_EVENT_TYPE(EVENT_UPDATE_SUMS_FRAME_TITLE_COMMAND)
00098 
00099 
00100 
00101 
00102 
00103 DEFINE_LOCAL_EVENT_TYPE(EVENT_UPDATE_SUMS_FRAME_STATUSBAR_COMMAND)
00104 
00105 
00106 
00107 
00108 DEFINE_LOCAL_EVENT_TYPE(EVENT_OPEN_RECENT_ADD_FILE)
00109 
00110 
00111 
00112 
00113 
00114 #if wxUSE_DRAG_AND_DROP
00115 
00116 
00117 
00118 class DndCheckSumListView : public wxFileDropTarget
00119 {
00120  
public:
00121   
00122   DndCheckSumListView(
ChecksumsListView *pOwner);
00123 
00124   
00125   
virtual bool OnDropFiles(wxCoord x, wxCoord y, 
const wxArrayString& filenames);
00126 
00127  
private:
00128   
ChecksumsListView* owner;  
00129 };
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 DndCheckSumListView::DndCheckSumListView(
ChecksumsListView *pOwner)
00139 {
00140   owner = pOwner;
00141 }
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 
bool DndCheckSumListView::OnDropFiles(wxCoord x, wxCoord y, 
const wxArrayString& filenames)
00157 {
00158   
if (owner != NULL)
00159   {   
00160 
00161 
00162     wxArrayString* f = 
new wxArrayString(filenames);
00163 
00164     wxCommandEvent event(EVENT_DNDFILES_COMMAND);
00165     event.SetClientData(f);
00166     owner->AddPendingEvent(event);
00167   }
00168 
00169   
return true;
00170 }
00171 
00172 
00173 
#endif  // wxUSE_DRAG_AND_DROP
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 class ChecksumsListView::ChecksumProgress : 
public ::
ChecksumProgress
00185 {
00186  
protected:
00187   wxString       
fileName;   
00188   wxString       
msg;        
00189   BytesDisplayer current;    
00190   double         dTotal;     
00191   wxString       
sTotal;     
00192   int            p;          
00193   wxTimeSpan     
timeSpan;   
00194   wxDateTime     
lt;         
00195   wxDateTime     
ct;         
00196   dlgProgress*   
progress;   
00197   int            maxProgress;    
00198   int            maxProgressM1;  
00199   double         maxProgressD;   
00200   
00201 
00202   ChecksumProgress() { 
init(); };
00203   
00204   
00205   
void init();
00206   
00207  
public:
00208   
00209   
ChecksumProgress(
const wxString& message, 
const wxString& title, wxWindow* parent, 
const BytesDisplayer& total);
00210   
00211   
00212   
virtual ~ChecksumProgress();
00213   
00214   
00215   
virtual void update(size_t read, 
bool& canceled);
00216   
00217   
00218   
void finished();
00219   
00220   
00221   wxString 
getFileName() const;
00222   
00223   
00224   
void setFileName(const wxString& curFileName);
00225 };
00226 
00227 
00228 
00229 
00230 
00231 
00232 void ChecksumsListView::
ChecksumProgress::init()
00233 {
00234   
progress = NULL;
00235 }
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 ChecksumsListView::ChecksumProgress::ChecksumProgress(
const wxString& message, 
const wxString& title, wxWindow* parent, 
const BytesDisplayer& total)
00250 {
00251   
init();
00252 
00253   
msg = message;
00254   
dTotal = total.
toDouble(BytesDisplayer::byte);
00255   
sTotal = total.
toString();
00256   
maxProgress = SHRT_MAX;
00257   
maxProgressM1 = 
maxProgress - 1;
00258   
maxProgressD = static_cast<double>(maxProgress);
00259   
timeSpan = wxTimeSpan(0, 0, 0, 
UPDATE_PROGRESS_DLG);
00260   
lt = wxDateTime::UNow() - 
timeSpan;
00261   
progress = 
new dlgProgress(title, _(
"Beginning..."), maxProgress, parent,
00262     wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME);
00263 }
00264 
00265 
00266 
00267 
00268 
00269 
00270 ChecksumsListView::ChecksumProgress::~ChecksumProgress()
00271 {
00272   
if (
progress != NULL)
00273   {
00274     
delete progress;
00275     
progress = NULL;
00276   }
00277 }
00278 
00279 
00280   
00281 
00282 
00283 
00284 
00285 
00286 
00287 
00288 
00289 void ChecksumsListView::ChecksumProgress::update(size_t read, 
bool& canceled)
00290 {
00291   
current += static_cast<unsigned long>(read);
00292   
p = (
dTotal != 0.0) ? static_cast<int>(
current.
toDouble(BytesDisplayer::byte) * 
maxProgressD / 
dTotal) : 
maxProgress;
00293   
if (
p >= 
maxProgress)
00294     
p = 
maxProgressM1;
00295   
ct = wxDateTime::UNow();
00296   
if (
ct.IsLaterThan(
lt))
00297   {
00298     canceled = !
progress->
Update(
p, wxString::Format(
msg, 
fileName.c_str(), 
current.
toString().c_str(), 
sTotal.c_str()));
00299     ::wxYield();
00300     
lt = 
ct + 
timeSpan;
00301   }
00302   
00303   
00304   
while (
progress->
isPaused())
00305     ::wxYield();
00306 }
00307 
00308 
00309   
00310 
00311 
00312 
00313 void ChecksumsListView::ChecksumProgress::finished()
00314 {
00315   
progress->
Update(
maxProgress, _(
"Finished"));
00316 }
00317 
00318 
00319   
00320 
00321 
00322 
00323 
00324 
00325 wxString 
ChecksumsListView::ChecksumProgress::getFileName()
 const
00326 
{
00327   
return fileName;
00328 }
00329 
00330 
00331   
00332 
00333 
00334 
00335 
00336 
00337 void ChecksumsListView::ChecksumProgress::setFileName(
const wxString& curFileName)
00338 {
00339   
fileName = curFileName;
00340 }
00341 
00342 
00343 
00344 
00345 
00346 
00347 
00348 
00349 IMPLEMENT_DYNAMIC_CLASS(
ChecksumsListView, wxListView)
00350 
00351 
00352 
00353 
00354 
00355 ChecksumsListView::
ChecksumsListView() : wxListView()
00356 {
00357   
init();
00358   
sumFile = NULL;
00359 }
00360 
00361 
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369 
00370 
00371 
00372 
00373 
00374 
00375 
00376 
00377 ChecksumsListView::ChecksumsListView(wxWindow* parent, wxWindowID 
id,
00378                                      
SumFile* checksumFile, 
const wxPoint& pos,
00379                                      
const wxSize& size, 
long style,
00380                                      
const wxValidator& validator,
00381                                      
const wxString& name) :
00382                     wxListView(parent, id, pos, size, style, validator, name)
00383 {
00384   
init();
00385   
sumFile = checksumFile;
00386 }
00387 
00388 
00389 
00390 
00391 
00392 
00393 ChecksumsListView::~ChecksumsListView()
00394 {
00395   
if (
sumFile != NULL)
00396   {
00397     
delete sumFile;
00398     
sumFile = NULL;
00399   }
00400 }
00401 
00402 
00403 
00404 
00405 
00406 
00407 void ChecksumsListView::init()
00408 {
00409   
00410   
00411   wxImageList* imlStateIcons = 
new wxImageList(16, 16);
00412   imlStateIcons->Add(wxIcon(lvw_sums_notverified_xpm));
00413   imlStateIcons->Add(wxIcon(lvw_sums_verified_xpm));
00414   imlStateIcons->Add(wxIcon(lvw_sums_invalid_xpm));
00415   imlStateIcons->Add(wxIcon(lvw_sums_notfound_xpm));
00416 
00417   
setColumnToSort(0, NONE);
00418   AssignImageList(imlStateIcons, wxIMAGE_LIST_SMALL);
00419   
00420 
  #if wxUSE_DRAG_AND_DROP
00421 
  SetDropTarget(
new DndCheckSumListView(
this));
00422 
  #endif  // wxUSE_DRAG_AND_DROP
00423 
00424   
columns[0] = FILE_NAME;
00425   
columns[1] = DIRECTORY;
00426   
columns[2] = CHECKSUM_VALUE;
00427   
columns[3] = STATE;
00428   InsertColumn(0, 
getColumnName(
columns[0]), wxLIST_FORMAT_LEFT);
00429   InsertColumn(1, 
getColumnName(
columns[1]), wxLIST_FORMAT_LEFT);
00430   InsertColumn(2, 
getColumnName(
columns[2]), wxLIST_FORMAT_LEFT);
00431   InsertColumn(3, 
getColumnName(
columns[3]), wxLIST_FORMAT_LEFT);
00432 }
00433 
00434 
00435 
00436 
00437 
00438 
00439 
00440 
00441 ChecksumsListView::SortOrder ChecksumsListView::getSortOrder()
 const
00442 
{
00443   
return sortOrder;
00444 }
00445 
00446 
00447   
00448 
00449 
00450 
00451 
00452 
00453 
00454 
00455 void ChecksumsListView::setSortOrder(
const SortOrder newSortOrder)
00456 {
00457   
switch (newSortOrder)
00458   {
00459     
case NONE :
00460     
case ASCENDING :
00461     
case DESCENDING :
00462       
sortOrder = newSortOrder;
00463       
break;
00464     
default :
00465       
sortOrder = NONE;
00466   }
00467 }
00468 
00469 
00470 
00471 
00472 
00473 
00474 
00475 
00476 int ChecksumsListView::getColumnToSort()
 const
00477 
{
00478   
return colToSort;
00479 }
00480 
00481 
00482 
00483 
00484 
00485 
00486 
00487 
00488 
00489 void ChecksumsListView::setColumnToSort(
const int col)
00490 {
00491   
if (col >= 0 && col < GetColumnCount())
00492     
colToSort = col;
00493   
else
00494     
colToSort = 0;
00495 }
00496 
00497 
00498 
00499 
00500 
00501 
00502 
00503 
00504 
00505 
00506 void ChecksumsListView::setColumnToSort(
const int col, 
const SortOrder newSortOrder)
00507 {
00508   
setColumnToSort(col);
00509   
setSortOrder(newSortOrder);
00510 }
00511 
00512 
00513 
00514 
00515 
00516 
00517 
00518 
00519 
00520 
00521 
00522 
00523 
00524 static int wxCALLBACK 
SumListCompareFnct(
long item1, 
long item2, 
long sortData)
00525 {
00526   
ChecksumsListView* pList = reinterpret_cast<ChecksumsListView*>(sortData);
00527 
00528   
00529   
ChecksumData cd1 = pList->
getSumFile()->
getChecksumData(item1);
00530   
ChecksumData cd2 = pList->
getSumFile()->
getChecksumData(item2);
00531 
00532   
00533   
int colToSort = pList->
getColumnToSort();
00534   ChecksumsListView::SortOrder sortOrder = pList->
getSortOrder();
00535 
00536   
00537   
if (sortOrder == ChecksumsListView::NONE)
00538   
00539     
return item1 - item2;
00540 
00541   
int res;
00542   ChecksumsListView::Columns cols[
LVW_SUMS_NBCOLS];
00543   pList->
getColumns(cols);
00544   
switch (cols[colToSort])
00545   {
00546     
case ChecksumsListView::FILE_NAME :
00547       res = ::compareFileName(cd1.
getFileName().GetFullName(), cd2.
getFileName().GetFullName());
00548       
break;
00549     
case ChecksumsListView::DIRECTORY : { 
00550       wxFileName fn1 = cd1.
getFileName();
00551       wxFileName fn2 = cd2.
getFileName();
00552       wxFileName sumFileName = pList->
getSumFile()->
getFileName();
00553 
00554       
if (
AppPrefs::get()->
readBool(prGUI_MAIN_SUMS_DIRSINABSOLUTEPATH))
00555       {
00556         
if (fn1.IsRelative())
00557           fn1.MakeAbsolute(sumFileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00558         
if (fn2.IsRelative())
00559           fn2.MakeAbsolute(sumFileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00560       }
00561       
else
00562       {
00563         
if (fn1.IsAbsolute())
00564           fn1.MakeRelativeTo(sumFileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00565         
if (fn2.IsAbsolute())
00566           fn2.MakeRelativeTo(sumFileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00567       }
00568       res = ::compareFileName(fn1.GetPath(wxPATH_GET_VOLUME), fn2.GetPath(wxPATH_GET_VOLUME)); }
00569       
break;
00570     
case ChecksumsListView::CHECKSUM_VALUE :
00571       res = cd1.
getChecksum().Cmp(cd2.
getChecksum());
00572       
break;
00573     
case ChecksumsListView::STATE :
00574       res = static_cast<int>(cd1.
getState()) - static_cast<int>(cd2.
getState());
00575       
break;
00576   }
00577 
00578   
if (sortOrder == ChecksumsListView::DESCENDING)
00579     res = -res;
00580 
00581   
return res;
00582 }
00583 
00584 
00585 
00586 
00587 
00588 
00589 void ChecksumsListView::sort()
00590 {
00591   
if (this->
getSumFile() != NULL)
00592   {
00593     wxBusyCursor wait;
00594     this->Freeze();
00595     this->SortItems(
SumListCompareFnct, reinterpret_cast<long>(
this));
00596     this->Thaw();
00597   }
00598 }
00599 
00600 
00601 
00602 
00603 
00604 
00605 
00606 
00607 SumFile* 
ChecksumsListView::getSumFile()
 const
00608 
{
00609   
return sumFile;
00610 }
00611 
00612 
00613 
00614 
00615 
00616 
00617 
00618 
00619 
00620 
00621 
00622 
00623 
00624 
00625 void ChecksumsListView::setSumFile(
SumFile* pSumFile)
00626 {
00627   
00628   
if (
sumFile == pSumFile)
00629     
return;
00630 
00631   
if (
sumFile != NULL)
00632     
delete sumFile;
00633 
00634   this->DeleteAllItems();
00635   
sumFile = pSumFile;
00636   
if (
sumFile != NULL)
00637   {
00638     MChecksumDataKeys keys;
00639     
sumFile->
getChecksumDataKeys(keys);
00640     size_t i, l = keys.GetCount();
00641     
for (i = 0; i < l; i++)
00642       
addChecksum(keys[i], _(
"Not verified"));
00643   }
00644   
00645   
00646   
sort();
00647 }
00648 
00649 
00650 
00651 
00652 
00653 
00654 void ChecksumsListView::selectAll()
00655 {
00656   
int state;
00657   
long item = this->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE);
00658   
while (item != -1)
00659   {
00660     state = this->GetItemState(item, wxLIST_STATE_SELECTED);
00661     
if (!(state & wxLIST_STATE_SELECTED))
00662       this->SetItemState(item, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
00663     item = this->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE);
00664   }
00665 }
00666 
00667 
00668 
00669 
00670 
00671 
00672 void ChecksumsListView::invertSelection()
00673 {
00674   
int state;
00675   
long item = this->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE);
00676   
while (item != -1)
00677   {
00678     state = this->GetItemState(item, wxLIST_STATE_SELECTED);
00679     state = ~state;
00680     this->SetItemState(item, state, wxLIST_STATE_SELECTED);
00681     item = this->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE);
00682   }
00683 }
00684 
00685 
00686 
00687 
00688 
00689 
00690 void ChecksumsListView::selectFilesToAdd()
00691 {
00692   
if (this->
getSumFile() != NULL)
00693   {
00694     
00695     
wxFileDialogFilterMaker fltMaker;
00696     fltMaker.
AddFilter(_(
"All the files"), wxT(
"*"));
00697     
00698     wxFileDialog dlgOpen(
this, _(
"Select the files to be added"),
00699                          wxEmptyString, wxEmptyString, fltMaker.
GetFilters(),
00700                          wxOPEN | wxHIDE_READONLY | wxMULTIPLE | wxFILE_MUST_EXIST, wxDefaultPosition);
00701     wxFileName direct(wxFileName(
sumFile->
getFileName()).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00702     
if (direct.DirExists())
00703       dlgOpen.SetDirectory(direct.GetFullPath());
00704 
00705     
if (dlgOpen.ShowModal() == wxID_OK)
00706     {
00707       wxArrayString files;
00708       dlgOpen.GetPaths(files);
00709       this->
addFiles(files);
00710     }
00711   }
00712 }
00713 
00714 
00715 
00716 
00717 
00718 
00719 void ChecksumsListView::selectDirectoriesToAdd()
00720 {
00721   
if (this->
getSumFile() != NULL)
00722   {
00723     
00724     wxDirDialog dlgDir(
this, _(
"Select the directory"));
00725     wxFileName direct(wxFileName(
sumFile->
getFileName()).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00726     
if (direct.DirExists())
00727       dlgDir.SetPath(direct.GetFullPath());
00728 
00729     
if (dlgDir.ShowModal() == wxID_OK)
00730     {
00731       wxArrayString files;
00732       files.Add(dlgDir.GetPath());
00733       this->
addFiles(files);
00734     }
00735   }
00736 }
00737 
00738 
00739 
00740 
00741 
00742 
00743 void ChecksumsListView::selectMatchingFilesToAdd()
00744 {
00745   
if (this->
getSumFile() != NULL)
00746   {
00747     
dlgAddMatchFiles dlg(
this, this->getSumFile()->getFileName());
00748     
if (dlg.ShowModal() == wxID_OK)
00749     {
00750       
00751       size_t i;
00752       
dlgAddMatchFiles::ArrayMatchPattern patterns;
00753       dlg.
getMatchPatterns(patterns);
00754       
00755       
if (patterns.
getCount() > 0)
00756       {
00757         wxFileName checksum(
getSumFile()->getFileName());
00758         
dlgAddMatchFiles::ArrayMatchPattern pats;
00759         
for (i = 0; i < patterns.
getCount(); i++)
00760         {
00761           
00762           
00763           wxFileName fn(patterns[i].getDirectory() + wxFileName::GetPathSeparator());
00764           
if (fn.IsRelative())
00765           
00766           {
00767             fn.MakeAbsolute(checksum.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00768             pats.
add(
dlgAddMatchFiles::MatchPattern(fn.GetPath(wxPATH_GET_VOLUME), patterns[i].getPattern(), patterns[i].getDepth()));
00769           }
00770           
else
00771           {
00772             fn.MakeRelativeTo(checksum.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00773             fn.MakeAbsolute(checksum.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00774             pats.
add(
dlgAddMatchFiles::MatchPattern(fn.GetPath(wxPATH_GET_VOLUME), patterns[i].getPattern(), patterns[i].getDepth()));
00775           }
00776         }
00777 
00778         wxArrayString files;
00779         
BytesDisplayer bs;
00780         
bool cont = 
true;
00781         i = 0;
00782         
while (cont && i < pats.
getCount())
00783         {
00784           wxArrayString lFiles;
00785           lFiles.Add(pats[i].getDirectory());
00786           cont = ::getFilesInSubdirectories(lFiles, files, bs,
00787                                             pats[i].getPattern(),
00788                                             pats[i].getDepth());
00789           i++;
00790         }
00791         
if (cont)
00792           
addFiles(files);
00793       }
00794     }
00795   }
00796 }
00797 
00798 
00799 
00800 
00801 
00802 
00803 
00804 
00805 
00806 
00807 
00808 
00809 void ChecksumsListView::addFiles(
const wxArrayString& files)
00810 {
00811   
if (this->
getSumFile() == NULL || files.IsEmpty())
00812     
return;
00813 
00814   
00815   wxLogNull logNo;
00816 
00817   
00818   wxArrayString allFiles;
00819   
BytesDisplayer total;
00820   
if (!::getFilesInSubdirectories(files, allFiles, total))
00821     
return;
00822 
00823   
if (allFiles.IsEmpty())
00824   
00825     
return;
00826 
00827   this->Freeze();
00828 
00829   
00830   InvalidFilesContainer invalidFiles;  
00831   wxString   sumFilePath = wxFileName(
getSumFile()->getFileName()).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
00832   
Checksum*  c = 
sumFile->
getChecksumCalculator();  
00833   wxFileName fn;            
00834   ChecksumFileCalculator::State retState;  
00835   wxString   calcSumValue;  
00836   
bool       cont = 
true;   
00837 
00838   
00839 
00840   cont = 
removeFilesInList(allFiles);
00841 
00842 
00843 
00844 
00845 
00846 
00847 
00848   
00849   
ChecksumProgress progressUpdater(_(
"Computing the checkum of %s\n%s on %s read."), _(
"Computing the checksums"), 
this, total);
00850   
ChecksumFileCalculator cfc(c, &progressUpdater);
00851   size_t i = 0;
00852   size_t l = allFiles.GetCount();
00853   
while (i < l && cont)
00854   {
00855     wxString& curFile = allFiles[i];
00856     fn = curFile;
00857 
00858     
00859     progressUpdater.
setFileName(fn.GetFullName());
00860     retState = cfc.
calculate(curFile, calcSumValue);
00861 
00862     
switch (retState)
00863     {
00864       
case ChecksumFileCalculator::Ok :              
00865         {
00866           fn.MakeRelativeTo(sumFilePath);
00867           
ChecksumData d(fn, calcSumValue, ChecksumData::Verified);
00868           
long k = this->
getSumFile()->
addChecksumData(d);
00869           this->
addChecksum(k, _(
"OK"));
00870         }
00871         
break;
00872 
00873       
case ChecksumFileCalculator::ReadError :       
00874         invalidFiles[curFile] = _(
"Error while reading the file");
00875         
break;
00876 
00877       
case ChecksumFileCalculator::FileNotFound :    
00878         invalidFiles[curFile] = _(
"File not found");
00879         
break;
00880 
00881       
case ChecksumFileCalculator::CantOpenFile :    
00882         invalidFiles[curFile] = _(
"File cannot be open");
00883         
break;
00884 
00885       
case ChecksumFileCalculator::CanceledByUser :  
00886         cont = 
false;
00887         
break;
00888     }
00889 
00890     i++;
00891   }
00892   
delete c;
00893   progressUpdater.
finished();
00894 
00895   this->Thaw();
00896   
00897   
00898   
sort();
00899   
00900   
if (!invalidFiles.empty())
00901   {
00902     
dlgInvalidFiles dlg(
this, _(
"Invalid files"),
00903                         _(
"The following files were not added to the list of the checksums:"), invalidFiles);
00904     dlg.ShowModal();
00905   }
00906 }
00907 
00908 
00909 
00910 
00911 
00912 
00913 
00914 
00915 
00916 
00917 static int removeFilesInListCompare(
const wxString& first, 
const wxString& second)
00918 {
00919   
return ::compareFileName(first, second);
00920 }
00921 
00922 
00923 
00924 
00925 
00926 
00927 
00928 
00929 
00930 
00931 
00932 
00933 bool ChecksumsListView::removeFilesInList(wxArrayString& files, wxArrayString* in)
00934 {
00935   
if (
sumFile->
getChecksumDataCount() == 0 && files.IsEmpty())
00936     
return true;
00937 
00938   wxArrayString lFiles;  
00939   wxFileName    fn;
00940   
bool cont = 
true;
00941   wxString sumFilePath = wxFileName(
sumFile->
getFileName()).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
00942   MChecksumData::const_iterator it = 
sumFile->
getChecksumDataBegin();
00943   MChecksumData::const_iterator end = 
sumFile->
getChecksumDataEnd();
00944 
00945   
00946   lFiles.Alloc(
sumFile->
getChecksumDataCount() + files.GetCount());
00947   
while (it != end)
00948   {
00949     fn = it->second.getFileName();
00950     
if (!fn.IsAbsolute())
00951       fn.MakeAbsolute(sumFilePath);
00952     lFiles.Add(fn.GetFullPath());
00953     it++;
00954   }
00955 
00956   
dlgProgress dlgProgress(_(
"Checking for duplicate files"), _(
"Beginning..."), 100, 
this,
00957     wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME);
00958 
00959   lFiles.Sort(
removeFilesInListCompare);
00960 
00961   wxTimeSpan timeSpan(0, 0, 0, 
UPDATE_PROGRESS_DLG);
00962   wxDateTime lt = wxDateTime::UNow() - timeSpan;  
00963   wxDateTime ct;                   
00964 
00965   
00966   size_t i = 0;
00967   
int r, a, b;
00968   
while (cont && i < files.GetCount())
00969   {
00970     fn = files[i];
00971     fn.Normalize(wxPATH_NORM_ALL, sumFilePath);
00972     wxString s = fn.GetFullPath();
00973 
00974     
int c = -1;
00975     a = 0;
00976     b = lFiles.GetCount() - 1;
00977     r = (a + b) / 2;
00978 
00979     
while ((a < b) && (r >= 0) && (r < lFiles.GetCount()) && ((c = ::compareFileName(s, lFiles[r])) != 0))
00980     {
00981       
if (c < 0)
00982         b = r - 1;
00983       
else
00984         a = r + 1;
00985         
00986       r = (a + b) / 2;
00987     }
00988     
if ((r >= 0) && (r < lFiles.GetCount()) && ::compareFileName(s, lFiles[r]) == 0)
00989     {
00990       
if (in != NULL)
00991         in->Add(s);
00992       files.Remove(i);
00993     }
00994     
else
00995     {
00996       
00997       
if (r < 0) r = 0;
00998       
if (!lFiles.IsEmpty() && r >= lFiles.GetCount()) r = lFiles.GetCount() - 1;
00999       
while (r > 0 && ::compareFileName(s, lFiles[r]) < 0)
01000         r--;
01001       
while (r < lFiles.GetCount() && ::compareFileName(s, lFiles[r]) >= 0)
01002         r++;
01003       lFiles.Insert(s, r);
01004 
01005       
01006 
01007 
01008 
01009       i++;
01010     }
01011     
01012     
01013     ct = wxDateTime::UNow();
01014     
if (ct.IsLaterThan(lt))
01015     {
01016       
int p;  
01017       lt = ct + timeSpan;
01018       size_t fc = files.GetCount();
01019       
if (fc > 0)
01020         p = static_cast<int>((static_cast<double>(i) / static_cast<double>(fc)) * 100.0);
01021       
else
01022         p = 100;
01023       
if (p >= 100) p = 99;
01024       cont = dlgProgress.
Update(p, wxString::Format(_(
"Checking %s"), s.c_str()));
01025       ::wxYield();
01026     }
01027     
01028     
01029     
while (dlgProgress.
isPaused())
01030       ::wxYield();
01031   }
01032 
01033   files.Shrink();
01034 
01035   dlgProgress.
Update(100, wxString::Format(_(
"Finished."), files[i].c_str()));
01036   
01037   
return cont;
01038 }
01039 
01040 
01041 
01042 
01043 
01044 
01045 
01046 
01047 
01048 
01049 
01050 
01051 bool ChecksumsListView::isInList(
const wxString& fileName)
01052 {
01053   
bool       found = 
false;
01054   wxFileName fn;
01055   wxString   sumFilePath = wxFileName(
sumFile->
getFileName()).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
01056 
01057   MChecksumData::const_iterator it = 
sumFile->
getChecksumDataBegin();
01058   MChecksumData::const_iterator end = 
sumFile->
getChecksumDataEnd();
01059 
01060   
while (!found && it != end)
01061   {
01062     fn = it->second.getFileName();
01063     fn.MakeAbsolute(sumFilePath);
01064     
if (::compareFileName(fn.GetFullPath(), fileName) == 0)
01065       found = 
true;
01066     
else
01067       it++;
01068   }
01069 
01070   
return found;
01071 }
01072 
01073 
01074 
01075 
01076 
01077 
01078 
01079 
01080 
01081 
01082 long ChecksumsListView::addChecksum(
const long key, 
const wxString& stateMsg)
01083 {
01084   
int p = this->GetItemCount();
01085   
01086   
01087   InsertItem(p, wxT(
""), 0);
01088   SetItemData(p, key);
01089   
01090   
01091   
setChecksum(p, stateMsg);
01092   
ChecksumData cd = 
sumFile->
getChecksumData(key);
01093   
setChecksumState(p, cd.
getState(), stateMsg);
01094   
01095   
return p;
01096 }
01097 
01098 
01099 
01100 
01101 
01102 
01103 
01104 
01105 
01106 
01107 
01108 
01109 void ChecksumsListView::setChecksum(
long item, 
const wxString& stateMsg)
01110 {
01111   wxFileName fn;
01112   
ChecksumData cd = 
sumFile->
getChecksumData(this->GetItemData(item));
01113   
01114   
for (
int i = 0; i < 
LVW_SUMS_NBCOLS; i++)
01115     
switch (
columns[i])
01116     {
01117       
case FILE_NAME :
01118         SetItem(item, i, cd.
getFileName().GetFullName());
01119         
break;
01120       
case DIRECTORY :
01121         fn = cd.
getFileName();
01122         
if (
AppPrefs::get()->
readBool(prGUI_MAIN_SUMS_DIRSINABSOLUTEPATH))
01123         {
01124           
if (fn.IsRelative())
01125             fn.MakeAbsolute(wxFileName(
sumFile->
getFileName()).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
01126         }
01127         
else
01128         {
01129           
if (fn.IsAbsolute())
01130             fn.MakeRelativeTo(wxFileName(
sumFile->
getFileName()).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
01131         }
01132         SetItem(item, i, fn.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
01133         
break;
01134       
case CHECKSUM_VALUE :
01135         
if (
AppPrefs::get()->
readBool(prGUI_MAIN_SUMS_UPPERCASE))
01136           SetItem(item, i, cd.
getChecksum().Upper());
01137         
else
01138           SetItem(item, i, cd.
getChecksum().Lower());
01139         
break;
01140       
case STATE :
01141           SetItem(item, i, stateMsg);
01142           
break;
01143     }
01144 
01145 }
01146 
01147 
01148 
01149 
01150 
01151 
01152 
01153 
01154 
01155 
01156 void ChecksumsListView::setChecksumState(
long item, 
const ChecksumData::State state, 
const wxString& msg)
01157 {
01158   
long key = GetItemData(item);
01159   
ChecksumData d = 
sumFile->
getChecksumData(key);
01160   
sumFile->
setChecksumState(key, state);
01161   
01162   
01163   
int stateCol = -1;
01164   
for (
int i = 0; (i < 
LVW_SUMS_NBCOLS) && (stateCol == -1); i++)
01165     
if (
columns[i] == STATE)
01166       stateCol = i;
01167 
01168   SetItem(item, stateCol, msg);
01169   SetItem(item, 0, GetItemText(item), state);
01170 }
01171 
01172 
01173 
01174 
01175 
01176 
01177 void ChecksumsListView::removeSelectedChecksums()
01178 {
01179   
if (this->
getSumFile() != NULL)
01180   {
01181     
long item;
01182 
01183     item = this->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
01184     
while (item != -1)
01185     {
01186       
sumFile->
removeChecksumData(this->GetItemData(item));
01187       this->DeleteItem(item);
01188       item = this->GetNextItem(item - 1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
01189     }
01190   }
01191 }
01192 
01193 
01194 
01195 
01196 
01197 
01198 
01199 
01200 
01201 
01202 
01203 
01204 wxArrayInt 
ChecksumsListView::getStates(
const bool onlySelected)
 const
01205 
{
01206   wxArrayInt states;
01207 
01208   
if (this->
getSumFile() != NULL)
01209   {
01210     
ChecksumData d;
01211     
const int state = onlySelected ? wxLIST_STATE_SELECTED : wxLIST_STATE_DONTCARE;
01212     
01213     states.Add(0, 
CD_STATE_COUNT);
01214 
01215     
long item = this->GetNextItem(-1, wxLIST_NEXT_ALL, state);
01216     
while (item != -1)
01217     {
01218       d = this->
getSumFile()->
getChecksumData(this->GetItemData(item));
01219       states[static_cast<size_t>(d.
getState())]++;
01220 
01221       item = this->GetNextItem(item, wxLIST_NEXT_ALL, state);
01222     }
01223   }
01224   
01225   
return states;
01226 }
01227 
01228 
01229 
01230 
01231 
01232 
01233 
01234 
01235 
01236 
01237 
01238 
01239 
01240 wxString 
ChecksumsListView::sumUpStates(
const bool onlySelected)
 const
01241 
{
01242   wxString res;
01243 
01244   
if (this->
getSumFile() != NULL)
01245   {
01246     wxArrayInt states = 
getStates(onlySelected);
01247     
int itemsCount = onlySelected ? this->GetSelectedItemCount() : this->GetItemCount();
01248 
01249     
if (itemsCount == 1)
01250       res = _(
"1 file was checked. ");
01251     
else
01252       res.Printf(_(
"%d files were checked. "), itemsCount);
01253 
01254     
if (states[ChecksumData::Verified] == itemsCount)
01255       res += _(
"All are ok.");
01256     
else if (states[ChecksumData::Invalid] == itemsCount)
01257       res += _(
"All are invalid.");
01258     
else if (states[ChecksumData::NotFound] == itemsCount)
01259       res += _(
"All cannot be opened.");
01260     
else
01261     {
01262       
if (states[ChecksumData::Verified] == 0)
01263         res += _(
"None is ok");
01264       
else if (states[ChecksumData::Verified] == 1)
01265         res += _(
"1 is ok");
01266       
else
01267         res += wxString::Format(_(
"%d are ok"), states[ChecksumData::Verified]);
01268       
01269       
if (states[ChecksumData::Invalid] == 1)
01270         res += _(
", 1 is invalid");
01271       
else if (states[ChecksumData::Invalid] > 1)
01272         res += wxString::Format(_(
", %d are invalid"), states[ChecksumData::Invalid]);
01273 
01274       
if (states[ChecksumData::NotFound] == 1)
01275         res += _(
", 1 can't be opened");
01276       
else if (states[ChecksumData::NotFound] > 1)
01277         res += wxString::Format(_(
", %d can't be opened"), states[ChecksumData::NotFound]);
01278 
01279       res += wxT(
'.');
01280     }
01281   }
01282 
01283   
return res;
01284 }
01285 
01286 
01287 
01288 
01289 
01290 
01291 
01292 
01293 
01294 
01295 bool ChecksumsListView::openChecksumFile(
const wxFileName& fileName)
01296 {
01297   
SumFile* sf = ::openChecksumFile(fileName);
01298 
01299   
if (sf != NULL)
01300   {
01301     
01302     this->
setSumFile(sf);
01303     
01304     
01305     wxCommandEvent event(EVENT_UPDATE_SUMS_FRAME_TITLE_COMMAND);
01306     this->GetParent()->ProcessEvent(event);
01307     
01308     
01309     
if (
AppPrefs::get()->
readBool(prGUI_AUTO_CHECK_ON_OPEN))
01310       this->
check();
01311 
01312     
01313     wxCommandEvent event2(EVENT_OPEN_RECENT_ADD_FILE);
01314     event2.SetString(fileName.GetFullPath());
01315     this->GetParent()->ProcessEvent(event2);
01316 
01317     
return true;
01318   }
01319   
else
01320   {
01321     ::wxMessageBox(wxString::Format(_(
"'%s' cannot be read."), fileName.GetFullPath().c_str()), _(
"Open a checksums' file"), wxOK | wxICON_EXCLAMATION);
01322     
return false;
01323   }
01324 }
01325 
01326 
01327 
01328 
01329 
01330 
01331 void ChecksumsListView::check()
01332 {
01333   
if (this->
getSumFile() == NULL)
01334     
return;  
01335   
01336   wxLogNull      logNo;   
01337   
ChecksumData   d;       
01338   wxFileName     fn;      
01339   
wxCOff_t       fs;      
01340   
BytesDisplayer total;   
01341   
const int state = (this->GetSelectedItemCount() > 0) ? wxLIST_STATE_SELECTED : wxLIST_STATE_DONTCARE;
01342 
01343   
01344   
long item = this->GetNextItem(-1, wxLIST_NEXT_ALL, state);
01345   
while (item != -1)
01346   {
01347     d = this->
getSumFile()->
getChecksumData(this->GetItemData(item));
01348     fn = d.
getFileName();
01349     
if (!fn.IsAbsolute())
01350       fn.MakeAbsolute(wxFileName(this->getSumFile()->getFileName()).GetPath(wxPATH_GET_VOLUME));
01351     
if ((fs = 
wxCGetFileLength(fn.GetFullPath())) != static_cast<wxCOff_t>(wxInvalidOffset))
01352       total += static_cast<double>(fs);
01353 
01354     item = this->GetNextItem(item, wxLIST_NEXT_ALL, state);
01355   }
01356 
01357   
01358   
Checksum* c = 
sumFile->
getChecksumCalculator();  
01359   ChecksumFileCalculator::State retState;  
01360   
bool cont = 
true;   
01361 
01362   
01363   
ChecksumProgress progressUpdater(_(
"Checking %s\n%s on %s read."), _(
"Checking the files"), 
this, total);
01364   
ChecksumFileCalculator cfc(c, &progressUpdater);
01365   item = this->GetNextItem(-1, wxLIST_NEXT_ALL, state);
01366   
while (item != -1 && cont)
01367   {
01368     
01369     d = this->
getSumFile()->
getChecksumData(this->GetItemData(item));
01370     fn = d.
getFileName();
01371     
if (!fn.IsAbsolute())
01372       fn.MakeAbsolute(wxFileName(this->getSumFile()->getFileName()).GetPath(wxPATH_GET_VOLUME));
01373 
01374     
01375     progressUpdater.
setFileName(fn.GetFullName());
01376     retState = cfc.
check(fn.GetFullPath(), d.
getChecksum());
01377 
01378     
switch (retState)
01379     {
01380       
case ChecksumFileCalculator::Ok :              
01381         this->
setChecksumState(item, ChecksumData::Verified, _(
"OK"));      
01382         
break;
01383 
01384       
case ChecksumFileCalculator::Invalid :         
01385         this->
setChecksumState(item, ChecksumData::Invalid, _(
"Checksums differ"));
01386         
break;
01387 
01388       
case ChecksumFileCalculator::ReadError :       
01389         this->
setChecksumState(item, ChecksumData::NotFound, _(
"Error while reading the file"));
01390         
break;
01391 
01392       
case ChecksumFileCalculator::FileNotFound :    
01393         this->
setChecksumState(item, ChecksumData::NotFound, _(
"File not found"));
01394         
break;
01395 
01396       
case ChecksumFileCalculator::CantOpenFile :    
01397         this->
setChecksumState(item, ChecksumData::NotFound, _(
"File cannot be open"));
01398         
break;
01399 
01400       
case ChecksumFileCalculator::CanceledByUser :  
01401         cont = 
false;
01402         
break;
01403     }
01404     
01405     item = this->GetNextItem(item, wxLIST_NEXT_ALL, state);
01406   }
01407   
delete c;
01408   progressUpdater.
finished();
01409 
01410   
01411   
sort();
01412   
01413   
01414   
if (cont && 
AppPrefs::get()->
readBool(prGUI_DLG_SUMUP_CHECK))
01415     ::wxMessageBox(this->
sumUpStates(), _(
"Checking checksums"), wxOK | wxICON_INFORMATION);
01416 
01417   
01418   wxCommandEvent event(EVENT_UPDATE_SUMS_FRAME_STATUSBAR_COMMAND);
01419   event.SetString(this->sumUpStates(this->GetSelectedItemCount() != 0));
01420   event.SetInt(0);
01421   this->GetParent()->ProcessEvent(event);
01422 }
01423 
01424 
01425 
01426 
01427 
01428 
01429 void ChecksumsListView::recompute()
01430 {
01431   
if (this->
getSumFile() == NULL || this->GetSelectedItemCount() == 0)
01432     
return;  
01433   
01434   wxLogNull      logNo;   
01435   
ChecksumData   d;       
01436   wxFileName     fn;      
01437   
wxCOff_t       fs;      
01438   
BytesDisplayer total;   
01439 
01440   
01441   
long item = this->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
01442   
while (item != -1)
01443   {
01444     d = this->
getSumFile()->
getChecksumData(this->GetItemData(item));
01445     fn = d.
getFileName();
01446     
if (!fn.IsAbsolute())
01447       fn.MakeAbsolute(wxFileName(this->getSumFile()->getFileName()).GetPath(wxPATH_GET_VOLUME));
01448     
if ((fs = 
wxCGetFileLength(fn.GetFullPath())) != static_cast<wxCOff_t>(wxInvalidOffset))
01449       total += static_cast<double>(fs);
01450 
01451     item = this->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
01452   }
01453 
01454   
01455   
Checksum* c = 
sumFile->
getChecksumCalculator();  
01456   ChecksumFileCalculator::State retState;  
01457   wxString calcSumValue;  
01458   
bool cont = 
true;   
01459 
01460   
01461   
ChecksumProgress progressUpdater(_(
"Recomputing the checkum of %s\n%s on %s read."), _(
"Recomputing the checksums"), 
this, total);
01462   
ChecksumFileCalculator cfc(c, &progressUpdater);
01463   item = this->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
01464   
while (item != -1 && cont)
01465   {
01466     d = this->
getSumFile()->
getChecksumData(this->GetItemData(item));
01467     fn = d.
getFileName();
01468     
if (!fn.IsAbsolute())
01469       fn.MakeAbsolute(wxFileName(this->getSumFile()->getFileName()).GetPath(wxPATH_GET_VOLUME));
01470 
01471     
01472     progressUpdater.
setFileName(fn.GetFullName());
01473     retState = cfc.
calculate(fn.GetFullPath(), calcSumValue);
01474     
01475     
switch (retState)
01476     {
01477       
case ChecksumFileCalculator::Ok :              
01478         this->
setChecksumState(item, ChecksumData::Verified, _(
"OK"));
01479         
if (calcSumValue.CmpNoCase(d.
getChecksum()) != 0)
01480         
01481         {
01482           
ChecksumData cd = this->
getSumFile()->
getChecksumData(this->GetItemData(item));
01483           cd.
setChecksum(calcSumValue);
01484           this->
getSumFile()->
setChecksumData(this->GetItemData(item), cd);
01485           this->
setChecksum(item, _(
"OK"));
01486         }
01487         
break;
01488 
01489       
case ChecksumFileCalculator::ReadError :       
01490         this->
setChecksumState(item, ChecksumData::NotFound, _(
"Error while reading the file"));
01491         
break;
01492 
01493       
case ChecksumFileCalculator::FileNotFound :    
01494         this->
setChecksumState(item, ChecksumData::NotFound, _(
"File not found"));
01495         
break;
01496 
01497       
case ChecksumFileCalculator::CantOpenFile :    
01498         this->
setChecksumState(item, ChecksumData::NotFound, _(
"File cannot be open"));
01499         
break;
01500 
01501       
case ChecksumFileCalculator::CanceledByUser :  
01502         cont = 
false;
01503         
break;
01504     }
01505 
01506     item = this->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
01507   }
01508   
delete c;
01509   progressUpdater.
finished();
01510   
01511   
01512   
sort();
01513 }
01514 
01515 
01516 
01517 
01518 
01519 
01520 void ChecksumsListView::reformat()
01521 {
01522   
reformat(NULL);
01523 }
01524 
01525 
01526 
01527 
#if defined(__WXMSW__)
01528 
01529 
01530 
01531 
01532 
01533 
void ChecksumsListView::OnContextMenu(wxContextMenuEvent& event)
01534 {
01535   ShowContextMenu(ScreenToClient(event.GetPosition()));
01536 }
01537 
01538 
#else
01539 
01540 
01541 
01542 
01543 
01544 void ChecksumsListView::OnRightUp(wxMouseEvent& event)
01545 {
01546   
ShowContextMenu(event.GetPosition());
01547 }
01548 
01549 
#endif  // defined(__WXMSW__)
01550 
01551 
01552 
01553 
01554 
01555 
01556 
01557 void ChecksumsListView::ShowContextMenu(
const wxPoint& p)
01558 {
01559   
if (
sumFile != NULL)
01560   {
01561     
01562     wxMenu pmnFonds;
01563     wxMenuItem* itpFilesAdd = 
new wxMenuItem(&pmnFonds, ITP_FILESADD, wxString(_(
"&Add files...")));
01564     itpFilesAdd->SetBitmap(wxBitmap(hi16_action_fileadd_xpm));
01565     wxMenuItem* itpDirectoriesAdd = 
new wxMenuItem(&pmnFonds, ITP_DIRECTORIESADD, wxString(_(
"A&dd directories...")));
01566     itpDirectoriesAdd->SetBitmap(wxBitmap(hi16_action_directoryadd_xpm));
01567     wxMenuItem* itpAddMatchingFiles = 
new wxMenuItem(&pmnFonds, ITP_ADDMATCHINGFILES, wxString(_(
"Add &matching files...")));
01568     itpAddMatchingFiles->SetBitmap(wxBitmap(hi16_action_addmatchingfiles_xpm));
01569     wxMenuItem* itpRemove = 
new wxMenuItem(&pmnFonds, ITP_REMOVE, wxString(_(
"&Remove")));
01570     itpRemove->SetBitmap(wxBitmap(hi16_action_fileremove_xpm));
01571 
01572     pmnFonds.Append(itpFilesAdd);
01573     pmnFonds.Append(itpDirectoriesAdd);
01574     pmnFonds.Append(itpAddMatchingFiles);
01575     pmnFonds.Append(itpRemove);
01576 
01577     
01578     
if (this->GetSelectedItemCount() == 0)
01579       itpRemove->Enable(
false);
01580   
01581     PopupMenu(&pmnFonds, p);
01582   }
01583 }
01584 
01585 
01586 
01587 
01588 
01589 
01590 
01591 
01592 void ChecksumsListView::itpAddFilesClick(wxCommandEvent& event)
01593 {
01594   this->
selectFilesToAdd();
01595 }
01596 
01597 
01598 
01599 
01600 
01601 
01602 
01603 
01604 void ChecksumsListView::itpAddDirectoriesClick(wxCommandEvent& event)
01605 {
01606   this->
selectDirectoriesToAdd();
01607 }
01608 
01609 
01610 
01611 
01612 
01613 
01614 
01615 
01616 void ChecksumsListView::itpAddMatchingFilesClick(wxCommandEvent& event)
01617 {
01618   this->
selectMatchingFilesToAdd();
01619 }
01620 
01621 
01622 
01623 
01624 
01625 
01626 
01627 
01628 void ChecksumsListView::itpRemoveClick(wxCommandEvent& event)
01629 {
01630   this->
removeSelectedChecksums();
01631 }
01632 
01633 
01634 
01635 
01636 
01637 
01638 
01639 
01640 void ChecksumsListView::DnDFiles(wxCommandEvent& event)
01641 {
01642   
01643   wxArrayString* f = reinterpret_cast<wxArrayString*>(event.GetClientData());
01644 
01645   
01646   
if (f != NULL)
01647   {
01648     
if (this->
getSumFile() == NULL)
01649     {
01650       size_t i = 0;
01651       
while (i < f->GetCount() && !(this->
openChecksumFile((*f)[i])))
01652         i++;
01653     }
01654     
else  
01655     {
01656       this->
addFiles(*f);
01657 
01658       
01659       wxCommandEvent event(EVENT_UPDATE_SUMS_FRAME_TITLE_COMMAND);
01660       this->GetParent()->ProcessEvent(event);
01661     }
01662   }
01663 
01664   
01665   
if (f != NULL)
01666     
delete f;
01667 }
01668 
01669 
01670 
01671 
01672 
01673 
01674 
01675 
01676 void ChecksumsListView::getColumns(Columns cols[LVW_SUMS_NBCOLS])
01677 {
01678   
for (
int i = 0; i < 
LVW_SUMS_NBCOLS; i++)
01679     cols[i] = 
columns[i];
01680 }
01681 
01682 
01683 
01684 
01685 
01686 
01687 
01688 
01689 
01690 
01691 bool ChecksumsListView::setColumns(Columns newColumns[LVW_SUMS_NBCOLS])
01692 {
01693   
int       i = 0;
01694   
int       j;
01695   
bool      OK = 
true;
01696   
bool      hasChanged = 
false;
01697   
Columns   oldColumns[
LVW_SUMS_NBCOLS];
01698   
01699   
01700   
while (OK && i < 
LVW_SUMS_NBCOLS)
01701   {
01702     
if (newColumns[i] != FILE_NAME && newColumns[i] != DIRECTORY &&
01703         newColumns[i] != CHECKSUM_VALUE && newColumns[i] != STATE)
01704       OK = 
false;
01705 
01706     i++;
01707   }
01708 
01709   
01710   i = 0;
01711   
while (OK && i < 
LVW_SUMS_NBCOLS)
01712   {
01713     j = i + 1;
01714     
while (j < 
LVW_SUMS_NBCOLS)
01715     {
01716       
if (newColumns[i] == newColumns[j])
01717         OK = 
false;
01718       j++;
01719     }
01720     i++;
01721   }
01722 
01723   
01724   
if (OK)
01725     
for (i = 0; i < 
LVW_SUMS_NBCOLS; i++)
01726     {
01727       oldColumns[i] = 
columns[i];
01728       
if (columns[i] != newColumns[i])
01729       {
01730         hasChanged = 
true;
01731         columns[i] = newColumns[i];
01732       }
01733     }
01734 
01735   
01736   
if (OK && hasChanged)
01737   {
01738     
reformat(oldColumns);
01739     
return true;
01740   }
01741   
return false;
01742 }
01743 
01744 
01745 
01746 
01747 
01748 
01749 
01750 
01751 
01752 void ChecksumsListView::reformat(Columns oldColumns[LVW_SUMS_NBCOLS])
01753 {
01754   wxBusyCursor wait;
01755   this->Freeze();
01756   
01757   
01758   
if (oldColumns != NULL)
01759   {
01760     wxListItem colitem;
01761     colitem.SetMask(wxLIST_MASK_TEXT);
01762     
for (
int i = 0; i < 
LVW_SUMS_NBCOLS; i++)
01763     {
01764       this->GetColumn(i, colitem);
01765       colitem.SetText(
getColumnName(
columns[i]));
01766       this->SetColumn(i, colitem);
01767     }
01768   }
01769 
01770   wxString     state;
01771   
int          i;
01772   wxListItem   li;
01773   
Columns*     refTab = (oldColumns == NULL) ? 
columns : oldColumns;
01774 
01775   
01776   
int stateCol = -1;
01777   
for (i = 0; (i < 
LVW_SUMS_NBCOLS) && (stateCol == -1); i++)
01778     
if (refTab[i] == STATE)
01779       stateCol = i;
01780 
01781   li.SetMask(wxLIST_MASK_TEXT);
01782   
long item = this->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE);
01783   
while (item != -1)
01784   {
01785     
01786     li.SetId(item);
01787     li.SetColumn(stateCol);
01788     this->GetItem(li);
01789     state = li.GetText();
01790 
01791     
01792     
setChecksum(item, state);
01793 
01794     item = this->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE);
01795   }
01796 
01797   this->Thaw();
01798   
01799   
01800   
sort();
01801 }
01802 
01803 
01804 
01805 
01806 
01807 
01808 
01809 
01810 
01811 wxString 
ChecksumsListView::getColumnName(
const Columns col)
01812 {
01813   wxString res;
01814   
switch (col)
01815   {
01816     
case FILE_NAME :
01817       res = _(
"File name");
01818       
break;
01819     
case DIRECTORY :
01820       res = _(
"Directory");
01821       
break;
01822     
case CHECKSUM_VALUE :
01823       res = _(
"Checksum value");
01824       
break;
01825     
case STATE :
01826       res = _(
"State");
01827       
break;
01828     
default :
01829       res = wxT(
"");
01830   }
01831   
return res;
01832 }
01833 
01834 
01835 
01836 BEGIN_EVENT_TABLE(
ChecksumsListView, wxListView)
01837   EVT_MENU(ITP_FILESADD, 
ChecksumsListView::itpAddFilesClick)
01838   EVT_MENU(ITP_DIRECTORIESADD, 
ChecksumsListView::itpAddDirectoriesClick)
01839   EVT_MENU(ITP_ADDMATCHINGFILES, 
ChecksumsListView::itpAddMatchingFilesClick)
01840   EVT_MENU(ITP_REMOVE, 
ChecksumsListView::itpRemoveClick)
01841   EVT_CUSTOM(EVENT_DNDFILES_COMMAND, -1, 
ChecksumsListView::DnDFiles)
01842 
01843   #if defined(__WXMSW__)
01844   EVT_CONTEXT_MENU(
ChecksumsListView::OnContextMenu)
01845   #else
01846   EVT_RIGHT_UP(
ChecksumsListView::OnRightUp)
01847   #endif  
01848 END_EVENT_TABLE()
01849