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