joachim99@8
|
1 /***************************************************************************
|
joachim99@8
|
2 directorymergewindow.cpp
|
joachim99@58
|
3 -----------------
|
joachim99@8
|
4 begin : Sat Oct 19 2002
|
joachim99@58
|
5 copyright : (C) 2002-2004 by Joachim Eibl
|
joachim99@8
|
6 email : joachim.eibl@gmx.de
|
joachim99@8
|
7 ***************************************************************************/
|
joachim99@8
|
8
|
joachim99@8
|
9 /***************************************************************************
|
joachim99@8
|
10 * *
|
joachim99@8
|
11 * This program is free software; you can redistribute it and/or modify *
|
joachim99@8
|
12 * it under the terms of the GNU General Public License as published by *
|
joachim99@8
|
13 * the Free Software Foundation; either version 2 of the License, or *
|
joachim99@8
|
14 * (at your option) any later version. *
|
joachim99@8
|
15 * *
|
joachim99@8
|
16 ***************************************************************************/
|
joachim99@8
|
17
|
joachim99@8
|
18 #include "directorymergewindow.h"
|
joachim99@8
|
19 #include "optiondialog.h"
|
joachim99@8
|
20 #include <vector>
|
joachim99@8
|
21 #include <map>
|
joachim99@8
|
22
|
joachim99@8
|
23 #include <qdir.h>
|
joachim99@8
|
24 #include <qapplication.h>
|
joachim99@8
|
25 #include <qpixmap.h>
|
joachim99@8
|
26 #include <qimage.h>
|
joachim99@8
|
27 #include <kpopupmenu.h>
|
joachim99@51
|
28 #include <kaction.h>
|
joachim99@8
|
29 #include <qregexp.h>
|
joachim99@8
|
30 #include <qmessagebox.h>
|
joachim99@8
|
31 #include <qlayout.h>
|
joachim99@8
|
32 #include <qlabel.h>
|
joachim99@8
|
33 #include <qtable.h>
|
joachim99@8
|
34 #include <qsplitter.h>
|
joachim99@8
|
35 #include <qprogressdialog.h>
|
joachim99@8
|
36 #include <kmessagebox.h>
|
joachim99@8
|
37 #include <kiconloader.h>
|
joachim99@8
|
38 #include <klocale.h>
|
joachim99@8
|
39 #include <iostream>
|
joachim99@8
|
40 #include <assert.h>
|
joachim99@8
|
41
|
joachim99@51
|
42 static bool conflictingFileTypes(MergeFileInfos& mfi);
|
joachim99@8
|
43
|
joachim99@8
|
44 class StatusInfo : public QListView
|
joachim99@8
|
45 {
|
joachim99@8
|
46 public:
|
joachim99@8
|
47 StatusInfo(QWidget* pParent) : QListView( pParent )
|
joachim99@8
|
48 {
|
joachim99@8
|
49 addColumn("");
|
joachim99@8
|
50 setSorting(-1); //disable sorting
|
joachim99@8
|
51 }
|
joachim99@8
|
52
|
joachim99@8
|
53 QListViewItem* m_pLast;
|
joachim99@8
|
54 QListViewItem* last()
|
joachim99@8
|
55 {
|
joachim99@8
|
56 if (firstChild()==0) return 0;
|
joachim99@8
|
57 else return m_pLast;
|
joachim99@8
|
58 }
|
joachim99@8
|
59
|
joachim99@8
|
60 void addText(const QString& s )
|
joachim99@8
|
61 {
|
joachim99@8
|
62 if (firstChild()==0) m_pLast = new QListViewItem( this, s );
|
joachim99@8
|
63 else m_pLast = new QListViewItem( this, last(), s );
|
joachim99@8
|
64 }
|
joachim99@8
|
65 };
|
joachim99@8
|
66
|
joachim99@8
|
67
|
joachim99@8
|
68 class TempRemover
|
joachim99@8
|
69 {
|
joachim99@8
|
70 public:
|
joachim99@8
|
71 TempRemover( const QString& origName, FileAccess& fa );
|
joachim99@8
|
72 ~TempRemover();
|
joachim99@8
|
73 QString name() { return m_name; }
|
joachim99@8
|
74 bool success() { return m_bSuccess; }
|
joachim99@8
|
75 private:
|
joachim99@8
|
76 QString m_name;
|
joachim99@8
|
77 bool m_bTemp;
|
joachim99@8
|
78 bool m_bSuccess;
|
joachim99@8
|
79 };
|
joachim99@8
|
80 TempRemover::TempRemover(const QString& origName, FileAccess& fa)
|
joachim99@8
|
81 {
|
joachim99@8
|
82 if ( fa.isLocal() )
|
joachim99@8
|
83 {
|
joachim99@8
|
84 m_name = origName;
|
joachim99@8
|
85 m_bTemp = false;
|
joachim99@8
|
86 m_bSuccess = true;
|
joachim99@8
|
87 }
|
joachim99@8
|
88 else
|
joachim99@8
|
89 {
|
joachim99@8
|
90 m_name = FileAccess::tempFileName();
|
joachim99@8
|
91 m_bSuccess = fa.copyFile( m_name );
|
joachim99@8
|
92 m_bTemp = m_bSuccess;
|
joachim99@8
|
93 }
|
joachim99@8
|
94 }
|
joachim99@8
|
95 TempRemover::~TempRemover()
|
joachim99@8
|
96 {
|
joachim99@8
|
97 if ( m_bTemp && ! m_name.isEmpty() )
|
joachim99@8
|
98 FileAccess::removeFile(m_name);
|
joachim99@8
|
99 }
|
joachim99@8
|
100
|
joachim99@8
|
101 void DirectoryMergeWindow::fastFileComparison(
|
joachim99@8
|
102 FileAccess& fi1, FileAccess& fi2,
|
joachim99@8
|
103 bool& bEqual, bool& bError, QString& status )
|
joachim99@8
|
104 {
|
joachim99@8
|
105 status = "";
|
joachim99@8
|
106 bEqual = false;
|
joachim99@8
|
107 bError = true;
|
joachim99@8
|
108
|
joachim99@8
|
109 if ( !m_bFollowFileLinks )
|
joachim99@8
|
110 {
|
joachim99@8
|
111 if ( fi1.isSymLink() != fi2.isSymLink() )
|
joachim99@8
|
112 {
|
joachim99@51
|
113 status = i18n("Mix of links and normal files.");
|
joachim99@8
|
114 return;
|
joachim99@8
|
115 }
|
joachim99@8
|
116 else if ( fi1.isSymLink() && fi2.isSymLink() )
|
joachim99@8
|
117 {
|
joachim99@8
|
118 bError = false;
|
joachim99@8
|
119 bEqual = fi1.readLink() == fi2.readLink();
|
joachim99@51
|
120 status = i18n("Link: ");
|
joachim99@8
|
121 return;
|
joachim99@8
|
122 }
|
joachim99@8
|
123 }
|
joachim99@8
|
124
|
joachim99@8
|
125 if ( fi1.size()!=fi2.size() )
|
joachim99@8
|
126 {
|
joachim99@8
|
127 bEqual = false;
|
joachim99@51
|
128 status = i18n("Size. ");
|
joachim99@51
|
129 return;
|
joachim99@51
|
130 }
|
joachim99@51
|
131 else if ( m_pOptions->m_bDmTrustSize )
|
joachim99@51
|
132 {
|
joachim99@51
|
133 bEqual = true;
|
joachim99@8
|
134 return;
|
joachim99@8
|
135 }
|
joachim99@8
|
136
|
joachim99@8
|
137 if ( m_pOptions->m_bDmTrustDate )
|
joachim99@8
|
138 {
|
joachim99@8
|
139 bEqual = ( fi1.lastModified() == fi2.lastModified() && fi1.size()==fi2.size() );
|
joachim99@8
|
140 bError = false;
|
joachim99@51
|
141 status = i18n("Date & Size: ");
|
joachim99@8
|
142 return;
|
joachim99@8
|
143 }
|
joachim99@8
|
144
|
joachim99@8
|
145 QString fileName1 = fi1.absFilePath();
|
joachim99@8
|
146 QString fileName2 = fi2.absFilePath();
|
joachim99@8
|
147 TempRemover tr1( fileName1, fi1 );
|
joachim99@8
|
148 if ( !tr1.success() )
|
joachim99@8
|
149 {
|
joachim99@51
|
150 status = i18n("Creating temp copy of %1 failed.").arg(fileName1);
|
joachim99@8
|
151 return;
|
joachim99@8
|
152 }
|
joachim99@8
|
153 TempRemover tr2( fileName2, fi2 );
|
joachim99@8
|
154 if ( !tr2.success() )
|
joachim99@8
|
155 {
|
joachim99@51
|
156 status = i18n("Creating temp copy of %1 failed.").arg(fileName2);
|
joachim99@8
|
157 return;
|
joachim99@8
|
158 }
|
joachim99@8
|
159
|
joachim99@8
|
160 std::vector<char> buf1(100000);
|
joachim99@8
|
161 std::vector<char> buf2(buf1.size());
|
joachim99@8
|
162
|
joachim99@8
|
163 QFile file1( tr1.name() );
|
joachim99@8
|
164
|
joachim99@8
|
165 if ( ! file1.open(IO_ReadOnly) )
|
joachim99@8
|
166 {
|
joachim99@51
|
167 status = i18n("Opening %1 failed.").arg(fileName1);
|
joachim99@8
|
168 return;
|
joachim99@8
|
169 }
|
joachim99@8
|
170
|
joachim99@8
|
171 QFile file2( tr2.name() );
|
joachim99@8
|
172
|
joachim99@8
|
173 if ( ! file2.open(IO_ReadOnly) )
|
joachim99@8
|
174 {
|
joachim99@51
|
175 status = i18n("Opening %1 failed.").arg(fileName2);
|
joachim99@8
|
176 return;
|
joachim99@8
|
177 }
|
joachim99@8
|
178
|
joachim99@8
|
179 #if QT_VERSION==230
|
joachim99@8
|
180 typedef int t_FileSize;
|
joachim99@8
|
181 #else
|
joachim99@8
|
182 typedef QFile::Offset t_FileSize;
|
joachim99@8
|
183 #endif
|
joachim99@8
|
184 t_FileSize size = file1.size();
|
joachim99@8
|
185
|
joachim99@8
|
186 while( size>0 )
|
joachim99@8
|
187 {
|
joachim99@8
|
188 int len = min2( size, (t_FileSize)buf1.size() );
|
joachim99@8
|
189 if( len != file1.readBlock( &buf1[0], len ) )
|
joachim99@8
|
190 {
|
joachim99@51
|
191 status = i18n("Error reading from %1").arg(fileName1);
|
joachim99@8
|
192 return;
|
joachim99@8
|
193 }
|
joachim99@8
|
194
|
joachim99@8
|
195 if( len != file2.readBlock( &buf2[0], len ) )
|
joachim99@8
|
196 {
|
joachim99@51
|
197 status = i18n("Error reading from %1").arg(fileName2);
|
joachim99@8
|
198 return;
|
joachim99@8
|
199 }
|
joachim99@8
|
200
|
joachim99@8
|
201 if ( memcmp( &buf1[0], &buf2[0], len ) != 0 )
|
joachim99@8
|
202 {
|
joachim99@8
|
203 bError = false;
|
joachim99@8
|
204 return;
|
joachim99@8
|
205 }
|
joachim99@8
|
206 size-=len;
|
joachim99@8
|
207 }
|
joachim99@8
|
208
|
joachim99@8
|
209 // If the program really arrives here, then the files are really equal.
|
joachim99@8
|
210 bError = false;
|
joachim99@8
|
211 bEqual = true;
|
joachim99@8
|
212 }
|
joachim99@8
|
213
|
joachim99@8
|
214
|
joachim99@8
|
215
|
joachim99@8
|
216
|
joachim99@8
|
217
|
joachim99@8
|
218 static int s_nameCol = 0;
|
joachim99@8
|
219 static int s_ACol = 1;
|
joachim99@8
|
220 static int s_BCol = 2;
|
joachim99@8
|
221 static int s_CCol = 3;
|
joachim99@8
|
222 static int s_OpCol = 4;
|
joachim99@8
|
223 static int s_OpStatusCol = 5;
|
joachim99@8
|
224 DirectoryMergeWindow::DirectoryMergeWindow( QWidget* pParent, OptionDialog* pOptions, KIconLoader* pIconLoader )
|
joachim99@8
|
225 : QListView( pParent )
|
joachim99@8
|
226 {
|
joachim99@8
|
227 connect( this, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(onDoubleClick(QListViewItem*)));
|
joachim99@8
|
228 connect( this, SIGNAL(returnPressed(QListViewItem*)), this, SLOT(onDoubleClick(QListViewItem*)));
|
joachim99@8
|
229 connect( this, SIGNAL( pressed(QListViewItem*,const QPoint&, int)),
|
joachim99@8
|
230 this, SLOT( onClick(QListViewItem*,const QPoint&, int)) );
|
joachim99@8
|
231 connect( this, SIGNAL(selectionChanged(QListViewItem*)), this, SLOT(onSelectionChanged(QListViewItem*)));
|
joachim99@8
|
232 m_pOptions = pOptions;
|
joachim99@8
|
233 m_pIconLoader = pIconLoader;
|
joachim99@8
|
234 m_pDirectoryMergeInfo = 0;
|
joachim99@8
|
235 m_bAllowResizeEvents = true;
|
joachim99@8
|
236 m_bSimulatedMergeStarted=false;
|
joachim99@8
|
237 m_bRealMergeStarted=false;
|
joachim99@8
|
238 m_bError = false;
|
joachim99@8
|
239 m_bSyncMode = false;
|
joachim99@8
|
240 m_pStatusInfo = new StatusInfo(0);
|
joachim99@8
|
241 m_pStatusInfo->hide();
|
joachim99@8
|
242
|
joachim99@51
|
243 addColumn(i18n("Name"));
|
joachim99@8
|
244 addColumn("A");
|
joachim99@8
|
245 addColumn("B");
|
joachim99@8
|
246 addColumn("C");
|
joachim99@51
|
247 addColumn(i18n("Operation"));
|
joachim99@51
|
248 addColumn(i18n("Status"));
|
joachim99@8
|
249 }
|
joachim99@8
|
250
|
joachim99@8
|
251 DirectoryMergeWindow::~DirectoryMergeWindow()
|
joachim99@8
|
252 {
|
joachim99@8
|
253 }
|
joachim99@8
|
254
|
joachim99@8
|
255
|
joachim99@8
|
256 int DirectoryMergeWindow::totalColumnWidth()
|
joachim99@8
|
257 {
|
joachim99@8
|
258 int w=0;
|
joachim99@8
|
259 for (int i=0; i<s_OpStatusCol; ++i)
|
joachim99@8
|
260 {
|
joachim99@8
|
261 w += columnWidth(i);
|
joachim99@8
|
262 }
|
joachim99@8
|
263 return w;
|
joachim99@8
|
264 }
|
joachim99@8
|
265
|
joachim99@8
|
266 void DirectoryMergeWindow::reload()
|
joachim99@8
|
267 {
|
joachim99@8
|
268 if ( isDirectoryMergeInProgress() )
|
joachim99@8
|
269 {
|
joachim99@8
|
270 int result = KMessageBox::warningYesNo(this,
|
joachim99@8
|
271 i18n("You are currently doing a directory merge. Are you sure, you want to abort the merge and rescan the directory?"),
|
joachim99@51
|
272 i18n("Warning"), i18n("Rescan"), i18n("Continue Merging") );
|
joachim99@8
|
273 if ( result!=KMessageBox::Yes )
|
joachim99@8
|
274 return;
|
joachim99@8
|
275 }
|
joachim99@8
|
276 init( m_dirA, m_dirB, m_dirC, m_dirDest, m_bDirectoryMerge );
|
joachim99@8
|
277 }
|
joachim99@8
|
278
|
joachim99@8
|
279 // Copy pm2 onto pm1, but preserve the alpha value from pm1 where pm2 is transparent.
|
joachim99@8
|
280 static QPixmap pixCombiner( const QPixmap& pm1, const QPixmap& pm2 )
|
joachim99@8
|
281 {
|
joachim99@8
|
282 QImage img1 = pm1.convertToImage().convertDepth(32);
|
joachim99@8
|
283 QImage img2 = pm2.convertToImage().convertDepth(32);
|
joachim99@8
|
284
|
joachim99@8
|
285 for (int y = 0; y < img1.height(); y++)
|
joachim99@8
|
286 {
|
joachim99@8
|
287 Q_UINT32 *line1 = reinterpret_cast<Q_UINT32 *>(img1.scanLine(y));
|
joachim99@8
|
288 Q_UINT32 *line2 = reinterpret_cast<Q_UINT32 *>(img2.scanLine(y));
|
joachim99@8
|
289 for (int x = 0; x < img1.width(); x++)
|
joachim99@8
|
290 {
|
joachim99@8
|
291 if ( qAlpha( line2[x] ) >0 )
|
joachim99@8
|
292 line1[x] = (line2[x] | 0xff000000);
|
joachim99@8
|
293 }
|
joachim99@8
|
294 }
|
joachim99@8
|
295 QPixmap pix;
|
joachim99@8
|
296 pix.convertFromImage(img1);
|
joachim99@8
|
297 return pix;
|
joachim99@8
|
298 }
|
joachim99@8
|
299
|
joachim99@8
|
300 // like pixCombiner but let the pm1 color shine through
|
joachim99@8
|
301 static QPixmap pixCombiner2( const QPixmap& pm1, const QPixmap& pm2 )
|
joachim99@8
|
302 {
|
joachim99@8
|
303 QImage img1 = pm1.convertToImage().convertDepth(32);
|
joachim99@8
|
304 QImage img2 = pm2.convertToImage().convertDepth(32);
|
joachim99@8
|
305
|
joachim99@8
|
306 for (int y = 0; y < img1.height(); y++)
|
joachim99@8
|
307 {
|
joachim99@8
|
308 Q_UINT32 *line1 = reinterpret_cast<Q_UINT32 *>(img1.scanLine(y));
|
joachim99@8
|
309 Q_UINT32 *line2 = reinterpret_cast<Q_UINT32 *>(img2.scanLine(y));
|
joachim99@8
|
310 for (int x = 0; x < img1.width(); x++)
|
joachim99@8
|
311 {
|
joachim99@8
|
312 if ( qAlpha( line2[x] ) >0 )
|
joachim99@8
|
313 {
|
joachim99@8
|
314 int r = ( qRed( line1[x] ) + qRed( line2[x] ))/2;
|
joachim99@8
|
315 int g = ( qGreen( line1[x] ) + qGreen( line2[x] ))/2;
|
joachim99@8
|
316 int b = ( qBlue( line1[x] ) + qBlue( line2[x] ))/2;
|
joachim99@8
|
317 line1[x] = qRgba( r,g,b, 0xff );
|
joachim99@8
|
318 }
|
joachim99@8
|
319 }
|
joachim99@8
|
320 }
|
joachim99@8
|
321 QPixmap pix;
|
joachim99@8
|
322 pix.convertFromImage(img1);
|
joachim99@8
|
323 return pix;
|
joachim99@8
|
324 }
|
joachim99@8
|
325
|
joachim99@8
|
326 static void calcDirStatus( bool bThreeDirs, DirMergeItem* i, int& nofFiles,
|
joachim99@8
|
327 int& nofDirs, int& nofEqualFiles, int& nofManualMerges )
|
joachim99@8
|
328 {
|
joachim99@8
|
329 if ( i->m_pMFI->m_bDirA || i->m_pMFI->m_bDirB || i->m_pMFI->m_bDirC )
|
joachim99@8
|
330 {
|
joachim99@8
|
331 ++nofDirs;
|
joachim99@8
|
332 }
|
joachim99@8
|
333 else
|
joachim99@8
|
334 {
|
joachim99@8
|
335 ++nofFiles;
|
joachim99@8
|
336 if ( i->m_pMFI->m_bEqualAB && (!bThreeDirs || i->m_pMFI->m_bEqualAC ))
|
joachim99@8
|
337 {
|
joachim99@8
|
338 ++nofEqualFiles;
|
joachim99@8
|
339 }
|
joachim99@8
|
340 else
|
joachim99@8
|
341 {
|
joachim99@8
|
342 if ( i->m_pMFI->m_eMergeOperation==eMergeABCToDest || i->m_pMFI->m_eMergeOperation==eMergeABToDest )
|
joachim99@8
|
343 ++nofManualMerges;
|
joachim99@8
|
344 }
|
joachim99@8
|
345 }
|
joachim99@8
|
346 for( QListViewItem* p = i->firstChild(); p!=0; p = p->nextSibling() )
|
joachim99@8
|
347 calcDirStatus( bThreeDirs, static_cast<DirMergeItem*>(p), nofFiles, nofDirs, nofEqualFiles, nofManualMerges );
|
joachim99@8
|
348 }
|
joachim99@8
|
349
|
joachim99@58
|
350 static QString sortString(const QString& s)
|
joachim99@58
|
351 {
|
joachim99@58
|
352 #ifdef _WIN32
|
joachim99@58
|
353 return s.upper();
|
joachim99@58
|
354 #else
|
joachim99@58
|
355 return s;
|
joachim99@58
|
356 #endif
|
joachim99@58
|
357 }
|
joachim99@58
|
358
|
joachim99@8
|
359 bool DirectoryMergeWindow::init
|
joachim99@8
|
360 (
|
joachim99@8
|
361 FileAccess& dirA,
|
joachim99@8
|
362 FileAccess& dirB,
|
joachim99@8
|
363 FileAccess& dirC,
|
joachim99@8
|
364 FileAccess& dirDest,
|
joachim99@8
|
365 bool bDirectoryMerge
|
joachim99@8
|
366 )
|
joachim99@8
|
367 {
|
joachim99@8
|
368 m_bFollowDirLinks = m_pOptions->m_bDmFollowDirLinks;
|
joachim99@8
|
369 m_bFollowFileLinks = m_pOptions->m_bDmFollowFileLinks;
|
joachim99@8
|
370 m_bSimulatedMergeStarted=false;
|
joachim99@8
|
371 m_bRealMergeStarted=false;
|
joachim99@8
|
372 m_bError=false;
|
joachim99@8
|
373 m_bDirectoryMerge = bDirectoryMerge;
|
joachim99@8
|
374
|
joachim99@8
|
375 clear();
|
joachim99@8
|
376
|
joachim99@53
|
377 m_mergeItemList.clear();
|
joachim99@51
|
378 m_currentItemForOperation = m_mergeItemList.end();
|
joachim99@8
|
379
|
joachim99@8
|
380 m_dirA = dirA;
|
joachim99@8
|
381 m_dirB = dirB;
|
joachim99@8
|
382 m_dirC = dirC;
|
joachim99@8
|
383 m_dirDest = dirDest;
|
joachim99@8
|
384
|
joachim99@8
|
385 // Check if all input directories exist and are valid. The dest dir is not tested now.
|
joachim99@8
|
386 // The test will happen only when we are going to write to it.
|
joachim99@8
|
387 if ( !m_dirA.isDir() || !m_dirB.isDir() ||
|
joachim99@8
|
388 (m_dirC.isValid() && !m_dirC.isDir()) )
|
joachim99@8
|
389 {
|
joachim99@8
|
390 QString text( i18n("Opening of directories failed:") );
|
joachim99@8
|
391 text += "\n\n";
|
joachim99@8
|
392 if ( !dirA.isDir() )
|
joachim99@51
|
393 { text += i18n("Dir A \"%1\" does not exist or is not a directory.\n").arg(m_dirA.prettyAbsPath()); }
|
joachim99@8
|
394
|
joachim99@8
|
395 if ( !dirB.isDir() )
|
joachim99@51
|
396 { text += i18n("Dir B \"%1\" does not exist or is not a directory.\n").arg(m_dirB.prettyAbsPath()); }
|
joachim99@8
|
397
|
joachim99@8
|
398 if ( m_dirC.isValid() && !m_dirC.isDir() )
|
joachim99@51
|
399 { text += i18n("Dir C \"%1\" does not exist or is not a directory.\n").arg(m_dirC.prettyAbsPath()); }
|
joachim99@8
|
400
|
joachim99@51
|
401 KMessageBox::sorry( this, text, i18n("Directory Open Error") );
|
joachim99@8
|
402 return false;
|
joachim99@8
|
403 }
|
joachim99@8
|
404
|
joachim99@8
|
405 if ( m_dirC.isValid() &&
|
joachim99@8
|
406 (m_dirDest.prettyAbsPath() == m_dirA.prettyAbsPath() || m_dirDest.prettyAbsPath()==m_dirB.prettyAbsPath() ) )
|
joachim99@8
|
407 {
|
joachim99@8
|
408 KMessageBox::error(this,
|
joachim99@53
|
409 i18n( "The destination directory must not be the same as A or B when "
|
joachim99@8
|
410 "three directories are merged.\nCheck again before continuing."),
|
joachim99@51
|
411 i18n("Parameter Warning"));
|
joachim99@8
|
412 return false;
|
joachim99@8
|
413 }
|
joachim99@8
|
414
|
joachim99@8
|
415 m_bSyncMode = m_pOptions->m_bDmSyncMode && !m_dirC.isValid() && !m_dirDest.isValid();
|
joachim99@8
|
416
|
joachim99@8
|
417 if ( m_dirDest.isValid() )
|
joachim99@8
|
418 m_dirDestInternal = m_dirDest;
|
joachim99@8
|
419 else
|
joachim99@8
|
420 m_dirDestInternal = m_dirC.isValid() ? m_dirC : m_dirB;
|
joachim99@8
|
421
|
joachim99@8
|
422 QString origCurrentDirectory = QDir::currentDirPath();
|
joachim99@8
|
423
|
joachim99@8
|
424 g_pProgressDialog->start();
|
joachim99@8
|
425
|
joachim99@8
|
426 m_fileMergeMap.clear();
|
joachim99@8
|
427 t_DirectoryList::iterator i;
|
joachim99@8
|
428
|
joachim99@8
|
429 // calc how many directories will be read:
|
joachim99@8
|
430 double nofScans = ( m_dirA.isValid() ? 1 : 0 )+( m_dirB.isValid() ? 1 : 0 )+( m_dirC.isValid() ? 1 : 0 );
|
joachim99@8
|
431 int currentScan = 0;
|
joachim99@8
|
432
|
joachim99@8
|
433 bool bListDirSuccessA = true;
|
joachim99@8
|
434 bool bListDirSuccessB = true;
|
joachim99@8
|
435 bool bListDirSuccessC = true;
|
joachim99@8
|
436 if ( m_dirA.isValid() )
|
joachim99@8
|
437 {
|
joachim99@51
|
438 g_pProgressDialog->setInformation(i18n("Reading Directory A"));
|
joachim99@8
|
439 g_pProgressDialog->setSubRangeTransformation(currentScan/nofScans, (currentScan+1)/nofScans);
|
joachim99@8
|
440 ++currentScan;
|
joachim99@8
|
441
|
joachim99@8
|
442 t_DirectoryList dirListA;
|
joachim99@8
|
443 bListDirSuccessA = m_dirA.listDir( &dirListA,
|
joachim99@8
|
444 m_pOptions->m_bDmRecursiveDirs, m_pOptions->m_bDmFindHidden,
|
joachim99@8
|
445 m_pOptions->m_DmFilePattern, m_pOptions->m_DmFileAntiPattern,
|
joachim99@8
|
446 m_pOptions->m_DmDirAntiPattern, m_pOptions->m_bDmFollowDirLinks,
|
joachim99@8
|
447 m_pOptions->m_bDmUseCvsIgnore);
|
joachim99@8
|
448
|
joachim99@8
|
449 for (i=dirListA.begin(); i!=dirListA.end();++i )
|
joachim99@8
|
450 {
|
joachim99@58
|
451 MergeFileInfos& mfi = m_fileMergeMap[sortString(i->filePath())];
|
joachim99@8
|
452 //std::cout <<i->filePath()<<std::endl;
|
joachim99@8
|
453 mfi.m_bExistsInA = true;
|
joachim99@8
|
454 mfi.m_fileInfoA = *i;
|
joachim99@8
|
455 }
|
joachim99@8
|
456 }
|
joachim99@8
|
457
|
joachim99@8
|
458 if ( m_dirB.isValid() )
|
joachim99@8
|
459 {
|
joachim99@51
|
460 g_pProgressDialog->setInformation(i18n("Reading Directory B"));
|
joachim99@8
|
461 g_pProgressDialog->setSubRangeTransformation(currentScan/nofScans, (currentScan+1)/nofScans);
|
joachim99@8
|
462 ++currentScan;
|
joachim99@8
|
463
|
joachim99@8
|
464 t_DirectoryList dirListB;
|
joachim99@8
|
465 bListDirSuccessB = m_dirB.listDir( &dirListB,
|
joachim99@8
|
466 m_pOptions->m_bDmRecursiveDirs, m_pOptions->m_bDmFindHidden,
|
joachim99@8
|
467 m_pOptions->m_DmFilePattern, m_pOptions->m_DmFileAntiPattern,
|
joachim99@8
|
468 m_pOptions->m_DmDirAntiPattern, m_pOptions->m_bDmFollowDirLinks,
|
joachim99@8
|
469 m_pOptions->m_bDmUseCvsIgnore);
|
joachim99@8
|
470
|
joachim99@8
|
471 for (i=dirListB.begin(); i!=dirListB.end();++i )
|
joachim99@8
|
472 {
|
joachim99@58
|
473 MergeFileInfos& mfi = m_fileMergeMap[sortString(i->filePath())];
|
joachim99@8
|
474 mfi.m_bExistsInB = true;
|
joachim99@8
|
475 mfi.m_fileInfoB = *i;
|
joachim99@8
|
476 }
|
joachim99@8
|
477 }
|
joachim99@8
|
478
|
joachim99@8
|
479 e_MergeOperation eDefaultMergeOp;
|
joachim99@8
|
480 if ( m_dirC.isValid() )
|
joachim99@8
|
481 {
|
joachim99@51
|
482 g_pProgressDialog->setInformation(i18n("Reading Directory C"));
|
joachim99@8
|
483 g_pProgressDialog->setSubRangeTransformation(currentScan/nofScans, (currentScan+1)/nofScans);
|
joachim99@8
|
484 ++currentScan;
|
joachim99@8
|
485
|
joachim99@8
|
486 t_DirectoryList dirListC;
|
joachim99@8
|
487 bListDirSuccessC = m_dirC.listDir( &dirListC,
|
joachim99@8
|
488 m_pOptions->m_bDmRecursiveDirs, m_pOptions->m_bDmFindHidden,
|
joachim99@8
|
489 m_pOptions->m_DmFilePattern, m_pOptions->m_DmFileAntiPattern,
|
joachim99@8
|
490 m_pOptions->m_DmDirAntiPattern, m_pOptions->m_bDmFollowDirLinks,
|
joachim99@8
|
491 m_pOptions->m_bDmUseCvsIgnore);
|
joachim99@8
|
492
|
joachim99@8
|
493 for (i=dirListC.begin(); i!=dirListC.end();++i )
|
joachim99@8
|
494 {
|
joachim99@58
|
495 MergeFileInfos& mfi = m_fileMergeMap[sortString(i->filePath())];
|
joachim99@8
|
496 mfi.m_bExistsInC = true;
|
joachim99@8
|
497 mfi.m_fileInfoC = *i;
|
joachim99@8
|
498 }
|
joachim99@8
|
499
|
joachim99@8
|
500 eDefaultMergeOp = eMergeABCToDest;
|
joachim99@8
|
501 }
|
joachim99@8
|
502 else
|
joachim99@8
|
503 eDefaultMergeOp = m_bSyncMode ? eMergeToAB : eMergeABToDest;
|
joachim99@8
|
504
|
joachim99@8
|
505 bool bContinue = true;
|
joachim99@8
|
506 if ( !bListDirSuccessA || !bListDirSuccessB || !bListDirSuccessC )
|
joachim99@8
|
507 {
|
joachim99@8
|
508 QString s = i18n("Some subdirectories were not readable in");
|
joachim99@8
|
509 if ( !bListDirSuccessA ) s += "\nA: " + m_dirA.prettyAbsPath();
|
joachim99@8
|
510 if ( !bListDirSuccessB ) s += "\nB: " + m_dirB.prettyAbsPath();
|
joachim99@8
|
511 if ( !bListDirSuccessC ) s += "\nC: " + m_dirC.prettyAbsPath();
|
joachim99@8
|
512 s+="\n";
|
joachim99@8
|
513 s+= i18n("Check the permissions of the subdirectories.");
|
joachim99@8
|
514 bContinue = KMessageBox::Continue == KMessageBox::warningContinueCancel( this, s );
|
joachim99@8
|
515 }
|
joachim99@8
|
516
|
joachim99@8
|
517 if ( bContinue )
|
joachim99@8
|
518 {
|
joachim99@8
|
519 prepareListView();
|
joachim99@8
|
520 g_pProgressDialog->hide();
|
joachim99@8
|
521
|
joachim99@8
|
522 for( QListViewItem* p = firstChild(); p!=0; p = p->nextSibling() )
|
joachim99@8
|
523 {
|
joachim99@8
|
524 DirMergeItem* pDMI = static_cast<DirMergeItem*>( p );
|
joachim99@8
|
525 calcSuggestedOperation( *pDMI->m_pMFI, eDefaultMergeOp );
|
joachim99@8
|
526 }
|
joachim99@8
|
527 }
|
joachim99@8
|
528 else
|
joachim99@8
|
529 {
|
joachim99@8
|
530 g_pProgressDialog->hide();
|
joachim99@8
|
531 setSelected( 0, true );
|
joachim99@8
|
532 }
|
joachim99@8
|
533
|
joachim99@8
|
534 QDir::setCurrent(origCurrentDirectory);
|
joachim99@8
|
535
|
joachim99@8
|
536 // Try to improve the view a little bit.
|
joachim99@8
|
537 QWidget* pParent = parentWidget();
|
joachim99@8
|
538 QSplitter* pSplitter = static_cast<QSplitter*>(pParent);
|
joachim99@8
|
539 if (pSplitter!=0)
|
joachim99@8
|
540 {
|
joachim99@8
|
541 QValueList<int> sizes = pSplitter->sizes();
|
joachim99@8
|
542 int total = sizes[0] + sizes[1];
|
joachim99@8
|
543 sizes[0]=total*6/10;
|
joachim99@8
|
544 sizes[1]=total - sizes[0];
|
joachim99@8
|
545 pSplitter->setSizes( sizes );
|
joachim99@8
|
546 }
|
joachim99@8
|
547
|
joachim99@8
|
548 if ( bContinue )
|
joachim99@8
|
549 {
|
joachim99@8
|
550 // Generate a status report
|
joachim99@8
|
551 int nofFiles=0;
|
joachim99@8
|
552 int nofDirs=0;
|
joachim99@8
|
553 int nofEqualFiles=0;
|
joachim99@8
|
554 int nofManualMerges=0;
|
joachim99@8
|
555 for( QListViewItem* p = firstChild(); p!=0; p = p->nextSibling() )
|
joachim99@8
|
556 calcDirStatus( m_dirC.isValid(), static_cast<DirMergeItem*>(p),
|
joachim99@8
|
557 nofFiles, nofDirs, nofEqualFiles, nofManualMerges );
|
joachim99@8
|
558
|
joachim99@8
|
559 QString s;
|
joachim99@51
|
560 s = i18n("Directory Comparison Status") + "\n\n" +
|
joachim99@8
|
561 i18n("Number of subdirectories:") +" "+ QString::number(nofDirs) + "\n"+
|
joachim99@8
|
562 i18n("Number of equal files:") +" "+ QString::number(nofEqualFiles) + "\n"+
|
joachim99@8
|
563 i18n("Number of different files:") +" "+ QString::number(nofFiles-nofEqualFiles);
|
joachim99@8
|
564
|
joachim99@8
|
565 if ( m_dirC.isValid() )
|
joachim99@8
|
566 s += "\n" + i18n("Number of manual merges:") +" "+ QString::number(nofManualMerges);
|
joachim99@8
|
567 KMessageBox::information( this, s );
|
joachim99@8
|
568 setSelected( firstChild(), true );
|
joachim99@8
|
569 }
|
joachim99@8
|
570
|
joachim99@8
|
571 return true;
|
joachim99@8
|
572 }
|
joachim99@8
|
573
|
joachim99@8
|
574
|
joachim99@8
|
575
|
joachim99@8
|
576 void DirectoryMergeWindow::slotChooseAEverywhere(){ setAllMergeOperations( eCopyAToDest ); }
|
joachim99@8
|
577
|
joachim99@8
|
578 void DirectoryMergeWindow::slotChooseBEverywhere(){ setAllMergeOperations( eCopyBToDest ); }
|
joachim99@8
|
579
|
joachim99@8
|
580 void DirectoryMergeWindow::slotChooseCEverywhere(){ setAllMergeOperations( eCopyCToDest ); }
|
joachim99@8
|
581
|
joachim99@8
|
582 void DirectoryMergeWindow::slotAutoChooseEverywhere()
|
joachim99@8
|
583 {
|
joachim99@8
|
584 e_MergeOperation eDefaultMergeOp = m_dirC.isValid() ? eMergeABCToDest :
|
joachim99@8
|
585 m_bSyncMode ? eMergeToAB : eMergeABToDest;
|
joachim99@8
|
586 setAllMergeOperations(eDefaultMergeOp );
|
joachim99@8
|
587 }
|
joachim99@8
|
588
|
joachim99@8
|
589 void DirectoryMergeWindow::slotNoOpEverywhere(){ setAllMergeOperations(eNoOperation); }
|
joachim99@8
|
590
|
joachim99@8
|
591 static void setListViewItemOpen( QListViewItem* p, bool bOpen )
|
joachim99@8
|
592 {
|
joachim99@8
|
593 for( QListViewItem* pChild = p->firstChild(); pChild!=0; pChild = pChild->nextSibling() )
|
joachim99@8
|
594 setListViewItemOpen( pChild, bOpen );
|
joachim99@8
|
595
|
joachim99@8
|
596 p->setOpen( bOpen );
|
joachim99@8
|
597 }
|
joachim99@8
|
598
|
joachim99@8
|
599 void DirectoryMergeWindow::slotFoldAllSubdirs()
|
joachim99@8
|
600 {
|
joachim99@8
|
601 for( QListViewItem* p = firstChild(); p!=0; p = p->nextSibling() )
|
joachim99@8
|
602 setListViewItemOpen( p, false );
|
joachim99@8
|
603 }
|
joachim99@8
|
604
|
joachim99@8
|
605 void DirectoryMergeWindow::slotUnfoldAllSubdirs()
|
joachim99@8
|
606 {
|
joachim99@8
|
607 for( QListViewItem* p = firstChild(); p!=0; p = p->nextSibling() )
|
joachim99@8
|
608 setListViewItemOpen( p, true );
|
joachim99@8
|
609 }
|
joachim99@8
|
610
|
joachim99@51
|
611 static void setMergeOperation( QListViewItem* pLVI, e_MergeOperation eMergeOp )
|
joachim99@51
|
612 {
|
joachim99@51
|
613 if ( pLVI==0 ) return;
|
joachim99@51
|
614
|
joachim99@51
|
615 DirMergeItem* pDMI = static_cast<DirMergeItem*>(pLVI);
|
joachim99@51
|
616 MergeFileInfos& mfi = *pDMI->m_pMFI;
|
joachim99@51
|
617
|
joachim99@51
|
618 mfi.setMergeOperation(eMergeOp );
|
joachim99@51
|
619 }
|
joachim99@51
|
620
|
joachim99@51
|
621 // Merge current item (merge mode)
|
joachim99@51
|
622 void DirectoryMergeWindow::slotCurrentDoNothing() { setMergeOperation(currentItem(), eNoOperation ); }
|
joachim99@53
|
623 void DirectoryMergeWindow::slotCurrentChooseA() { setMergeOperation(currentItem(), m_bSyncMode ? eCopyAToB : eCopyAToDest ); }
|
joachim99@53
|
624 void DirectoryMergeWindow::slotCurrentChooseB() { setMergeOperation(currentItem(), m_bSyncMode ? eCopyBToA : eCopyBToDest ); }
|
joachim99@51
|
625 void DirectoryMergeWindow::slotCurrentChooseC() { setMergeOperation(currentItem(), eCopyCToDest ); }
|
joachim99@51
|
626 void DirectoryMergeWindow::slotCurrentMerge()
|
joachim99@51
|
627 {
|
joachim99@51
|
628 bool bThreeDirs = m_dirC.isValid();
|
joachim99@51
|
629 setMergeOperation(currentItem(), bThreeDirs ? eMergeABCToDest : eMergeABToDest );
|
joachim99@51
|
630 }
|
joachim99@51
|
631 void DirectoryMergeWindow::slotCurrentDelete() { setMergeOperation(currentItem(), eDeleteFromDest ); }
|
joachim99@51
|
632 // Sync current item
|
joachim99@51
|
633 void DirectoryMergeWindow::slotCurrentCopyAToB() { setMergeOperation(currentItem(), eCopyAToB ); }
|
joachim99@51
|
634 void DirectoryMergeWindow::slotCurrentCopyBToA() { setMergeOperation(currentItem(), eCopyBToA ); }
|
joachim99@51
|
635 void DirectoryMergeWindow::slotCurrentDeleteA() { setMergeOperation(currentItem(), eDeleteA ); }
|
joachim99@51
|
636 void DirectoryMergeWindow::slotCurrentDeleteB() { setMergeOperation(currentItem(), eDeleteB ); }
|
joachim99@51
|
637 void DirectoryMergeWindow::slotCurrentDeleteAAndB() { setMergeOperation(currentItem(), eDeleteAB ); }
|
joachim99@51
|
638 void DirectoryMergeWindow::slotCurrentMergeToA() { setMergeOperation(currentItem(), eMergeToA ); }
|
joachim99@51
|
639 void DirectoryMergeWindow::slotCurrentMergeToB() { setMergeOperation(currentItem(), eMergeToB ); }
|
joachim99@51
|
640 void DirectoryMergeWindow::slotCurrentMergeToAAndB() { setMergeOperation(currentItem(), eMergeToAB ); }
|
joachim99@51
|
641
|
joachim99@51
|
642
|
joachim99@51
|
643 void DirectoryMergeWindow::keyPressEvent( QKeyEvent* e )
|
joachim99@51
|
644 {
|
joachim99@51
|
645 if ( (e->state() & Qt::ControlButton)!=0 )
|
joachim99@51
|
646 {
|
joachim99@51
|
647 bool bThreeDirs = m_dirC.isValid();
|
joachim99@51
|
648
|
joachim99@51
|
649 QListViewItem* lvi = currentItem();
|
joachim99@51
|
650 DirMergeItem* pDMI = lvi==0 ? 0 : static_cast<DirMergeItem*>(lvi);
|
joachim99@51
|
651 MergeFileInfos* pMFI = pDMI==0 ? 0 : pDMI->m_pMFI;
|
joachim99@51
|
652
|
joachim99@51
|
653 if ( pMFI==0 ) return;
|
joachim99@51
|
654 bool bMergeMode = bThreeDirs || !m_bSyncMode;
|
joachim99@51
|
655 bool bFTConflict = pMFI==0 ? false : conflictingFileTypes(*pMFI);
|
joachim99@51
|
656
|
joachim99@51
|
657 if ( bMergeMode )
|
joachim99@51
|
658 {
|
joachim99@51
|
659 switch(e->key())
|
joachim99@51
|
660 {
|
joachim99@51
|
661 case Key_1: if(pMFI->m_bExistsInA){ slotCurrentChooseA(); } return;
|
joachim99@51
|
662 case Key_2: if(pMFI->m_bExistsInB){ slotCurrentChooseB(); } return;
|
joachim99@51
|
663 case Key_3: if(pMFI->m_bExistsInC){ slotCurrentChooseC(); } return;
|
joachim99@51
|
664 case Key_Space: slotCurrentDoNothing(); return;
|
joachim99@51
|
665 case Key_4: if ( !bFTConflict ) { slotCurrentMerge(); } return;
|
joachim99@51
|
666 case Key_Delete: slotCurrentDelete(); return;
|
joachim99@51
|
667 default: break;
|
joachim99@51
|
668 }
|
joachim99@51
|
669 }
|
joachim99@51
|
670 else
|
joachim99@51
|
671 {
|
joachim99@51
|
672 switch(e->key())
|
joachim99@51
|
673 {
|
joachim99@51
|
674 case Key_1: if(pMFI->m_bExistsInA){ slotCurrentCopyAToB(); } return;
|
joachim99@51
|
675 case Key_2: if(pMFI->m_bExistsInB){ slotCurrentCopyBToA(); } return;
|
joachim99@51
|
676 case Key_Space: slotCurrentDoNothing(); return;
|
joachim99@51
|
677 case Key_4: if ( !bFTConflict ) { slotCurrentMergeToAAndB(); } return;
|
joachim99@51
|
678 case Key_Delete: if( pMFI->m_bExistsInA && pMFI->m_bExistsInB ) slotCurrentDeleteAAndB();
|
joachim99@51
|
679 else if( pMFI->m_bExistsInA ) slotCurrentDeleteA();
|
joachim99@51
|
680 else if( pMFI->m_bExistsInB ) slotCurrentDeleteB();
|
joachim99@51
|
681 return;
|
joachim99@51
|
682 default: break;
|
joachim99@51
|
683 }
|
joachim99@51
|
684 }
|
joachim99@51
|
685 }
|
joachim99@51
|
686
|
joachim99@51
|
687 QListView::keyPressEvent(e);
|
joachim99@51
|
688 }
|
joachim99@51
|
689
|
joachim99@53
|
690 void DirectoryMergeWindow::focusInEvent(QFocusEvent*)
|
joachim99@53
|
691 {
|
joachim99@53
|
692 updateAvailabilities();
|
joachim99@53
|
693 }
|
joachim99@53
|
694 void DirectoryMergeWindow::focusOutEvent(QFocusEvent*)
|
joachim99@53
|
695 {
|
joachim99@53
|
696 updateAvailabilities();
|
joachim99@53
|
697 }
|
joachim99@51
|
698
|
joachim99@8
|
699 void DirectoryMergeWindow::setAllMergeOperations( e_MergeOperation eDefaultOperation )
|
joachim99@8
|
700 {
|
joachim99@8
|
701 if ( KMessageBox::Yes == KMessageBox::warningYesNo(this,
|
joachim99@8
|
702 i18n("This affects all merge operations."),
|
joachim99@51
|
703 i18n("Changing All Merge Operations"),i18n("C&ontinue"), i18n("&Cancel") ) )
|
joachim99@8
|
704 {
|
joachim99@8
|
705 for( QListViewItem* p = firstChild(); p!=0; p = p->nextSibling() )
|
joachim99@8
|
706 {
|
joachim99@8
|
707 DirMergeItem* pDMI = static_cast<DirMergeItem*>( p );
|
joachim99@8
|
708 calcSuggestedOperation( *pDMI->m_pMFI, eDefaultOperation );
|
joachim99@8
|
709 }
|
joachim99@8
|
710 }
|
joachim99@8
|
711 }
|
joachim99@8
|
712
|
joachim99@8
|
713
|
joachim99@8
|
714 void DirectoryMergeWindow::compareFilesAndCalcAges( MergeFileInfos& mfi )
|
joachim99@8
|
715 {
|
joachim99@8
|
716 std::map<QDateTime,int> dateMap;
|
joachim99@8
|
717
|
joachim99@8
|
718 if( mfi.m_bExistsInA )
|
joachim99@8
|
719 {
|
joachim99@8
|
720 mfi.m_bLinkA = mfi.m_fileInfoA.isSymLink();
|
joachim99@8
|
721 mfi.m_bDirA = mfi.m_fileInfoA.isDir();
|
joachim99@8
|
722 dateMap[ mfi.m_fileInfoA.lastModified() ] = 0;
|
joachim99@8
|
723 }
|
joachim99@8
|
724 if( mfi.m_bExistsInB )
|
joachim99@8
|
725 {
|
joachim99@8
|
726 mfi.m_bLinkB = mfi.m_fileInfoB.isSymLink();
|
joachim99@8
|
727 mfi.m_bDirB = mfi.m_fileInfoB.isDir();
|
joachim99@8
|
728 dateMap[ mfi.m_fileInfoB.lastModified() ] = 1;
|
joachim99@8
|
729 }
|
joachim99@8
|
730 if( mfi.m_bExistsInC )
|
joachim99@8
|
731 {
|
joachim99@8
|
732 mfi.m_bLinkC = mfi.m_fileInfoC.isSymLink();
|
joachim99@8
|
733 mfi.m_bDirC = mfi.m_fileInfoC.isDir();
|
joachim99@8
|
734 dateMap[ mfi.m_fileInfoC.lastModified() ] = 2;
|
joachim99@8
|
735 }
|
joachim99@8
|
736
|
joachim99@8
|
737 bool bError;
|
joachim99@8
|
738 QString eqStatus;
|
joachim99@8
|
739 if( mfi.m_bExistsInA && mfi.m_bExistsInB )
|
joachim99@8
|
740 {
|
joachim99@8
|
741 if( mfi.m_bDirA ) mfi.m_bEqualAB=true;
|
joachim99@8
|
742 else fastFileComparison( mfi.m_fileInfoA, mfi.m_fileInfoB, mfi.m_bEqualAB, bError, eqStatus );
|
joachim99@8
|
743 }
|
joachim99@8
|
744 if( mfi.m_bExistsInA && mfi.m_bExistsInC )
|
joachim99@8
|
745 {
|
joachim99@8
|
746 if( mfi.m_bDirA ) mfi.m_bEqualAC=true;
|
joachim99@8
|
747 else fastFileComparison( mfi.m_fileInfoA, mfi.m_fileInfoC, mfi.m_bEqualAC, bError, eqStatus );
|
joachim99@8
|
748 }
|
joachim99@8
|
749 if( mfi.m_bExistsInB && mfi.m_bExistsInC )
|
joachim99@8
|
750 {
|
joachim99@8
|
751 if (mfi.m_bEqualAB && mfi.m_bEqualAC)
|
joachim99@8
|
752 mfi.m_bEqualBC = true;
|
joachim99@8
|
753 else
|
joachim99@8
|
754 {
|
joachim99@8
|
755 if( mfi.m_bDirB ) mfi.m_bEqualBC=true;
|
joachim99@8
|
756 else fastFileComparison( mfi.m_fileInfoB, mfi.m_fileInfoC, mfi.m_bEqualBC, bError, eqStatus );
|
joachim99@8
|
757 }
|
joachim99@8
|
758 }
|
joachim99@8
|
759
|
joachim99@8
|
760 if (mfi.m_bLinkA!=mfi.m_bLinkB) mfi.m_bEqualAB=false;
|
joachim99@8
|
761 if (mfi.m_bLinkA!=mfi.m_bLinkC) mfi.m_bEqualAC=false;
|
joachim99@8
|
762 if (mfi.m_bLinkB!=mfi.m_bLinkC) mfi.m_bEqualBC=false;
|
joachim99@8
|
763
|
joachim99@8
|
764 if (mfi.m_bDirA!=mfi.m_bDirB) mfi.m_bEqualAB=false;
|
joachim99@8
|
765 if (mfi.m_bDirA!=mfi.m_bDirC) mfi.m_bEqualAC=false;
|
joachim99@8
|
766 if (mfi.m_bDirB!=mfi.m_bDirC) mfi.m_bEqualBC=false;
|
joachim99@8
|
767
|
joachim99@8
|
768 assert(eNew==0 && eMiddle==1 && eOld==2);
|
joachim99@8
|
769
|
joachim99@8
|
770 // The map automatically sorts the keys.
|
joachim99@8
|
771 int age = eNew;
|
joachim99@8
|
772 std::map<QDateTime,int>::reverse_iterator i;
|
joachim99@8
|
773 for( i=dateMap.rbegin(); i!=dateMap.rend(); ++i )
|
joachim99@8
|
774 {
|
joachim99@8
|
775 int n = i->second;
|
joachim99@8
|
776 if ( n==0 && mfi.m_ageA==eNotThere )
|
joachim99@8
|
777 {
|
joachim99@8
|
778 mfi.m_ageA = (e_Age)age; ++age;
|
joachim99@8
|
779 if ( mfi.m_bEqualAB ) { mfi.m_ageB = mfi.m_ageA; ++age; }
|
joachim99@8
|
780 if ( mfi.m_bEqualAC ) { mfi.m_ageC = mfi.m_ageA; ++age; }
|
joachim99@8
|
781 }
|
joachim99@8
|
782 else if ( n==1 && mfi.m_ageB==eNotThere )
|
joachim99@8
|
783 {
|
joachim99@8
|
784 mfi.m_ageB = (e_Age)age; ++age;
|
joachim99@8
|
785 if ( mfi.m_bEqualAB ) { mfi.m_ageA = mfi.m_ageB; ++age; }
|
joachim99@8
|
786 if ( mfi.m_bEqualBC ) { mfi.m_ageC = mfi.m_ageB; ++age; }
|
joachim99@8
|
787 }
|
joachim99@8
|
788 else if ( n==2 && mfi.m_ageC==eNotThere)
|
joachim99@8
|
789 {
|
joachim99@8
|
790 mfi.m_ageC = (e_Age)age; ++age;
|
joachim99@8
|
791 if ( mfi.m_bEqualAC ) { mfi.m_ageA = mfi.m_ageC; ++age; }
|
joachim99@8
|
792 if ( mfi.m_bEqualBC ) { mfi.m_ageB = mfi.m_ageC; ++age; }
|
joachim99@8
|
793 }
|
joachim99@8
|
794 }
|
joachim99@8
|
795
|
joachim99@8
|
796 // The checks below are necessary when the dates of the file are equal but the
|
joachim99@8
|
797 // files are not. One wouldn't expect this to happen, yet it happens sometimes.
|
joachim99@8
|
798 if ( mfi.m_bExistsInC && mfi.m_ageC==eNotThere )
|
joachim99@8
|
799 {
|
joachim99@8
|
800 mfi.m_ageC = (e_Age)age; ++age;
|
joachim99@8
|
801 mfi.m_bConflictingAges = true;
|
joachim99@8
|
802 }
|
joachim99@8
|
803 if ( mfi.m_bExistsInB && mfi.m_ageB==eNotThere )
|
joachim99@8
|
804 {
|
joachim99@8
|
805 mfi.m_ageB = (e_Age)age; ++age;
|
joachim99@8
|
806 mfi.m_bConflictingAges = true;
|
joachim99@8
|
807 }
|
joachim99@8
|
808 if ( mfi.m_bExistsInA && mfi.m_ageA==eNotThere )
|
joachim99@8
|
809 {
|
joachim99@8
|
810 mfi.m_ageA = (e_Age)age; ++age;
|
joachim99@8
|
811 mfi.m_bConflictingAges = true;
|
joachim99@8
|
812 }
|
joachim99@8
|
813
|
joachim99@8
|
814 if ( mfi.m_ageA != eOld && mfi.m_ageB != eOld && mfi.m_ageC != eOld )
|
joachim99@8
|
815 {
|
joachim99@8
|
816 if (mfi.m_ageA == eMiddle) mfi.m_ageA = eOld;
|
joachim99@8
|
817 if (mfi.m_ageB == eMiddle) mfi.m_ageB = eOld;
|
joachim99@8
|
818 if (mfi.m_ageC == eMiddle) mfi.m_ageC = eOld;
|
joachim99@8
|
819 }
|
joachim99@8
|
820 }
|
joachim99@8
|
821
|
joachim99@8
|
822 static QPixmap* s_pm_dir;
|
joachim99@8
|
823 static QPixmap* s_pm_file;
|
joachim99@8
|
824
|
joachim99@8
|
825 static void setOnePixmap( QListViewItem* pLVI, int col, e_Age eAge, bool bLink, bool bDir )
|
joachim99@8
|
826 {
|
joachim99@8
|
827 #include "xpm/equal.xpm"
|
joachim99@8
|
828 #include "xpm/not_equal.xpm"
|
joachim99@8
|
829 #include "xpm/not_everywhere.xpm"
|
joachim99@8
|
830 #include "xpm/not_there.xpm"
|
joachim99@8
|
831 #include "xpm/link_arrow.xpm"
|
joachim99@8
|
832
|
joachim99@8
|
833 static QPixmap pmLink( link_arrow );
|
joachim99@8
|
834
|
joachim99@8
|
835 static QPixmap pmDirLink( pixCombiner( *s_pm_dir, pmLink) );
|
joachim99@8
|
836 static QPixmap pmFileLink( pixCombiner( *s_pm_file, pmLink ) );
|
joachim99@8
|
837
|
joachim99@8
|
838 static QPixmap pmNotThere( not_there_pm );
|
joachim99@8
|
839
|
joachim99@8
|
840 static QPixmap pmNew( equal_pm );
|
joachim99@8
|
841 static QPixmap pmOld( not_equal_pm );
|
joachim99@8
|
842 static QPixmap pmMiddle( not_everywhere_pm );
|
joachim99@8
|
843
|
joachim99@8
|
844 static QPixmap pmNewLink( pixCombiner( pmNew, pmLink) );
|
joachim99@8
|
845 static QPixmap pmOldLink( pixCombiner( pmOld, pmLink) );
|
joachim99@8
|
846 static QPixmap pmMiddleLink( pixCombiner( pmMiddle, pmLink) );
|
joachim99@8
|
847
|
joachim99@8
|
848 static QPixmap pmNewDir( pixCombiner2( pmNew, *s_pm_dir) );
|
joachim99@8
|
849 static QPixmap pmMiddleDir( pixCombiner2( pmMiddle, *s_pm_dir) );
|
joachim99@8
|
850 static QPixmap pmOldDir( pixCombiner2( pmOld, *s_pm_dir) );
|
joachim99@8
|
851
|
joachim99@8
|
852 static QPixmap pmNewDirLink( pixCombiner( pmNewDir, pmLink) );
|
joachim99@8
|
853 static QPixmap pmMiddleDirLink( pixCombiner( pmMiddleDir, pmLink) );
|
joachim99@8
|
854 static QPixmap pmOldDirLink( pixCombiner( pmOldDir, pmLink) );
|
joachim99@8
|
855
|
joachim99@8
|
856 static QPixmap* ageToPm[]= { &pmNew, &pmMiddle, &pmOld, &pmNotThere, s_pm_file };
|
joachim99@8
|
857 static QPixmap* ageToPmLink[]= { &pmNewLink, &pmMiddleLink, &pmOldLink, &pmNotThere, &pmFileLink };
|
joachim99@8
|
858 static QPixmap* ageToPmDir[]= { &pmNewDir, &pmMiddleDir, &pmOldDir, &pmNotThere, s_pm_dir };
|
joachim99@8
|
859 static QPixmap* ageToPmDirLink[]={ &pmNewDirLink, &pmMiddleDirLink, &pmOldDirLink, &pmNotThere, &pmDirLink };
|
joachim99@8
|
860
|
joachim99@8
|
861 QPixmap** ppPm = bDir ? ( bLink ? ageToPmDirLink : ageToPmDir ):
|
joachim99@8
|
862 ( bLink ? ageToPmLink : ageToPm );
|
joachim99@8
|
863
|
joachim99@8
|
864 pLVI->setPixmap( col, *ppPm[eAge] );
|
joachim99@8
|
865 }
|
joachim99@8
|
866
|
joachim99@8
|
867 static void setPixmaps( MergeFileInfos& mfi, bool bCheckC )
|
joachim99@8
|
868 {
|
joachim99@8
|
869 setOnePixmap( mfi.m_pDMI, s_nameCol, eAgeEnd,
|
joachim99@8
|
870 mfi.m_bLinkA || mfi.m_bLinkB || mfi.m_bLinkC,
|
joachim99@8
|
871 mfi.m_bDirA || mfi.m_bDirB || mfi.m_bDirC
|
joachim99@8
|
872 );
|
joachim99@8
|
873
|
joachim99@8
|
874 if ( mfi.m_bDirA || mfi.m_bDirB || mfi.m_bDirC )
|
joachim99@8
|
875 {
|
joachim99@8
|
876 mfi.m_ageA=eNotThere;
|
joachim99@8
|
877 mfi.m_ageB=eNotThere;
|
joachim99@8
|
878 mfi.m_ageC=eNotThere;
|
joachim99@8
|
879 int age = eNew;
|
joachim99@8
|
880 if ( mfi.m_bExistsInC )
|
joachim99@8
|
881 {
|
joachim99@8
|
882 mfi.m_ageC = (e_Age)age;
|
joachim99@8
|
883 if (mfi.m_bEqualAC) mfi.m_ageA = (e_Age)age;
|
joachim99@8
|
884 if (mfi.m_bEqualBC) mfi.m_ageB = (e_Age)age;
|
joachim99@8
|
885 ++age;
|
joachim99@8
|
886 }
|
joachim99@8
|
887 if ( mfi.m_bExistsInB && mfi.m_ageB==eNotThere )
|
joachim99@8
|
888 {
|
joachim99@8
|
889 mfi.m_ageB = (e_Age)age;
|
joachim99@8
|
890 if (mfi.m_bEqualAB) mfi.m_ageA = (e_Age)age;
|
joachim99@8
|
891 ++age;
|
joachim99@8
|
892 }
|
joachim99@8
|
893 if ( mfi.m_bExistsInA && mfi.m_ageA==eNotThere )
|
joachim99@8
|
894 {
|
joachim99@8
|
895 mfi.m_ageA = (e_Age)age;
|
joachim99@8
|
896 }
|
joachim99@8
|
897 if ( mfi.m_ageA != eOld && mfi.m_ageB != eOld && mfi.m_ageC != eOld )
|
joachim99@8
|
898 {
|
joachim99@8
|
899 if (mfi.m_ageA == eMiddle) mfi.m_ageA = eOld;
|
joachim99@8
|
900 if (mfi.m_ageB == eMiddle) mfi.m_ageB = eOld;
|
joachim99@8
|
901 if (mfi.m_ageC == eMiddle) mfi.m_ageC = eOld;
|
joachim99@8
|
902 }
|
joachim99@8
|
903 }
|
joachim99@8
|
904
|
joachim99@8
|
905 setOnePixmap( mfi.m_pDMI, s_ACol, mfi.m_ageA, mfi.m_bLinkA, mfi.m_bDirA );
|
joachim99@8
|
906 setOnePixmap( mfi.m_pDMI, s_BCol, mfi.m_ageB, mfi.m_bLinkB, mfi.m_bDirB );
|
joachim99@8
|
907 if ( bCheckC )
|
joachim99@8
|
908 setOnePixmap( mfi.m_pDMI, s_CCol, mfi.m_ageC, mfi.m_bLinkC, mfi.m_bDirC );
|
joachim99@8
|
909 }
|
joachim99@8
|
910
|
joachim99@8
|
911 // Iterate through the complete tree. Start by specifying QListView::firstChild().
|
joachim99@8
|
912 static QListViewItem* treeIterator( QListViewItem* p, bool bVisitChildren=true )
|
joachim99@8
|
913 {
|
joachim99@8
|
914 if( p!=0 )
|
joachim99@8
|
915 {
|
joachim99@8
|
916 if ( bVisitChildren && p->firstChild() != 0 ) p = p->firstChild();
|
joachim99@8
|
917 else if ( p->nextSibling() !=0 ) p = p->nextSibling();
|
joachim99@8
|
918 else
|
joachim99@8
|
919 {
|
joachim99@8
|
920 p = p->parent();
|
joachim99@8
|
921 while ( p!=0 )
|
joachim99@8
|
922 {
|
joachim99@8
|
923 if( p->nextSibling()!=0 ) { p = p->nextSibling(); break; }
|
joachim99@8
|
924 else { p = p->parent(); }
|
joachim99@8
|
925 }
|
joachim99@8
|
926 }
|
joachim99@8
|
927 }
|
joachim99@8
|
928 return p;
|
joachim99@8
|
929 }
|
joachim99@8
|
930
|
joachim99@8
|
931 void DirectoryMergeWindow::prepareListView()
|
joachim99@8
|
932 {
|
joachim99@8
|
933 static bool bFirstTime = true;
|
joachim99@8
|
934 if (bFirstTime)
|
joachim99@8
|
935 {
|
joachim99@8
|
936 #include "xpm/file.xpm"
|
joachim99@8
|
937 #include "xpm/folder.xpm"
|
joachim99@8
|
938 s_pm_dir = new QPixmap( m_pIconLoader->loadIcon("folder", KIcon::Small ) );
|
joachim99@8
|
939 if (s_pm_dir->size()!=QSize(16,16))
|
joachim99@8
|
940 {
|
joachim99@8
|
941 delete s_pm_dir;
|
joachim99@8
|
942 s_pm_dir = new QPixmap( folder_pm );
|
joachim99@8
|
943 }
|
joachim99@8
|
944 s_pm_file= new QPixmap( file_pm );
|
joachim99@8
|
945 bFirstTime=false;
|
joachim99@8
|
946 }
|
joachim99@8
|
947
|
joachim99@8
|
948 clear();
|
joachim99@8
|
949
|
joachim99@8
|
950 setRootIsDecorated( true );
|
joachim99@8
|
951
|
joachim99@8
|
952 bool bCheckC = m_dirC.isValid();
|
joachim99@8
|
953
|
joachim99@8
|
954 std::map<QString, MergeFileInfos>::iterator j;
|
joachim99@8
|
955 int nrOfFiles = m_fileMergeMap.size();
|
joachim99@8
|
956 int currentIdx = 1;
|
joachim99@8
|
957 QTime t;
|
joachim99@8
|
958 t.start();
|
joachim99@8
|
959 for( j=m_fileMergeMap.begin(); j!=m_fileMergeMap.end(); ++j )
|
joachim99@8
|
960 {
|
joachim99@8
|
961 MergeFileInfos& mfi = j->second;
|
joachim99@8
|
962
|
joachim99@8
|
963 mfi.m_subPath = mfi.m_fileInfoA.exists() ? mfi.m_fileInfoA.filePath() :
|
joachim99@8
|
964 mfi.m_fileInfoB.exists() ? mfi.m_fileInfoB.filePath() :
|
joachim99@25
|
965 mfi.m_fileInfoC.exists() ? mfi.m_fileInfoC.filePath() :
|
joachim99@25
|
966 QString("");
|
joachim99@8
|
967
|
joachim99@58
|
968 // const QString& fileName = j->first;
|
joachim99@58
|
969 const QString& fileName = mfi.m_subPath;
|
joachim99@58
|
970
|
joachim99@8
|
971 g_pProgressDialog->setInformation(
|
joachim99@51
|
972 i18n("Processing ") + QString::number(currentIdx) +" / "+ QString::number(nrOfFiles)
|
joachim99@8
|
973 +"\n" + fileName, double(currentIdx) / nrOfFiles, false );
|
joachim99@8
|
974 if ( g_pProgressDialog->wasCancelled() ) break;
|
joachim99@8
|
975 ++currentIdx;
|
joachim99@8
|
976
|
joachim99@8
|
977
|
joachim99@8
|
978 // The comparisons and calculations for each file take place here.
|
joachim99@8
|
979 compareFilesAndCalcAges( mfi );
|
joachim99@8
|
980
|
joachim99@8
|
981 bool bEqual = bCheckC ? mfi.m_bEqualAB && mfi.m_bEqualAC : mfi.m_bEqualAB;
|
joachim99@8
|
982 bool bDir = mfi.m_bDirA || mfi.m_bDirB || mfi.m_bDirC;
|
joachim99@8
|
983
|
joachim99@8
|
984 if ( m_pOptions->m_bDmShowOnlyDeltas && !bDir && bEqual )
|
joachim99@8
|
985 continue;
|
joachim99@8
|
986
|
joachim99@8
|
987 // Get dirname from fileName: Search for "/" from end:
|
joachim99@8
|
988 int pos = fileName.findRev('/');
|
joachim99@8
|
989 QString dirPart;
|
joachim99@8
|
990 QString filePart;
|
joachim99@8
|
991 if (pos==-1)
|
joachim99@8
|
992 {
|
joachim99@8
|
993 // Top dir
|
joachim99@8
|
994 filePart = fileName;
|
joachim99@8
|
995 }
|
joachim99@8
|
996 else
|
joachim99@8
|
997 {
|
joachim99@8
|
998 dirPart = fileName.left(pos);
|
joachim99@8
|
999 filePart = fileName.mid(pos+1);
|
joachim99@8
|
1000 }
|
joachim99@8
|
1001
|
joachim99@8
|
1002 if ( dirPart.isEmpty() ) // Top level
|
joachim99@8
|
1003 {
|
joachim99@8
|
1004 new DirMergeItem( this, filePart, &mfi );
|
joachim99@8
|
1005 }
|
joachim99@8
|
1006 else
|
joachim99@8
|
1007 {
|
joachim99@58
|
1008 MergeFileInfos& dirMfi = m_fileMergeMap[sortString(dirPart)]; // parent
|
joachim99@8
|
1009 assert(dirMfi.m_pDMI!=0);
|
joachim99@8
|
1010 new DirMergeItem( dirMfi.m_pDMI, filePart, &mfi );
|
joachim99@8
|
1011 mfi.m_pParent = &dirMfi;
|
joachim99@8
|
1012
|
joachim99@8
|
1013 if ( !bEqual ) // Set all parents to "not equal"
|
joachim99@8
|
1014 {
|
joachim99@8
|
1015 MergeFileInfos* p = mfi.m_pParent;
|
joachim99@8
|
1016 while(p!=0)
|
joachim99@8
|
1017 {
|
joachim99@8
|
1018 bool bChange = false;
|
joachim99@8
|
1019 if ( !mfi.m_bEqualAB && p->m_bEqualAB ){ p->m_bEqualAB = false; bChange=true; }
|
joachim99@8
|
1020 if ( !mfi.m_bEqualAC && p->m_bEqualAC ){ p->m_bEqualAC = false; bChange=true; }
|
joachim99@8
|
1021 if ( !mfi.m_bEqualBC && p->m_bEqualBC ){ p->m_bEqualBC = false; bChange=true; }
|
joachim99@8
|
1022
|
joachim99@8
|
1023 if ( bChange )
|
joachim99@8
|
1024 setPixmaps( *p, bCheckC );
|
joachim99@8
|
1025 else
|
joachim99@8
|
1026 break;
|
joachim99@8
|
1027
|
joachim99@8
|
1028 p = p->m_pParent;
|
joachim99@8
|
1029 }
|
joachim99@8
|
1030 }
|
joachim99@8
|
1031 }
|
joachim99@8
|
1032
|
joachim99@8
|
1033 setPixmaps( mfi, bCheckC );
|
joachim99@8
|
1034 }
|
joachim99@8
|
1035
|
joachim99@8
|
1036 if ( m_pOptions->m_bDmShowOnlyDeltas )
|
joachim99@8
|
1037 {
|
joachim99@8
|
1038 // Remove all equals. (Search tree depth first)
|
joachim99@8
|
1039 QListViewItem* p = firstChild();
|
joachim99@8
|
1040 while( p!=0 && firstChild() != 0 )
|
joachim99@8
|
1041 {
|
joachim99@8
|
1042 QListViewItem* pParent = p->parent();
|
joachim99@8
|
1043 QListViewItem* pNextSibling = p->nextSibling();
|
joachim99@8
|
1044
|
joachim99@8
|
1045 DirMergeItem* pDMI = static_cast<DirMergeItem*>(p);
|
joachim99@8
|
1046 bool bDirEqual = bCheckC ? pDMI->m_pMFI->m_bEqualAB && pDMI->m_pMFI->m_bEqualAC
|
joachim99@8
|
1047 : pDMI->m_pMFI->m_bEqualAB;
|
joachim99@8
|
1048 if ( pDMI!=0 && pDMI->m_pMFI->m_bDirA && bDirEqual )
|
joachim99@8
|
1049 {
|
joachim99@8
|
1050 delete p;
|
joachim99@8
|
1051 p=0;
|
joachim99@8
|
1052 }
|
joachim99@8
|
1053
|
joachim99@8
|
1054 if ( p!=0 && p->firstChild() != 0 ) p = p->firstChild();
|
joachim99@8
|
1055 else if ( pNextSibling!=0 ) p = pNextSibling;
|
joachim99@8
|
1056 else
|
joachim99@8
|
1057 {
|
joachim99@8
|
1058 p=pParent;
|
joachim99@8
|
1059 while ( p!=0 )
|
joachim99@8
|
1060 {
|
joachim99@8
|
1061 if( p->nextSibling()!=0 ) { p = p->nextSibling(); break; }
|
joachim99@8
|
1062 else { p = p->parent(); }
|
joachim99@8
|
1063 }
|
joachim99@8
|
1064 }
|
joachim99@8
|
1065 }
|
joachim99@8
|
1066 }
|
joachim99@8
|
1067 }
|
joachim99@8
|
1068
|
joachim99@8
|
1069 static bool conflictingFileTypes(MergeFileInfos& mfi)
|
joachim99@8
|
1070 {
|
joachim99@8
|
1071 // Now check if file/dir-types fit.
|
joachim99@8
|
1072 if ( mfi.m_bLinkA || mfi.m_bLinkB || mfi.m_bLinkC )
|
joachim99@8
|
1073 {
|
joachim99@8
|
1074 if ( mfi.m_bExistsInA && ! mfi.m_bLinkA ||
|
joachim99@8
|
1075 mfi.m_bExistsInB && ! mfi.m_bLinkB ||
|
joachim99@8
|
1076 mfi.m_bExistsInC && ! mfi.m_bLinkC )
|
joachim99@8
|
1077 {
|
joachim99@8
|
1078 return true;
|
joachim99@8
|
1079 }
|
joachim99@8
|
1080 }
|
joachim99@8
|
1081
|
joachim99@8
|
1082 if ( mfi.m_bDirA || mfi.m_bDirB || mfi.m_bDirC )
|
joachim99@8
|
1083 {
|
joachim99@8
|
1084 if ( mfi.m_bExistsInA && ! mfi.m_bDirA ||
|
joachim99@8
|
1085 mfi.m_bExistsInB && ! mfi.m_bDirB ||
|
joachim99@8
|
1086 mfi.m_bExistsInC && ! mfi.m_bDirC )
|
joachim99@8
|
1087 {
|
joachim99@8
|
1088 return true;
|
joachim99@8
|
1089 }
|
joachim99@8
|
1090 }
|
joachim99@8
|
1091 return false;
|
joachim99@8
|
1092 }
|
joachim99@8
|
1093
|
joachim99@8
|
1094 void DirectoryMergeWindow::calcSuggestedOperation( MergeFileInfos& mfi, e_MergeOperation eDefaultMergeOp )
|
joachim99@8
|
1095 {
|
joachim99@8
|
1096 bool bCheckC = m_dirC.isValid();
|
joachim99@8
|
1097 bool bCopyNewer = m_pOptions->m_bDmCopyNewer;
|
joachim99@8
|
1098
|
joachim99@8
|
1099 if ( eDefaultMergeOp == eMergeABCToDest && !bCheckC ) { eDefaultMergeOp = eMergeABToDest; }
|
joachim99@8
|
1100 if ( eDefaultMergeOp == eMergeToAB && bCheckC ) { assert(false); }
|
joachim99@51
|
1101
|
joachim99@8
|
1102 if ( eDefaultMergeOp == eMergeToA || eDefaultMergeOp == eMergeToB ||
|
joachim99@8
|
1103 eDefaultMergeOp == eMergeABCToDest || eDefaultMergeOp == eMergeABToDest || eDefaultMergeOp == eMergeToAB )
|
joachim99@51
|
1104 {
|
joachim99@8
|
1105 if ( !bCheckC )
|
joachim99@8
|
1106 {
|
joachim99@8
|
1107 if ( mfi.m_bEqualAB )
|
joachim99@8
|
1108 {
|
joachim99@8
|
1109 mfi.setMergeOperation( eNoOperation ); // All is well, nothing to do.
|
joachim99@8
|
1110 }
|
joachim99@8
|
1111 else if ( mfi.m_bExistsInA && mfi.m_bExistsInB )
|
joachim99@8
|
1112 {
|
joachim99@8
|
1113 if ( !bCopyNewer || mfi.m_bDirA )
|
joachim99@8
|
1114 mfi.setMergeOperation( eDefaultMergeOp );
|
joachim99@8
|
1115 else if ( bCopyNewer && mfi.m_bConflictingAges )
|
joachim99@8
|
1116 {
|
joachim99@8
|
1117 mfi.setMergeOperation( eConflictingAges );
|
joachim99@8
|
1118 }
|
joachim99@8
|
1119 else
|
joachim99@8
|
1120 {
|
joachim99@8
|
1121 if ( mfi.m_ageA == eNew )
|
joachim99@8
|
1122 mfi.setMergeOperation( eDefaultMergeOp == eMergeToAB ? eCopyAToB : eCopyAToDest );
|
joachim99@8
|
1123 else
|
joachim99@8
|
1124 mfi.setMergeOperation( eDefaultMergeOp == eMergeToAB ? eCopyBToA : eCopyBToDest );
|
joachim99@8
|
1125 }
|
joachim99@8
|
1126 }
|
joachim99@8
|
1127 else if ( !mfi.m_bExistsInA && mfi.m_bExistsInB )
|
joachim99@8
|
1128 {
|
joachim99@8
|
1129 if ( eDefaultMergeOp==eMergeABToDest ) mfi.setMergeOperation( eCopyBToDest );
|
joachim99@8
|
1130 else if ( eDefaultMergeOp==eMergeToB ) mfi.setMergeOperation( eNoOperation );
|
joachim99@8
|
1131 else mfi.setMergeOperation( eCopyBToA );
|
joachim99@8
|
1132 }
|
joachim99@8
|
1133 else if ( mfi.m_bExistsInA && !mfi.m_bExistsInB )
|
joachim99@8
|
1134 {
|
joachim99@8
|
1135 if ( eDefaultMergeOp==eMergeABToDest ) mfi.setMergeOperation( eCopyAToDest );
|
joachim99@8
|
1136 else if ( eDefaultMergeOp==eMergeToA ) mfi.setMergeOperation( eNoOperation );
|
joachim99@8
|
1137 else mfi.setMergeOperation( eCopyAToB );
|
joachim99@8
|
1138 }
|
joachim99@8
|
1139 else //if ( !mfi.m_bExistsInA && !mfi.m_bExistsInB )
|
joachim99@8
|
1140 {
|
joachim99@8
|
1141 mfi.setMergeOperation( eNoOperation ); assert(false);
|
joachim99@8
|
1142 }
|
joachim99@8
|
1143 }
|
joachim99@8
|
1144 else
|
joachim99@8
|
1145 {
|
joachim99@8
|
1146 if ( mfi.m_bEqualAB && mfi.m_bEqualAC )
|
joachim99@8
|
1147 {
|
joachim99@8
|
1148 mfi.setMergeOperation( eCopyCToDest );
|
joachim99@8
|
1149 }
|
joachim99@8
|
1150 else if ( mfi.m_bExistsInA && mfi.m_bExistsInB && mfi.m_bExistsInC)
|
joachim99@8
|
1151 {
|
joachim99@8
|
1152 if ( mfi.m_bEqualAB )
|
joachim99@8
|
1153 mfi.setMergeOperation( eCopyCToDest );
|
joachim99@8
|
1154 else if ( mfi.m_bEqualAC )
|
joachim99@8
|
1155 mfi.setMergeOperation( eCopyBToDest );
|
joachim99@8
|
1156 else if ( mfi.m_bEqualBC )
|
joachim99@8
|
1157 mfi.setMergeOperation( eCopyCToDest );
|
joachim99@8
|
1158 else
|
joachim99@8
|
1159 mfi.setMergeOperation( eMergeABCToDest );
|
joachim99@8
|
1160 }
|
joachim99@8
|
1161 else if ( mfi.m_bExistsInA && mfi.m_bExistsInB && !mfi.m_bExistsInC )
|
joachim99@8
|
1162 {
|
joachim99@8
|
1163 if ( mfi.m_bEqualAB )
|
joachim99@8
|
1164 mfi.setMergeOperation( eDeleteFromDest );
|
joachim99@8
|
1165 else
|
joachim99@8
|
1166 mfi.setMergeOperation( eCopyBToDest );
|
joachim99@8
|
1167 }
|
joachim99@8
|
1168 else if ( mfi.m_bExistsInA && !mfi.m_bExistsInB && mfi.m_bExistsInC )
|
joachim99@8
|
1169 {
|
joachim99@8
|
1170 if ( mfi.m_bEqualAC )
|
joachim99@8
|
1171 mfi.setMergeOperation( eDeleteFromDest );
|
joachim99@8
|
1172 else
|
joachim99@8
|
1173 mfi.setMergeOperation( eCopyCToDest );
|
joachim99@8
|
1174 }
|
joachim99@8
|
1175 else if ( !mfi.m_bExistsInA && mfi.m_bExistsInB && mfi.m_bExistsInC )
|
joachim99@8
|
1176 {
|
joachim99@8
|
1177 if ( mfi.m_bEqualBC )
|
joachim99@8
|
1178 mfi.setMergeOperation( eCopyCToDest );
|
joachim99@8
|
1179 else
|
joachim99@8
|
1180 mfi.setMergeOperation( eMergeABCToDest );
|
joachim99@8
|
1181 }
|
joachim99@8
|
1182 else if ( !mfi.m_bExistsInA && !mfi.m_bExistsInB && mfi.m_bExistsInC )
|
joachim99@8
|
1183 {
|
joachim99@8
|
1184 mfi.setMergeOperation( eCopyCToDest );
|
joachim99@8
|
1185 }
|
joachim99@8
|
1186 else if ( !mfi.m_bExistsInA && mfi.m_bExistsInB && !mfi.m_bExistsInC )
|
joachim99@8
|
1187 {
|
joachim99@8
|
1188 mfi.setMergeOperation( eCopyBToDest );
|
joachim99@8
|
1189 }
|
joachim99@8
|
1190 else if ( mfi.m_bExistsInA && !mfi.m_bExistsInB && !mfi.m_bExistsInC)
|
joachim99@8
|
1191 {
|
joachim99@8
|
1192 mfi.setMergeOperation( eDeleteFromDest );
|
joachim99@8
|
1193 }
|
joachim99@8
|
1194 else //if ( !mfi.m_bExistsInA && !mfi.m_bExistsInB && !mfi.m_bExistsInC )
|
joachim99@8
|
1195 {
|
joachim99@8
|
1196 mfi.setMergeOperation( eNoOperation ); assert(false);
|
joachim99@8
|
1197 }
|
joachim99@8
|
1198 }
|
joachim99@8
|
1199
|
joachim99@8
|
1200 // Now check if file/dir-types fit.
|
joachim99@8
|
1201 if ( conflictingFileTypes(mfi) )
|
joachim99@8
|
1202 {
|
joachim99@8
|
1203 mfi.setMergeOperation( eConflictingFileTypes );
|
joachim99@8
|
1204 }
|
joachim99@8
|
1205 }
|
joachim99@8
|
1206 else
|
joachim99@8
|
1207 {
|
joachim99@8
|
1208 e_MergeOperation eMO = eDefaultMergeOp;
|
joachim99@8
|
1209 switch ( eDefaultMergeOp )
|
joachim99@8
|
1210 {
|
joachim99@8
|
1211 case eConflictingFileTypes:
|
joachim99@8
|
1212 case eConflictingAges:
|
joachim99@8
|
1213 case eDeleteA:
|
joachim99@8
|
1214 case eDeleteB:
|
joachim99@8
|
1215 case eDeleteAB:
|
joachim99@8
|
1216 case eDeleteFromDest:
|
joachim99@8
|
1217 case eNoOperation: break;
|
joachim99@8
|
1218 case eCopyAToB: if ( !mfi.m_bExistsInA ) { eMO = eDeleteB; } break;
|
joachim99@8
|
1219 case eCopyBToA: if ( !mfi.m_bExistsInB ) { eMO = eDeleteA; } break;
|
joachim99@8
|
1220 case eCopyAToDest: if ( !mfi.m_bExistsInA ) { eMO = eDeleteFromDest; } break;
|
joachim99@8
|
1221 case eCopyBToDest: if ( !mfi.m_bExistsInB ) { eMO = eDeleteFromDest; } break;
|
joachim99@8
|
1222 case eCopyCToDest: if ( !mfi.m_bExistsInC ) { eMO = eDeleteFromDest; } break;
|
joachim99@8
|
1223
|
joachim99@8
|
1224 case eMergeToA:
|
joachim99@8
|
1225 case eMergeToB:
|
joachim99@8
|
1226 case eMergeToAB:
|
joachim99@8
|
1227 case eMergeABCToDest:
|
joachim99@8
|
1228 case eMergeABToDest:
|
joachim99@8
|
1229 default:
|
joachim99@8
|
1230 assert(false);
|
joachim99@8
|
1231 }
|
joachim99@8
|
1232 mfi.setMergeOperation( eMO );
|
joachim99@8
|
1233 }
|
joachim99@8
|
1234 }
|
joachim99@8
|
1235
|
joachim99@8
|
1236 void DirectoryMergeWindow::onDoubleClick( QListViewItem* lvi )
|
joachim99@8
|
1237 {
|
joachim99@8
|
1238 if (lvi==0) return;
|
joachim99@8
|
1239
|
joachim99@8
|
1240 if ( m_bDirectoryMerge )
|
joachim99@8
|
1241 mergeCurrentFile();
|
joachim99@8
|
1242 else
|
joachim99@8
|
1243 compareCurrentFile();
|
joachim99@8
|
1244 }
|
joachim99@8
|
1245
|
joachim99@8
|
1246 void DirectoryMergeWindow::onSelectionChanged( QListViewItem* lvi )
|
joachim99@8
|
1247 {
|
joachim99@8
|
1248 if ( lvi==0 ) return;
|
joachim99@8
|
1249
|
joachim99@8
|
1250 DirMergeItem* pDMI = static_cast<DirMergeItem*>(lvi);
|
joachim99@8
|
1251
|
joachim99@8
|
1252 MergeFileInfos& mfi = *pDMI->m_pMFI;
|
joachim99@8
|
1253 assert( mfi.m_pDMI==pDMI );
|
joachim99@8
|
1254
|
joachim99@8
|
1255 m_pDirectoryMergeInfo->setInfo( m_dirA, m_dirB, m_dirC, m_dirDestInternal, mfi );
|
joachim99@8
|
1256 }
|
joachim99@8
|
1257
|
joachim99@8
|
1258 void DirectoryMergeWindow::onClick( QListViewItem* lvi, const QPoint& p, int c )
|
joachim99@8
|
1259 {
|
joachim99@8
|
1260 if ( lvi==0 ) return;
|
joachim99@8
|
1261
|
joachim99@8
|
1262 DirMergeItem* pDMI = static_cast<DirMergeItem*>(lvi);
|
joachim99@8
|
1263
|
joachim99@8
|
1264 MergeFileInfos& mfi = *pDMI->m_pMFI;
|
joachim99@8
|
1265 assert( mfi.m_pDMI==pDMI );
|
joachim99@8
|
1266
|
joachim99@8
|
1267 if ( c!=s_OpCol ) return;
|
joachim99@8
|
1268
|
joachim99@8
|
1269 bool bThreeDirs = m_dirC.isValid();
|
joachim99@8
|
1270
|
joachim99@8
|
1271 KPopupMenu m(this);
|
joachim99@8
|
1272 if ( bThreeDirs )
|
joachim99@8
|
1273 {
|
joachim99@51
|
1274 dirCurrentDoNothing->plug(&m);
|
joachim99@8
|
1275 int count=0;
|
joachim99@51
|
1276 if ( mfi.m_bExistsInA ) { dirCurrentChooseA->plug(&m); ++count; }
|
joachim99@51
|
1277 if ( mfi.m_bExistsInB ) { dirCurrentChooseB->plug(&m); ++count; }
|
joachim99@51
|
1278 if ( mfi.m_bExistsInC ) { dirCurrentChooseC->plug(&m); ++count; }
|
joachim99@51
|
1279 if ( !conflictingFileTypes(mfi) && count>1 ) dirCurrentMerge->plug(&m);
|
joachim99@51
|
1280 dirCurrentDelete->plug(&m);
|
joachim99@8
|
1281 }
|
joachim99@8
|
1282 else if ( m_bSyncMode )
|
joachim99@8
|
1283 {
|
joachim99@51
|
1284 dirCurrentSyncDoNothing->plug(&m);
|
joachim99@51
|
1285 if ( mfi.m_bExistsInA ) dirCurrentSyncCopyAToB->plug(&m);
|
joachim99@51
|
1286 if ( mfi.m_bExistsInB ) dirCurrentSyncCopyBToA->plug(&m);
|
joachim99@51
|
1287 if ( mfi.m_bExistsInA ) dirCurrentSyncDeleteA->plug(&m);
|
joachim99@51
|
1288 if ( mfi.m_bExistsInB ) dirCurrentSyncDeleteB->plug(&m);
|
joachim99@8
|
1289 if ( mfi.m_bExistsInA && mfi.m_bExistsInB )
|
joachim99@8
|
1290 {
|
joachim99@51
|
1291 dirCurrentSyncDeleteAAndB->plug(&m);
|
joachim99@8
|
1292 if ( !conflictingFileTypes(mfi))
|
joachim99@8
|
1293 {
|
joachim99@51
|
1294 dirCurrentSyncMergeToA->plug(&m);
|
joachim99@51
|
1295 dirCurrentSyncMergeToB->plug(&m);
|
joachim99@51
|
1296 dirCurrentSyncMergeToAAndB->plug(&m);
|
joachim99@8
|
1297 }
|
joachim99@8
|
1298 }
|
joachim99@8
|
1299 }
|
joachim99@8
|
1300 else
|
joachim99@8
|
1301 {
|
joachim99@51
|
1302 dirCurrentDoNothing->plug(&m);
|
joachim99@51
|
1303 if ( mfi.m_bExistsInA ) { dirCurrentChooseA->plug(&m); }
|
joachim99@51
|
1304 if ( mfi.m_bExistsInB ) { dirCurrentChooseB->plug(&m); }
|
joachim99@51
|
1305 if ( !conflictingFileTypes(mfi) && mfi.m_bExistsInA && mfi.m_bExistsInB ) dirCurrentMerge->plug(&m);
|
joachim99@51
|
1306 dirCurrentDelete->plug(&m);
|
joachim99@8
|
1307 }
|
joachim99@8
|
1308
|
joachim99@51
|
1309 m.exec( p );
|
joachim99@8
|
1310 }
|
joachim99@8
|
1311
|
joachim99@8
|
1312 // Since Qt 2.3.0 doesn't allow the specification of a compare operator, this trick emulates it.
|
joachim99@8
|
1313 #if QT_VERSION==230
|
joachim99@8
|
1314 #define DIRSORT(x) ( pMFI->m_bDirA ? " " : "" )+x
|
joachim99@8
|
1315 #else
|
joachim99@8
|
1316 #define DIRSORT(x) x
|
joachim99@8
|
1317 #endif
|
joachim99@8
|
1318
|
joachim99@8
|
1319 DirMergeItem::DirMergeItem( QListView* pParent, const QString& fileName, MergeFileInfos* pMFI )
|
joachim99@51
|
1320 : QListViewItem( pParent, DIRSORT( fileName ), "","","", i18n("To do.") )
|
joachim99@8
|
1321 {
|
joachim99@8
|
1322 pMFI->m_pDMI = this;
|
joachim99@8
|
1323 m_pMFI = pMFI;
|
joachim99@8
|
1324 }
|
joachim99@8
|
1325
|
joachim99@8
|
1326 DirMergeItem::DirMergeItem( DirMergeItem* pParent, const QString& fileName, MergeFileInfos* pMFI )
|
joachim99@51
|
1327 : QListViewItem( pParent, DIRSORT( fileName ), "","","", i18n("To do.") )
|
joachim99@8
|
1328 {
|
joachim99@8
|
1329 pMFI->m_pDMI = this;
|
joachim99@8
|
1330 m_pMFI = pMFI;
|
joachim99@8
|
1331 }
|
joachim99@8
|
1332
|
joachim99@8
|
1333 DirMergeItem::~DirMergeItem()
|
joachim99@8
|
1334 {
|
joachim99@8
|
1335 m_pMFI->m_pDMI = 0;
|
joachim99@8
|
1336 }
|
joachim99@8
|
1337
|
joachim99@8
|
1338 void MergeFileInfos::setMergeOperation( e_MergeOperation eMOp )
|
joachim99@8
|
1339 {
|
joachim99@51
|
1340 if ( eMOp != m_eMergeOperation )
|
joachim99@51
|
1341 {
|
joachim99@51
|
1342 m_bOperationComplete = false;
|
joachim99@51
|
1343 m_pDMI->setText( s_OpStatusCol, "" );
|
joachim99@51
|
1344 }
|
joachim99@51
|
1345
|
joachim99@8
|
1346 m_eMergeOperation = eMOp;
|
joachim99@51
|
1347 QString s;
|
joachim99@8
|
1348 bool bDir = m_bDirA || m_bDirB || m_bDirC;
|
joachim99@8
|
1349 if( m_pDMI!=0 )
|
joachim99@8
|
1350 {
|
joachim99@8
|
1351 switch( m_eMergeOperation )
|
joachim99@8
|
1352 {
|
joachim99@8
|
1353 case eNoOperation: s=""; m_pDMI->setText(s_OpCol,""); break;
|
joachim99@51
|
1354 case eCopyAToB: s=i18n("Copy A to B"); break;
|
joachim99@51
|
1355 case eCopyBToA: s=i18n("Copy B to A"); break;
|
joachim99@51
|
1356 case eDeleteA: s=i18n("Delete A"); break;
|
joachim99@51
|
1357 case eDeleteB: s=i18n("Delete B"); break;
|
joachim99@51
|
1358 case eDeleteAB: s=i18n("Delete A & B"); break;
|
joachim99@51
|
1359 case eMergeToA: s=i18n("Merge to A"); break;
|
joachim99@51
|
1360 case eMergeToB: s=i18n("Merge to B"); break;
|
joachim99@51
|
1361 case eMergeToAB: s=i18n("Merge to A & B"); break;
|
joachim99@8
|
1362 case eCopyAToDest: s="A"; break;
|
joachim99@8
|
1363 case eCopyBToDest: s="B"; break;
|
joachim99@8
|
1364 case eCopyCToDest: s="C"; break;
|
joachim99@51
|
1365 case eDeleteFromDest: s=i18n("Delete (if exists)"); break;
|
joachim99@51
|
1366 case eMergeABCToDest: s= bDir ? i18n("Merge") : i18n("Merge (manual)"); break;
|
joachim99@51
|
1367 case eMergeABToDest: s= bDir ? i18n("Merge") : i18n("Merge (manual)"); break;
|
joachim99@51
|
1368 case eConflictingFileTypes: s=i18n("Error: Conflicting File Types"); break;
|
joachim99@51
|
1369 case eConflictingAges: s=i18n("Error: Dates are equal but files are not."); break;
|
joachim99@8
|
1370 default: assert(false); break;
|
joachim99@8
|
1371 }
|
joachim99@8
|
1372 m_pDMI->setText(s_OpCol,s);
|
joachim99@8
|
1373
|
joachim99@8
|
1374 e_MergeOperation eChildrenMergeOp = m_eMergeOperation;
|
joachim99@8
|
1375 if ( eChildrenMergeOp == eConflictingFileTypes ) eChildrenMergeOp = eMergeABCToDest;
|
joachim99@8
|
1376 QListViewItem* p = m_pDMI->firstChild();
|
joachim99@8
|
1377 while ( p!=0 )
|
joachim99@8
|
1378 {
|
joachim99@8
|
1379 DirMergeItem* pDMI = static_cast<DirMergeItem*>( p );
|
joachim99@8
|
1380 DirectoryMergeWindow* pDMW = static_cast<DirectoryMergeWindow*>( p->listView() );
|
joachim99@8
|
1381 pDMW->calcSuggestedOperation( *pDMI->m_pMFI, eChildrenMergeOp );
|
joachim99@8
|
1382 p = p->nextSibling();
|
joachim99@8
|
1383 }
|
joachim99@8
|
1384 }
|
joachim99@8
|
1385 }
|
joachim99@8
|
1386
|
joachim99@8
|
1387 void DirectoryMergeWindow::compareCurrentFile()
|
joachim99@8
|
1388 {
|
joachim99@8
|
1389 if (!canContinue()) return;
|
joachim99@8
|
1390
|
joachim99@8
|
1391 if ( m_bRealMergeStarted )
|
joachim99@8
|
1392 {
|
joachim99@51
|
1393 KMessageBox::sorry(this,i18n("This operation is currently not possible."),i18n("Operation Not Possible"));
|
joachim99@8
|
1394 return;
|
joachim99@8
|
1395 }
|
joachim99@8
|
1396
|
joachim99@8
|
1397 DirMergeItem* pDMI = static_cast<DirMergeItem*>( selectedItem() );
|
joachim99@8
|
1398 if ( pDMI != 0 )
|
joachim99@8
|
1399 {
|
joachim99@8
|
1400 MergeFileInfos& mfi = *pDMI->m_pMFI;
|
joachim99@8
|
1401 if ( !(mfi.m_bDirA || mfi.m_bDirB || mfi.m_bDirC) )
|
joachim99@8
|
1402 {
|
joachim99@8
|
1403 emit startDiffMerge(
|
joachim99@8
|
1404 mfi.m_bExistsInA ? mfi.m_fileInfoA.absFilePath() : QString(""),
|
joachim99@8
|
1405 mfi.m_bExistsInB ? mfi.m_fileInfoB.absFilePath() : QString(""),
|
joachim99@8
|
1406 mfi.m_bExistsInC ? mfi.m_fileInfoC.absFilePath() : QString(""),
|
joachim99@8
|
1407 "",
|
joachim99@8
|
1408 "","",""
|
joachim99@8
|
1409 );
|
joachim99@8
|
1410 }
|
joachim99@8
|
1411 }
|
joachim99@8
|
1412 emit updateAvailabilities();
|
joachim99@8
|
1413 }
|
joachim99@8
|
1414
|
joachim99@8
|
1415
|
joachim99@8
|
1416
|
joachim99@8
|
1417 bool DirectoryMergeWindow::isFileSelected()
|
joachim99@8
|
1418 {
|
joachim99@8
|
1419 DirMergeItem* pDMI = static_cast<DirMergeItem*>( selectedItem() );
|
joachim99@8
|
1420 if ( pDMI != 0 )
|
joachim99@8
|
1421 {
|
joachim99@8
|
1422 MergeFileInfos& mfi = *pDMI->m_pMFI;
|
joachim99@8
|
1423 return ! (mfi.m_bDirA || mfi.m_bDirB || mfi.m_bDirC || conflictingFileTypes(mfi) );
|
joachim99@8
|
1424 }
|
joachim99@8
|
1425 return false;
|
joachim99@8
|
1426 }
|
joachim99@8
|
1427
|
joachim99@8
|
1428 void DirectoryMergeWindow::mergeResultSaved(const QString& fileName)
|
joachim99@8
|
1429 {
|
joachim99@51
|
1430 DirMergeItem* pCurrentItemForOperation = (m_mergeItemList.empty() || m_currentItemForOperation==m_mergeItemList.end() )
|
joachim99@51
|
1431 ? 0
|
joachim99@51
|
1432 : *m_currentItemForOperation;
|
joachim99@51
|
1433
|
joachim99@51
|
1434 if ( pCurrentItemForOperation!=0 && pCurrentItemForOperation->m_pMFI==0 )
|
joachim99@8
|
1435 {
|
joachim99@51
|
1436 KMessageBox::error( this, i18n("This should never happen: \n\nmergeResultSaved: m_pMFI=0\n\nIf you know how to reproduce this, please contact the program author."),i18n("Program Error") );
|
joachim99@8
|
1437 return;
|
joachim99@8
|
1438 }
|
joachim99@51
|
1439 if ( pCurrentItemForOperation!=0 && fileName == fullNameDest(*pCurrentItemForOperation->m_pMFI) )
|
joachim99@8
|
1440 {
|
joachim99@51
|
1441 if ( pCurrentItemForOperation->m_pMFI->m_eMergeOperation==eMergeToAB )
|
joachim99@8
|
1442 {
|
joachim99@51
|
1443 MergeFileInfos& mfi = *pCurrentItemForOperation->m_pMFI;
|
joachim99@8
|
1444 bool bSuccess = copyFLD( fullNameB(mfi), fullNameA(mfi) );
|
joachim99@8
|
1445 if (!bSuccess)
|
joachim99@8
|
1446 {
|
joachim99@51
|
1447 KMessageBox::error(this, i18n("An error occurred while copying.\n"), i18n("Error") );
|
joachim99@51
|
1448 m_pStatusInfo->setCaption(i18n("Merge Error"));
|
joachim99@8
|
1449 m_pStatusInfo->show();
|
joachim99@8
|
1450 if ( m_pStatusInfo->firstChild()!=0 )
|
joachim99@8
|
1451 m_pStatusInfo->ensureItemVisible( m_pStatusInfo->last() );
|
joachim99@8
|
1452 m_bError = true;
|
joachim99@51
|
1453 pCurrentItemForOperation->setText( s_OpStatusCol, i18n("Error.") );
|
joachim99@8
|
1454 mfi.m_eMergeOperation = eCopyBToA;
|
joachim99@8
|
1455 return;
|
joachim99@8
|
1456 }
|
joachim99@8
|
1457 }
|
joachim99@51
|
1458 pCurrentItemForOperation->setText( s_OpStatusCol, i18n("Done.") );
|
joachim99@51
|
1459 pCurrentItemForOperation->m_pMFI->m_bOperationComplete = true;
|
joachim99@51
|
1460 if ( m_mergeItemList.size()==1 )
|
joachim99@51
|
1461 {
|
joachim99@51
|
1462 m_mergeItemList.clear();
|
joachim99@51
|
1463 m_bRealMergeStarted=false;
|
joachim99@51
|
1464 }
|
joachim99@8
|
1465 }
|
joachim99@8
|
1466
|
joachim99@8
|
1467 emit updateAvailabilities();
|
joachim99@8
|
1468 }
|
joachim99@8
|
1469
|
joachim99@8
|
1470 bool DirectoryMergeWindow::canContinue()
|
joachim99@8
|
1471 {
|
joachim99@8
|
1472 bool bCanContinue=false;
|
joachim99@8
|
1473 checkIfCanContinue( &bCanContinue );
|
joachim99@8
|
1474 if ( bCanContinue && !m_bError )
|
joachim99@8
|
1475 {
|
joachim99@51
|
1476 DirMergeItem* pCurrentItemForOperation =
|
joachim99@51
|
1477 (m_mergeItemList.empty() || m_currentItemForOperation==m_mergeItemList.end() ) ? 0 : *m_currentItemForOperation;
|
joachim99@51
|
1478
|
joachim99@51
|
1479 if ( pCurrentItemForOperation!=0 && ! pCurrentItemForOperation->m_pMFI->m_bOperationComplete )
|
joachim99@8
|
1480 {
|
joachim99@51
|
1481 pCurrentItemForOperation->setText( s_OpStatusCol, i18n("Not saved.") );
|
joachim99@51
|
1482 pCurrentItemForOperation->m_pMFI->m_bOperationComplete = true;
|
joachim99@51
|
1483 if ( m_mergeItemList.size()==1 )
|
joachim99@51
|
1484 {
|
joachim99@51
|
1485 m_mergeItemList.clear();
|
joachim99@51
|
1486 m_bRealMergeStarted=false;
|
joachim99@51
|
1487 }
|
joachim99@8
|
1488 }
|
joachim99@8
|
1489 }
|
joachim99@8
|
1490 return bCanContinue;
|
joachim99@8
|
1491 }
|
joachim99@8
|
1492
|
joachim99@51
|
1493 bool DirectoryMergeWindow::executeMergeOperation( MergeFileInfos& mfi, bool& bSingleFileMerge )
|
joachim99@8
|
1494 {
|
joachim99@51
|
1495 bool bCreateBackups = m_pOptions->m_bDmCreateBakFiles;
|
joachim99@51
|
1496 // First decide destname
|
joachim99@51
|
1497 QString destName;
|
joachim99@51
|
1498 switch( mfi.m_eMergeOperation )
|
joachim99@51
|
1499 {
|
joachim99@51
|
1500 case eNoOperation: break;
|
joachim99@51
|
1501 case eDeleteAB: break;
|
joachim99@51
|
1502 case eMergeToAB: // let the user save in B. In mergeResultSaved() the file will be copied to A.
|
joachim99@51
|
1503 case eMergeToB:
|
joachim99@51
|
1504 case eDeleteB:
|
joachim99@51
|
1505 case eCopyAToB: destName = fullNameB(mfi); break;
|
joachim99@51
|
1506 case eMergeToA:
|
joachim99@51
|
1507 case eDeleteA:
|
joachim99@51
|
1508 case eCopyBToA: destName = fullNameA(mfi); break;
|
joachim99@51
|
1509 case eMergeABToDest:
|
joachim99@51
|
1510 case eMergeABCToDest:
|
joachim99@51
|
1511 case eCopyAToDest:
|
joachim99@51
|
1512 case eCopyBToDest:
|
joachim99@51
|
1513 case eCopyCToDest:
|
joachim99@51
|
1514 case eDeleteFromDest: destName = fullNameDest(mfi); break;
|
joachim99@51
|
1515 default:
|
joachim99@51
|
1516 KMessageBox::error( this, i18n("Unknown merge operation. (This must never happen!)"), i18n("Error") );
|
joachim99@51
|
1517 assert(false);
|
joachim99@51
|
1518 }
|
joachim99@8
|
1519
|
joachim99@51
|
1520 bool bSuccess = false;
|
joachim99@51
|
1521 bSingleFileMerge = false;
|
joachim99@51
|
1522 switch( mfi.m_eMergeOperation )
|
joachim99@51
|
1523 {
|
joachim99@51
|
1524 case eNoOperation: bSuccess = true; break;
|
joachim99@51
|
1525 case eCopyAToDest:
|
joachim99@51
|
1526 case eCopyAToB: bSuccess = copyFLD( fullNameA(mfi), destName ); break;
|
joachim99@51
|
1527 case eCopyBToDest:
|
joachim99@51
|
1528 case eCopyBToA: bSuccess = copyFLD( fullNameB(mfi), destName ); break;
|
joachim99@51
|
1529 case eCopyCToDest: bSuccess = copyFLD( fullNameC(mfi), destName ); break;
|
joachim99@51
|
1530 case eDeleteFromDest:
|
joachim99@51
|
1531 case eDeleteA:
|
joachim99@51
|
1532 case eDeleteB: bSuccess = deleteFLD( destName, bCreateBackups ); break;
|
joachim99@51
|
1533 case eDeleteAB: bSuccess = deleteFLD( fullNameA(mfi), bCreateBackups ) &&
|
joachim99@51
|
1534 deleteFLD( fullNameB(mfi), bCreateBackups ); break;
|
joachim99@51
|
1535 case eMergeABToDest:
|
joachim99@51
|
1536 case eMergeToA:
|
joachim99@51
|
1537 case eMergeToAB:
|
joachim99@51
|
1538 case eMergeToB: bSuccess = mergeFLD( fullNameA(mfi), fullNameB(mfi), "",
|
joachim99@51
|
1539 destName, bSingleFileMerge );
|
joachim99@51
|
1540 break;
|
joachim99@51
|
1541 case eMergeABCToDest:bSuccess = mergeFLD(
|
joachim99@51
|
1542 mfi.m_bExistsInA ? fullNameA(mfi) : QString(""),
|
joachim99@51
|
1543 mfi.m_bExistsInB ? fullNameB(mfi) : QString(""),
|
joachim99@51
|
1544 mfi.m_bExistsInC ? fullNameC(mfi) : QString(""),
|
joachim99@51
|
1545 destName, bSingleFileMerge );
|
joachim99@51
|
1546 break;
|
joachim99@51
|
1547 default:
|
joachim99@51
|
1548 KMessageBox::error( this, i18n("Unknown merge operation."), i18n("Error") );
|
joachim99@51
|
1549 assert(false);
|
joachim99@51
|
1550 }
|
joachim99@8
|
1551
|
joachim99@51
|
1552 return bSuccess;
|
joachim99@51
|
1553 }
|
joachim99@8
|
1554
|
joachim99@51
|
1555
|
joachim99@51
|
1556 // Check if the merge can start, and prepare the m_mergeItemList which then contains all
|
joachim99@51
|
1557 // items that must be merged.
|
joachim99@51
|
1558 void DirectoryMergeWindow::prepareMergeStart( QListViewItem* pBegin, QListViewItem* pEnd, bool bVerbose )
|
joachim99@51
|
1559 {
|
joachim99@51
|
1560 if ( bVerbose )
|
joachim99@8
|
1561 {
|
joachim99@51
|
1562 int status = KMessageBox::warningYesNoCancel(this,
|
joachim99@51
|
1563 i18n("The merge is about to begin.\n\n"
|
joachim99@51
|
1564 "Choose \"Do it\" if you have read the instructions and know what you are doing.\n"
|
joachim99@51
|
1565 "Choosing \"Simulate it\" will tell you what would happen.\n\n"
|
joachim99@51
|
1566 "Be aware that this program still has beta status "
|
joachim99@51
|
1567 "and there is NO WARRANTY whatsoever! Make backups of your vital data!"),
|
joachim99@51
|
1568 i18n("Starting Merge"), i18n("Do It"), i18n("Simulate It") );
|
joachim99@51
|
1569 if (status==KMessageBox::Yes) m_bRealMergeStarted = true;
|
joachim99@51
|
1570 else if (status==KMessageBox::No ) m_bSimulatedMergeStarted = true;
|
joachim99@51
|
1571 else return;
|
joachim99@51
|
1572 }
|
joachim99@51
|
1573 else
|
joachim99@51
|
1574 {
|
joachim99@51
|
1575 m_bRealMergeStarted = true;
|
joachim99@51
|
1576 }
|
joachim99@51
|
1577
|
joachim99@51
|
1578 m_mergeItemList.clear();
|
joachim99@51
|
1579 if (pBegin == 0)
|
joachim99@51
|
1580 return;
|
joachim99@51
|
1581
|
joachim99@51
|
1582 for( QListViewItem* p = pBegin; p!= pEnd; p = treeIterator( p ) )
|
joachim99@51
|
1583 {
|
joachim99@51
|
1584 DirMergeItem* pDMI = static_cast<DirMergeItem*>(p);
|
joachim99@51
|
1585
|
joachim99@51
|
1586 if ( ! pDMI->m_pMFI->m_bOperationComplete )
|
joachim99@8
|
1587 {
|
joachim99@51
|
1588 m_mergeItemList.push_back(pDMI);
|
joachim99@51
|
1589
|
joachim99@8
|
1590 if (pDMI!=0 && pDMI->m_pMFI->m_eMergeOperation == eConflictingFileTypes )
|
joachim99@8
|
1591 {
|
joachim99@8
|
1592 ensureItemVisible( pDMI );
|
joachim99@8
|
1593 setSelected( pDMI, true );
|
joachim99@51
|
1594 KMessageBox::error(this, i18n("The highlighted item has a different type in the different directories. Select what to do."), i18n("Error"));
|
joachim99@51
|
1595 m_mergeItemList.clear();
|
joachim99@51
|
1596 m_bRealMergeStarted=false;
|
joachim99@8
|
1597 return;
|
joachim99@8
|
1598 }
|
joachim99@8
|
1599 if (pDMI!=0 && pDMI->m_pMFI->m_eMergeOperation == eConflictingAges )
|
joachim99@8
|
1600 {
|
joachim99@8
|
1601 ensureItemVisible( pDMI );
|
joachim99@8
|
1602 setSelected( pDMI, true );
|
joachim99@51
|
1603 KMessageBox::error(this, i18n("The modification dates of the file are equal but the files are not. Select what to do."), i18n("Error"));
|
joachim99@51
|
1604 m_mergeItemList.clear();
|
joachim99@51
|
1605 m_bRealMergeStarted=false;
|
joachim99@8
|
1606 return;
|
joachim99@8
|
1607 }
|
joachim99@8
|
1608 }
|
joachim99@8
|
1609 }
|
joachim99@8
|
1610
|
joachim99@51
|
1611 m_currentItemForOperation = m_mergeItemList.begin();
|
joachim99@51
|
1612 return;
|
joachim99@51
|
1613 }
|
joachim99@51
|
1614
|
joachim99@51
|
1615 void DirectoryMergeWindow::slotRunOperationForCurrentItem()
|
joachim99@51
|
1616 {
|
joachim99@51
|
1617 if ( ! canContinue() ) return;
|
joachim99@51
|
1618
|
joachim99@51
|
1619 bool bVerbose = false;
|
joachim99@51
|
1620 if ( m_mergeItemList.empty() )
|
joachim99@51
|
1621 {
|
joachim99@51
|
1622 QListViewItem* pBegin = currentItem();
|
joachim99@53
|
1623 QListViewItem* pEnd = pBegin;
|
joachim99@53
|
1624 while ( pEnd!=0 && pEnd->nextSibling()==0 )
|
joachim99@53
|
1625 {
|
joachim99@53
|
1626 pEnd = pEnd->parent();
|
joachim99@53
|
1627 }
|
joachim99@53
|
1628 if ( pEnd!=0 )
|
joachim99@53
|
1629 pEnd=pEnd->nextSibling();
|
joachim99@51
|
1630
|
joachim99@53
|
1631 prepareMergeStart( pBegin, pEnd, bVerbose );
|
joachim99@51
|
1632 mergeContinue(true, bVerbose);
|
joachim99@51
|
1633 }
|
joachim99@51
|
1634 else
|
joachim99@51
|
1635 mergeContinue(false, bVerbose);
|
joachim99@51
|
1636 }
|
joachim99@51
|
1637
|
joachim99@51
|
1638 void DirectoryMergeWindow::slotRunOperationForAllItems()
|
joachim99@51
|
1639 {
|
joachim99@51
|
1640 if ( ! canContinue() ) return;
|
joachim99@51
|
1641
|
joachim99@51
|
1642 bool bVerbose = true;
|
joachim99@51
|
1643 if ( m_mergeItemList.empty() )
|
joachim99@51
|
1644 {
|
joachim99@51
|
1645 QListViewItem* pBegin = firstChild();
|
joachim99@51
|
1646
|
joachim99@51
|
1647 prepareMergeStart( pBegin, 0, bVerbose );
|
joachim99@51
|
1648 mergeContinue(true, bVerbose);
|
joachim99@51
|
1649 }
|
joachim99@51
|
1650 else
|
joachim99@51
|
1651 mergeContinue(false, bVerbose);
|
joachim99@51
|
1652 }
|
joachim99@51
|
1653
|
joachim99@51
|
1654 void DirectoryMergeWindow::mergeCurrentFile()
|
joachim99@51
|
1655 {
|
joachim99@51
|
1656 if (!canContinue()) return;
|
joachim99@51
|
1657
|
joachim99@51
|
1658 if ( m_bRealMergeStarted )
|
joachim99@51
|
1659 {
|
joachim99@51
|
1660 KMessageBox::sorry(this,i18n("This operation is currently not possible because dir merge currently runs."),i18n("Operation Not Possible"));
|
joachim99@51
|
1661 return;
|
joachim99@51
|
1662 }
|
joachim99@51
|
1663
|
joachim99@51
|
1664 if ( isFileSelected() )
|
joachim99@51
|
1665 {
|
joachim99@51
|
1666 DirMergeItem* pDMI = static_cast<DirMergeItem*>( selectedItem() );
|
joachim99@51
|
1667 if ( pDMI != 0 )
|
joachim99@51
|
1668 {
|
joachim99@51
|
1669 MergeFileInfos& mfi = *pDMI->m_pMFI;
|
joachim99@51
|
1670 m_mergeItemList.clear();
|
joachim99@51
|
1671 m_mergeItemList.push_back( pDMI );
|
joachim99@51
|
1672 m_currentItemForOperation=m_mergeItemList.begin();
|
joachim99@51
|
1673 bool bDummy=false;
|
joachim99@51
|
1674 mergeFLD(
|
joachim99@51
|
1675 mfi.m_bExistsInA ? mfi.m_fileInfoA.absFilePath() : QString(""),
|
joachim99@51
|
1676 mfi.m_bExistsInB ? mfi.m_fileInfoB.absFilePath() : QString(""),
|
joachim99@51
|
1677 mfi.m_bExistsInC ? mfi.m_fileInfoC.absFilePath() : QString(""),
|
joachim99@51
|
1678 fullNameDest(mfi),
|
joachim99@51
|
1679 bDummy
|
joachim99@51
|
1680 );
|
joachim99@51
|
1681 }
|
joachim99@51
|
1682 }
|
joachim99@51
|
1683 emit updateAvailabilities();
|
joachim99@51
|
1684 }
|
joachim99@51
|
1685
|
joachim99@51
|
1686
|
joachim99@51
|
1687 // When bStart is true then m_currentItemForOperation must still be processed.
|
joachim99@51
|
1688 // When bVerbose is true then a messagebox will tell when the merge is complete.
|
joachim99@51
|
1689 void DirectoryMergeWindow::mergeContinue(bool bStart, bool bVerbose)
|
joachim99@51
|
1690 {
|
joachim99@51
|
1691 if ( m_mergeItemList.empty() )
|
joachim99@51
|
1692 return;
|
joachim99@51
|
1693
|
joachim99@51
|
1694 int nrOfItems = 0;
|
joachim99@51
|
1695 int nrOfCompletedItems = 0;
|
joachim99@51
|
1696 int nrOfCompletedSimItems = 0;
|
joachim99@51
|
1697
|
joachim99@51
|
1698 // Count the number of completed items (for the progress bar).
|
joachim99@51
|
1699 for( MergeItemList::iterator i = m_mergeItemList.begin(); i!=m_mergeItemList.end(); ++i )
|
joachim99@51
|
1700 {
|
joachim99@53
|
1701 DirMergeItem* pDMI = *i;
|
joachim99@51
|
1702 ++nrOfItems;
|
joachim99@51
|
1703 if ( pDMI->m_pMFI->m_bOperationComplete )
|
joachim99@51
|
1704 ++nrOfCompletedItems;
|
joachim99@51
|
1705 if ( pDMI->m_pMFI->m_bSimOpComplete )
|
joachim99@51
|
1706 ++nrOfCompletedSimItems;
|
joachim99@51
|
1707 }
|
joachim99@51
|
1708
|
joachim99@51
|
1709 m_pStatusInfo->hide();
|
joachim99@51
|
1710 m_pStatusInfo->clear();
|
joachim99@51
|
1711
|
joachim99@51
|
1712 DirMergeItem* pCurrentItemForOperation = m_currentItemForOperation==m_mergeItemList.end() ? 0 : *m_currentItemForOperation;
|
joachim99@51
|
1713
|
joachim99@51
|
1714 bool bContinueWithCurrentItem = bStart; // true for first item, else false
|
joachim99@8
|
1715 bool bSkipItem = false;
|
joachim99@51
|
1716 if ( !bStart && m_bError && pCurrentItemForOperation!=0 )
|
joachim99@8
|
1717 {
|
joachim99@8
|
1718 int status = KMessageBox::warningYesNoCancel(this,
|
joachim99@8
|
1719 i18n("There was an error in the last step.\n"
|
joachim99@8
|
1720 "Do you want to continue with the item that caused the error or do you want to skip this item?"),
|
joachim99@51
|
1721 i18n("Continue merge after an error"), i18n("Continue With Last Item"), i18n("Skip Item") );
|
joachim99@51
|
1722 if (status==KMessageBox::Yes) bContinueWithCurrentItem = true;
|
joachim99@8
|
1723 else if (status==KMessageBox::No ) bSkipItem = true;
|
joachim99@8
|
1724 else return;
|
joachim99@8
|
1725 m_bError = false;
|
joachim99@8
|
1726 }
|
joachim99@8
|
1727
|
joachim99@8
|
1728 g_pProgressDialog->start();
|
joachim99@8
|
1729
|
joachim99@8
|
1730 bool bSuccess = true;
|
joachim99@8
|
1731 bool bSingleFileMerge = false;
|
joachim99@8
|
1732 bool bSim = m_bSimulatedMergeStarted;
|
joachim99@8
|
1733 while( bSuccess )
|
joachim99@8
|
1734 {
|
joachim99@51
|
1735 if ( pCurrentItemForOperation==0 )
|
joachim99@51
|
1736 {
|
joachim99@51
|
1737 m_mergeItemList.clear();
|
joachim99@51
|
1738 m_bRealMergeStarted=false;
|
joachim99@51
|
1739 break;
|
joachim99@51
|
1740 }
|
joachim99@51
|
1741
|
joachim99@51
|
1742 if ( pCurrentItemForOperation!=0 && !bContinueWithCurrentItem )
|
joachim99@8
|
1743 {
|
joachim99@8
|
1744 if ( bSim )
|
joachim99@8
|
1745 {
|
joachim99@51
|
1746 if( pCurrentItemForOperation->firstChild()==0 )
|
joachim99@8
|
1747 {
|
joachim99@51
|
1748 pCurrentItemForOperation->m_pMFI->m_bSimOpComplete = true;
|
joachim99@8
|
1749 }
|
joachim99@8
|
1750 }
|
joachim99@8
|
1751 else
|
joachim99@8
|
1752 {
|
joachim99@51
|
1753 if( pCurrentItemForOperation->firstChild()==0 )
|
joachim99@8
|
1754 {
|
joachim99@51
|
1755 if( !pCurrentItemForOperation->m_pMFI->m_bOperationComplete )
|
joachim99@8
|
1756 {
|
joachim99@51
|
1757 pCurrentItemForOperation->setText( s_OpStatusCol, bSkipItem ? i18n("Skipped.") : i18n("Done.") );
|
joachim99@51
|
1758 pCurrentItemForOperation->m_pMFI->m_bOperationComplete = true;
|
joachim99@8
|
1759 bSkipItem = false;
|
joachim99@8
|
1760 }
|
joachim99@8
|
1761 }
|
joachim99@8
|
1762 else
|
joachim99@8
|
1763 {
|
joachim99@51
|
1764 pCurrentItemForOperation->setText( s_OpStatusCol, i18n("In progress...") );
|
joachim99@8
|
1765 }
|
joachim99@8
|
1766 }
|
joachim99@8
|
1767 }
|
joachim99@8
|
1768
|
joachim99@51
|
1769 if ( ! bContinueWithCurrentItem )
|
joachim99@8
|
1770 {
|
joachim99@51
|
1771 // Depth first
|
joachim99@51
|
1772 QListViewItem* pPrevItem = pCurrentItemForOperation;
|
joachim99@51
|
1773 ++m_currentItemForOperation;
|
joachim99@51
|
1774 pCurrentItemForOperation = m_currentItemForOperation==m_mergeItemList.end() ? 0 : *m_currentItemForOperation;
|
joachim99@51
|
1775 if ( (pCurrentItemForOperation==0 || pCurrentItemForOperation->parent()!=pPrevItem->parent()) && pPrevItem->parent()!=0 )
|
joachim99@8
|
1776 {
|
joachim99@51
|
1777 // Check if the parent may be set to "Done"
|
joachim99@51
|
1778 QListViewItem* pParent = pPrevItem->parent();
|
joachim99@51
|
1779 bool bDone = true;
|
joachim99@51
|
1780 while ( bDone && pParent!=0 )
|
joachim99@8
|
1781 {
|
joachim99@51
|
1782 for( QListViewItem* p = pParent->firstChild(); p!=0; p=p->nextSibling() )
|
joachim99@8
|
1783 {
|
joachim99@51
|
1784 DirMergeItem* pDMI = static_cast<DirMergeItem*>(p);
|
joachim99@51
|
1785 if ( !bSim && ! pDMI->m_pMFI->m_bOperationComplete || bSim && pDMI->m_pMFI->m_bSimOpComplete )
|
joachim99@8
|
1786 {
|
joachim99@51
|
1787 bDone=false;
|
joachim99@51
|
1788 break;
|
joachim99@8
|
1789 }
|
joachim99@8
|
1790 }
|
joachim99@51
|
1791 if ( bDone )
|
joachim99@51
|
1792 {
|
joachim99@51
|
1793 if (bSim)
|
joachim99@51
|
1794 static_cast<DirMergeItem*>(pParent)->m_pMFI->m_bSimOpComplete = bDone;
|
joachim99@51
|
1795 else
|
joachim99@51
|
1796 {
|
joachim99@51
|
1797 pParent->setText( s_OpStatusCol, i18n("Done.") );
|
joachim99@51
|
1798 static_cast<DirMergeItem*>(pParent)->m_pMFI->m_bOperationComplete = bDone;
|
joachim99@51
|
1799 }
|
joachim99@51
|
1800 }
|
joachim99@51
|
1801 pParent = pParent->parent();
|
joachim99@8
|
1802 }
|
joachim99@8
|
1803 }
|
joachim99@8
|
1804 }
|
joachim99@8
|
1805
|
joachim99@51
|
1806 if ( pCurrentItemForOperation == 0 ) // end?
|
joachim99@8
|
1807 {
|
joachim99@8
|
1808 if ( m_bRealMergeStarted )
|
joachim99@8
|
1809 {
|
joachim99@51
|
1810 if (bVerbose)
|
joachim99@51
|
1811 {
|
joachim99@51
|
1812 KMessageBox::information( this, i18n("Merge operation complete."), i18n("Merge Complete") );
|
joachim99@51
|
1813 }
|
joachim99@8
|
1814 m_bRealMergeStarted = false;
|
joachim99@51
|
1815 m_pStatusInfo->setCaption(i18n("Merge Complete"));
|
joachim99@8
|
1816 }
|
joachim99@8
|
1817 if ( m_bSimulatedMergeStarted )
|
joachim99@8
|
1818 {
|
joachim99@8
|
1819 m_bSimulatedMergeStarted = false;
|
joachim99@8
|
1820 for( QListViewItem* p=firstChild(); p!=0; p=treeIterator(p) )
|
joachim99@8
|
1821 {
|
joachim99@8
|
1822 static_cast<DirMergeItem*>(p)->m_pMFI->m_bSimOpComplete = false;
|
joachim99@8
|
1823 }
|
joachim99@51
|
1824 m_pStatusInfo->setCaption(i18n("Simulated merge complete: Check if you agree with the proposed operations."));
|
joachim99@8
|
1825 m_pStatusInfo->show();
|
joachim99@8
|
1826 }
|
joachim99@8
|
1827 g_pProgressDialog->hide();
|
joachim99@51
|
1828 m_mergeItemList.clear();
|
joachim99@51
|
1829 m_bRealMergeStarted=false;
|
joachim99@8
|
1830 return;
|
joachim99@8
|
1831 }
|
joachim99@8
|
1832
|
joachim99@51
|
1833 MergeFileInfos& mfi = *pCurrentItemForOperation->m_pMFI;
|
joachim99@8
|
1834
|
joachim99@8
|
1835 g_pProgressDialog->setInformation( mfi.m_subPath,
|
joachim99@8
|
1836 bSim ? double(nrOfCompletedSimItems)/nrOfItems : double(nrOfCompletedItems)/nrOfItems,
|
joachim99@51
|
1837 false // bRedrawUpdate
|
joachim99@8
|
1838 );
|
joachim99@8
|
1839 g_pProgressDialog->show();
|
joachim99@8
|
1840
|
joachim99@51
|
1841 bSuccess = executeMergeOperation( mfi, bSingleFileMerge ); // Here the real operation happens.
|
joachim99@8
|
1842
|
joachim99@8
|
1843 if ( bSuccess )
|
joachim99@8
|
1844 {
|
joachim99@8
|
1845 if(bSim) ++nrOfCompletedSimItems;
|
joachim99@8
|
1846 else ++nrOfCompletedItems;
|
joachim99@8
|
1847 bContinueWithCurrentItem = false;
|
joachim99@8
|
1848 }
|
joachim99@51
|
1849
|
joachim99@51
|
1850 if( g_pProgressDialog->wasCancelled() )
|
joachim99@51
|
1851 break;
|
joachim99@8
|
1852 } // end while
|
joachim99@8
|
1853
|
joachim99@8
|
1854 g_pProgressDialog->hide();
|
joachim99@8
|
1855
|
joachim99@51
|
1856 setCurrentItem( pCurrentItemForOperation );
|
joachim99@51
|
1857 ensureItemVisible( pCurrentItemForOperation );
|
joachim99@8
|
1858 if ( !bSuccess && !bSingleFileMerge )
|
joachim99@8
|
1859 {
|
joachim99@51
|
1860 KMessageBox::error(this, i18n("An error occurred. Press OK to see detailed information.\n"), i18n("Error") );
|
joachim99@51
|
1861 m_pStatusInfo->setCaption(i18n("Merge Error"));
|
joachim99@8
|
1862 m_pStatusInfo->show();
|
joachim99@8
|
1863 if ( m_pStatusInfo->firstChild()!=0 )
|
joachim99@8
|
1864 m_pStatusInfo->ensureItemVisible( m_pStatusInfo->last() );
|
joachim99@8
|
1865 m_bError = true;
|
joachim99@51
|
1866 pCurrentItemForOperation->setText( s_OpStatusCol, i18n("Error.") );
|
joachim99@8
|
1867 }
|
joachim99@8
|
1868 else
|
joachim99@8
|
1869 {
|
joachim99@8
|
1870 m_bError = false;
|
joachim99@8
|
1871 }
|
joachim99@8
|
1872 emit updateAvailabilities();
|
joachim99@51
|
1873
|
joachim99@51
|
1874 if ( m_currentItemForOperation==m_mergeItemList.end() )
|
joachim99@51
|
1875 {
|
joachim99@51
|
1876 m_mergeItemList.clear();
|
joachim99@51
|
1877 m_bRealMergeStarted=false;
|
joachim99@51
|
1878 }
|
joachim99@8
|
1879 }
|
joachim99@8
|
1880
|
joachim99@8
|
1881 void DirectoryMergeWindow::allowResizeEvents(bool bAllowResizeEvents )
|
joachim99@8
|
1882 {
|
joachim99@8
|
1883 m_bAllowResizeEvents = bAllowResizeEvents;
|
joachim99@8
|
1884 }
|
joachim99@8
|
1885
|
joachim99@8
|
1886 void DirectoryMergeWindow::resizeEvent( QResizeEvent* e )
|
joachim99@8
|
1887 {
|
joachim99@8
|
1888 if (m_bAllowResizeEvents)
|
joachim99@8
|
1889 QListView::resizeEvent(e);
|
joachim99@8
|
1890 }
|
joachim99@8
|
1891
|
joachim99@8
|
1892 bool DirectoryMergeWindow::deleteFLD( const QString& name, bool bCreateBackup )
|
joachim99@8
|
1893 {
|
joachim99@8
|
1894 FileAccess fi(name, true);
|
joachim99@8
|
1895 if ( !fi.exists() )
|
joachim99@8
|
1896 return true;
|
joachim99@8
|
1897
|
joachim99@8
|
1898 if ( bCreateBackup )
|
joachim99@8
|
1899 {
|
joachim99@8
|
1900 bool bSuccess = renameFLD( name, name+".orig" );
|
joachim99@8
|
1901 if (!bSuccess)
|
joachim99@8
|
1902 {
|
joachim99@51
|
1903 m_pStatusInfo->addText( i18n("Error: While deleting %1: Creating backup failed.").arg(name) );
|
joachim99@8
|
1904 return false;
|
joachim99@8
|
1905 }
|
joachim99@8
|
1906 }
|
joachim99@8
|
1907 else
|
joachim99@8
|
1908 {
|
joachim99@8
|
1909 if ( fi.isDir() && !fi.isSymLink() )
|
joachim99@51
|
1910 m_pStatusInfo->addText(i18n("delete directory recursively( %1 )").arg(name));
|
joachim99@8
|
1911 else
|
joachim99@51
|
1912 m_pStatusInfo->addText(i18n("delete( %1 )").arg(name));
|
joachim99@8
|
1913
|
joachim99@8
|
1914 if ( m_bSimulatedMergeStarted )
|
joachim99@8
|
1915 {
|
joachim99@8
|
1916 return true;
|
joachim99@8
|
1917 }
|
joachim99@8
|
1918
|
joachim99@8
|
1919 if ( fi.isDir() && !fi.isSymLink() )// recursive directory delete only for real dirs, not symlinks
|
joachim99@8
|
1920 {
|
joachim99@8
|
1921 t_DirectoryList dirList;
|
joachim99@8
|
1922 bool bSuccess = fi.listDir( &dirList, false, true, "*", "", "", false, false ); // not recursive, find hidden files
|
joachim99@8
|
1923
|
joachim99@8
|
1924 if ( !bSuccess )
|
joachim99@8
|
1925 {
|
joachim99@8
|
1926 // No Permission to read directory or other error.
|
joachim99@51
|
1927 m_pStatusInfo->addText( i18n("Error: delete dir operation failed while trying to read the directory.") );
|
joachim99@8
|
1928 return false;
|
joachim99@8
|
1929 }
|
joachim99@8
|
1930
|
joachim99@8
|
1931 t_DirectoryList::iterator it; // create list iterator
|
joachim99@8
|
1932
|
joachim99@8
|
1933 for ( it=dirList.begin(); it!=dirList.end(); ++it ) // for each file...
|
joachim99@8
|
1934 {
|
joachim99@8
|
1935 FileAccess& fi2 = *it;
|
joachim99@8
|
1936 if ( fi2.fileName() == "." || fi2.fileName()==".." )
|
joachim99@8
|
1937 continue;
|
joachim99@8
|
1938 bSuccess = deleteFLD( fi2.absFilePath(), false );
|
joachim99@8
|
1939 if (!bSuccess) break;
|
joachim99@8
|
1940 }
|
joachim99@8
|
1941 if (bSuccess)
|
joachim99@8
|
1942 {
|
joachim99@8
|
1943 bSuccess = FileAccess::removeDir( name );
|
joachim99@8
|
1944 if ( !bSuccess )
|
joachim99@8
|
1945 {
|
joachim99@51
|
1946 m_pStatusInfo->addText( i18n("Error: rmdir( %1 ) operation failed.").arg(name));
|
joachim99@8
|
1947 return false;
|
joachim99@8
|
1948 }
|
joachim99@8
|
1949 }
|
joachim99@8
|
1950 }
|
joachim99@8
|
1951 else
|
joachim99@8
|
1952 {
|
joachim99@8
|
1953 bool bSuccess = FileAccess::removeFile( name );
|
joachim99@8
|
1954 if ( !bSuccess )
|
joachim99@8
|
1955 {
|
joachim99@51
|
1956 m_pStatusInfo->addText( i18n("Error: delete operation failed.") );
|
joachim99@8
|
1957 return false;
|
joachim99@8
|
1958 }
|
joachim99@8
|
1959 }
|
joachim99@8
|
1960 }
|
joachim99@8
|
1961 return true;
|
joachim99@8
|
1962 }
|
joachim99@8
|
1963
|
joachim99@8
|
1964 bool DirectoryMergeWindow::mergeFLD( const QString& nameA,const QString& nameB,const QString& nameC,const QString& nameDest, bool& bSingleFileMerge )
|
joachim99@8
|
1965 {
|
joachim99@8
|
1966 FileAccess fi(nameA);
|
joachim99@8
|
1967 if (fi.isDir())
|
joachim99@8
|
1968 {
|
joachim99@8
|
1969 return makeDir(nameDest);
|
joachim99@8
|
1970 }
|
joachim99@8
|
1971
|
joachim99@8
|
1972 // Make sure that the dir exists, into which we will save the file later.
|
joachim99@8
|
1973 int pos=nameDest.findRev('/');
|
joachim99@8
|
1974 if ( pos>0 )
|
joachim99@8
|
1975 {
|
joachim99@8
|
1976 QString parentName = nameDest.left(pos);
|
joachim99@8
|
1977 bool bSuccess = makeDir(parentName, true /*quiet*/);
|
joachim99@8
|
1978 if (!bSuccess)
|
joachim99@8
|
1979 return false;
|
joachim99@8
|
1980 }
|
joachim99@8
|
1981
|
joachim99@51
|
1982 m_pStatusInfo->addText(i18n("manual merge( %1, %2, %3 -> %4)").arg(nameA).arg(nameB).arg(nameC).arg(nameDest));
|
joachim99@8
|
1983 if ( m_bSimulatedMergeStarted )
|
joachim99@8
|
1984 {
|
joachim99@51
|
1985 m_pStatusInfo->addText(i18n(" Note: After a manual merge the user should continue via F7.") );
|
joachim99@8
|
1986 return true;
|
joachim99@8
|
1987 }
|
joachim99@8
|
1988
|
joachim99@8
|
1989 bSingleFileMerge = true;
|
joachim99@51
|
1990 (*m_currentItemForOperation)->setText( s_OpStatusCol, i18n("In progress...") );
|
joachim99@51
|
1991 ensureItemVisible( *m_currentItemForOperation );
|
joachim99@8
|
1992
|
joachim99@8
|
1993 emit startDiffMerge( nameA, nameB, nameC, nameDest, "","","" );
|
joachim99@8
|
1994
|
joachim99@8
|
1995 return false;
|
joachim99@8
|
1996 }
|
joachim99@8
|
1997
|
joachim99@8
|
1998 bool DirectoryMergeWindow::copyFLD( const QString& srcName, const QString& destName )
|
joachim99@8
|
1999 {
|
joachim99@8
|
2000 if ( srcName == destName )
|
joachim99@8
|
2001 return true;
|
joachim99@8
|
2002
|
joachim99@8
|
2003 if ( FileAccess(destName, true).exists() )
|
joachim99@8
|
2004 {
|
joachim99@8
|
2005 bool bSuccess = deleteFLD( destName, m_pOptions->m_bDmCreateBakFiles );
|
joachim99@8
|
2006 if ( !bSuccess )
|
joachim99@8
|
2007 {
|
joachim99@51
|
2008 m_pStatusInfo->addText(i18n("Error: copy( %1 -> %2 ) failed."
|
joachim99@51
|
2009 "Deleting existing destination failed.").arg(srcName).arg(destName));
|
joachim99@8
|
2010 return false;
|
joachim99@8
|
2011 }
|
joachim99@8
|
2012 }
|
joachim99@8
|
2013
|
joachim99@8
|
2014 FileAccess fi( srcName );
|
joachim99@8
|
2015
|
joachim99@8
|
2016 if ( fi.isSymLink() && (fi.isDir() && !m_bFollowDirLinks || !fi.isDir() && !m_bFollowDirLinks) )
|
joachim99@8
|
2017 {
|
joachim99@51
|
2018 m_pStatusInfo->addText(i18n("copyLink( %1 -> %2 )").arg(srcName).arg(destName));
|
joachim99@8
|
2019 #ifdef _WIN32
|
joachim99@8
|
2020 // What are links?
|
joachim99@8
|
2021 #else
|
joachim99@8
|
2022 if ( m_bSimulatedMergeStarted )
|
joachim99@8
|
2023 {
|
joachim99@8
|
2024 return true;
|
joachim99@8
|
2025 }
|
joachim99@8
|
2026 FileAccess destFi(destName);
|
joachim99@8
|
2027 if ( !destFi.isLocal() || !fi.isLocal() )
|
joachim99@8
|
2028 {
|
joachim99@51
|
2029 m_pStatusInfo->addText(i18n("Error: copyLink failed: Remote links are not yet supported."));
|
joachim99@8
|
2030 return false;
|
joachim99@8
|
2031 }
|
joachim99@8
|
2032 QString linkTarget = fi.readLink();
|
joachim99@8
|
2033 bool bSuccess = FileAccess::symLink( linkTarget, destName );
|
joachim99@8
|
2034 if (!bSuccess)
|
joachim99@51
|
2035 m_pStatusInfo->addText(i18n("Error: copyLink failed."));
|
joachim99@8
|
2036 return bSuccess;
|
joachim99@8
|
2037 #endif
|
joachim99@8
|
2038 }
|
joachim99@8
|
2039
|
joachim99@8
|
2040 if ( fi.isDir() )
|
joachim99@8
|
2041 {
|
joachim99@8
|
2042 bool bSuccess = makeDir( destName );
|
joachim99@8
|
2043 return bSuccess;
|
joachim99@8
|
2044 }
|
joachim99@8
|
2045
|
joachim99@8
|
2046 int pos=destName.findRev('/');
|
joachim99@8
|
2047 if ( pos>0 )
|
joachim99@8
|
2048 {
|
joachim99@8
|
2049 QString parentName = destName.left(pos);
|
joachim99@8
|
2050 bool bSuccess = makeDir(parentName, true /*quiet*/);
|
joachim99@8
|
2051 if (!bSuccess)
|
joachim99@8
|
2052 return false;
|
joachim99@8
|
2053 }
|
joachim99@8
|
2054
|
joachim99@51
|
2055 m_pStatusInfo->addText(i18n("copy( %1 -> %2 )").arg(srcName).arg(destName));
|
joachim99@8
|
2056
|
joachim99@8
|
2057 if ( m_bSimulatedMergeStarted )
|
joachim99@8
|
2058 {
|
joachim99@8
|
2059 return true;
|
joachim99@8
|
2060 }
|
joachim99@8
|
2061
|
joachim99@8
|
2062 FileAccess faSrc ( srcName );
|
joachim99@8
|
2063 bool bSuccess = faSrc.copyFile( destName );
|
joachim99@8
|
2064 if (! bSuccess ) m_pStatusInfo->addText( faSrc.getStatusText() );
|
joachim99@8
|
2065 return bSuccess;
|
joachim99@8
|
2066 }
|
joachim99@8
|
2067
|
joachim99@8
|
2068 // Rename is not an operation that can be selected by the user.
|
joachim99@8
|
2069 // It will only be used to create backups.
|
joachim99@8
|
2070 // Hence it will delete an existing destination without making a backup (of the old backup.)
|
joachim99@8
|
2071 bool DirectoryMergeWindow::renameFLD( const QString& srcName, const QString& destName )
|
joachim99@8
|
2072 {
|
joachim99@8
|
2073 if ( srcName == destName )
|
joachim99@8
|
2074 return true;
|
joachim99@8
|
2075
|
joachim99@8
|
2076 if ( FileAccess(destName, true).exists() )
|
joachim99@8
|
2077 {
|
joachim99@8
|
2078 bool bSuccess = deleteFLD( destName, false /*no backup*/ );
|
joachim99@8
|
2079 if (!bSuccess)
|
joachim99@8
|
2080 {
|
joachim99@51
|
2081 m_pStatusInfo->addText( i18n("Error during rename( %1 -> %2 ): "
|
joachim99@51
|
2082 "Cannot delete existing destination." ).arg(srcName).arg(destName));
|
joachim99@8
|
2083 return false;
|
joachim99@8
|
2084 }
|
joachim99@8
|
2085 }
|
joachim99@8
|
2086
|
joachim99@51
|
2087 m_pStatusInfo->addText(i18n("rename( %1 -> %2 )").arg(srcName).arg(destName)) ;
|
joachim99@8
|
2088 if ( m_bSimulatedMergeStarted )
|
joachim99@8
|
2089 {
|
joachim99@8
|
2090 return true;
|
joachim99@8
|
2091 }
|
joachim99@8
|
2092
|
joachim99@8
|
2093 bool bSuccess = FileAccess( srcName ).rename( destName );
|
joachim99@8
|
2094 if (!bSuccess)
|
joachim99@8
|
2095 {
|
joachim99@51
|
2096 m_pStatusInfo->addText( i18n("Error: Rename failed.") );
|
joachim99@8
|
2097 return false;
|
joachim99@8
|
2098 }
|
joachim99@8
|
2099
|
joachim99@8
|
2100 return true;
|
joachim99@8
|
2101 }
|
joachim99@8
|
2102
|
joachim99@8
|
2103 bool DirectoryMergeWindow::makeDir( const QString& name, bool bQuiet )
|
joachim99@8
|
2104 {
|
joachim99@8
|
2105 FileAccess fi(name, true);
|
joachim99@8
|
2106 if( fi.exists() && fi.isDir() )
|
joachim99@8
|
2107 return true;
|
joachim99@8
|
2108
|
joachim99@8
|
2109 if( fi.exists() && !fi.isDir() )
|
joachim99@8
|
2110 {
|
joachim99@8
|
2111 bool bSuccess = deleteFLD( name, true );
|
joachim99@8
|
2112 if (!bSuccess)
|
joachim99@8
|
2113 {
|
joachim99@51
|
2114 m_pStatusInfo->addText( i18n("Error during makeDir of %1. "
|
joachim99@51
|
2115 "Cannot delete existing file." ).arg(name));
|
joachim99@8
|
2116 return false;
|
joachim99@8
|
2117 }
|
joachim99@8
|
2118 }
|
joachim99@8
|
2119
|
joachim99@8
|
2120 int pos=name.findRev('/');
|
joachim99@8
|
2121 if ( pos>0 )
|
joachim99@8
|
2122 {
|
joachim99@8
|
2123 QString parentName = name.left(pos);
|
joachim99@8
|
2124 bool bSuccess = makeDir(parentName,true);
|
joachim99@8
|
2125 if (!bSuccess)
|
joachim99@8
|
2126 return false;
|
joachim99@8
|
2127 }
|
joachim99@8
|
2128
|
joachim99@8
|
2129 if ( ! bQuiet )
|
joachim99@51
|
2130 m_pStatusInfo->addText(i18n("makeDir( %1 )").arg(name));
|
joachim99@8
|
2131
|
joachim99@8
|
2132 if ( m_bSimulatedMergeStarted )
|
joachim99@8
|
2133 {
|
joachim99@8
|
2134 return true;
|
joachim99@8
|
2135 }
|
joachim99@8
|
2136
|
joachim99@8
|
2137 bool bSuccess = FileAccess::makeDir( name );
|
joachim99@8
|
2138 if ( bSuccess == false )
|
joachim99@8
|
2139 {
|
joachim99@51
|
2140 m_pStatusInfo->addText( i18n("Error while creating directory.") );
|
joachim99@8
|
2141 return false;
|
joachim99@8
|
2142 }
|
joachim99@8
|
2143 return true;
|
joachim99@8
|
2144 }
|
joachim99@8
|
2145
|
joachim99@8
|
2146
|
joachim99@8
|
2147 DirectoryMergeInfo::DirectoryMergeInfo( QWidget* pParent )
|
joachim99@8
|
2148 : QFrame(pParent)
|
joachim99@8
|
2149 {
|
joachim99@8
|
2150 QVBoxLayout *topLayout = new QVBoxLayout( this );
|
joachim99@8
|
2151
|
joachim99@8
|
2152 QGridLayout *grid = new QGridLayout( topLayout );
|
joachim99@8
|
2153 grid->setColStretch(1,10);
|
joachim99@8
|
2154
|
joachim99@8
|
2155 int line=0;
|
joachim99@8
|
2156
|
joachim99@8
|
2157 m_pA = new QLabel("A",this); grid->addWidget( m_pA,line, 0 );
|
joachim99@8
|
2158 m_pInfoA = new QLabel(this); grid->addWidget( m_pInfoA,line,1 ); ++line;
|
joachim99@8
|
2159 m_pB = new QLabel("B",this); grid->addWidget( m_pB,line, 0 );
|
joachim99@8
|
2160 m_pInfoB = new QLabel(this); grid->addWidget( m_pInfoB,line,1 ); ++line;
|
joachim99@8
|
2161 m_pC = new QLabel("C",this); grid->addWidget( m_pC,line, 0 );
|
joachim99@8
|
2162 m_pInfoC = new QLabel(this); grid->addWidget( m_pInfoC,line,1 ); ++line;
|
joachim99@51
|
2163 m_pDest = new QLabel(i18n("Dest"),this); grid->addWidget( m_pDest,line, 0 );
|
joachim99@8
|
2164 m_pInfoDest = new QLabel(this); grid->addWidget( m_pInfoDest,line,1 ); ++line;
|
joachim99@8
|
2165
|
joachim99@8
|
2166 m_pInfoList = new QListView(this); topLayout->addWidget( m_pInfoList );
|
joachim99@51
|
2167 m_pInfoList->addColumn(i18n("Dir"));
|
joachim99@51
|
2168 m_pInfoList->addColumn(i18n("Type"));
|
joachim99@51
|
2169 m_pInfoList->addColumn(i18n("Size"));
|
joachim99@51
|
2170 m_pInfoList->addColumn(i18n("Attr"));
|
joachim99@51
|
2171 m_pInfoList->addColumn(i18n("Last Modification"));
|
joachim99@51
|
2172 m_pInfoList->addColumn(i18n("Link-Destination"));
|
joachim99@8
|
2173 setMinimumSize( 100,100 );
|
joachim99@8
|
2174 }
|
joachim99@8
|
2175
|
joachim99@8
|
2176 static void addListViewItem( QListView* pListView, const QString& dir,
|
joachim99@8
|
2177 const QString& basePath, FileAccess& fi )
|
joachim99@8
|
2178 {
|
joachim99@8
|
2179 if ( basePath.isEmpty() )
|
joachim99@8
|
2180 {
|
joachim99@8
|
2181 return;
|
joachim99@8
|
2182 }
|
joachim99@8
|
2183 else
|
joachim99@8
|
2184 {
|
joachim99@8
|
2185 if ( fi.exists() )
|
joachim99@8
|
2186 {
|
joachim99@8
|
2187 #if QT_VERSION==230
|
joachim99@8
|
2188 QString dateString = fi.lastModified().toString();
|
joachim99@8
|
2189 #else
|
joachim99@8
|
2190 QString dateString = fi.lastModified().toString("yyyy-MM-dd hh:mm:ss");
|
joachim99@8
|
2191 #endif
|
joachim99@8
|
2192
|
joachim99@8
|
2193 new QListViewItem(
|
joachim99@8
|
2194 pListView,
|
joachim99@8
|
2195 dir,
|
joachim99@51
|
2196 QString( fi.isDir() ? i18n("Dir") : i18n("File") ) + (fi.isSymLink() ? "-Link" : ""),
|
joachim99@8
|
2197 QString::number(fi.size()),
|
joachim99@8
|
2198 QString(fi.isReadable() ? "r" : " ") + (fi.isWritable()?"w" : " ")
|
joachim99@8
|
2199 #ifdef _WIN32
|
joachim99@8
|
2200 /*Future: Use GetFileAttributes()*/,
|
joachim99@8
|
2201 #else
|
joachim99@8
|
2202 + (fi.isExecutable()?"x" : " "),
|
joachim99@8
|
2203 #endif
|
joachim99@8
|
2204 dateString,
|
joachim99@8
|
2205 QString(fi.isSymLink() ? (" -> " + fi.readLink()) : QString(""))
|
joachim99@8
|
2206 );
|
joachim99@8
|
2207 }
|
joachim99@8
|
2208 else
|
joachim99@8
|
2209 {
|
joachim99@8
|
2210 new QListViewItem(
|
joachim99@8
|
2211 pListView,
|
joachim99@8
|
2212 dir,
|
joachim99@51
|
2213 i18n("not available"),
|
joachim99@8
|
2214 "",
|
joachim99@8
|
2215 "",
|
joachim99@8
|
2216 "",
|
joachim99@8
|
2217 ""
|
joachim99@8
|
2218 );
|
joachim99@8
|
2219 }
|
joachim99@8
|
2220 }
|
joachim99@8
|
2221 }
|
joachim99@8
|
2222
|
joachim99@8
|
2223 void DirectoryMergeInfo::setInfo(
|
joachim99@8
|
2224 const FileAccess& dirA,
|
joachim99@8
|
2225 const FileAccess& dirB,
|
joachim99@8
|
2226 const FileAccess& dirC,
|
joachim99@8
|
2227 const FileAccess& dirDest,
|
joachim99@8
|
2228 MergeFileInfos& mfi )
|
joachim99@8
|
2229 {
|
joachim99@8
|
2230 bool bHideDest = false;
|
joachim99@8
|
2231 if ( dirA.absFilePath()==dirDest.absFilePath() )
|
joachim99@8
|
2232 {
|
joachim99@51
|
2233 m_pA->setText( i18n("A (Dest): ") ); bHideDest=true;
|
joachim99@8
|
2234 }
|
joachim99@8
|
2235 else
|
joachim99@51
|
2236 m_pA->setText( !dirC.isValid() ? QString("A: ") : i18n("A (Base): "));
|
joachim99@8
|
2237
|
joachim99@8
|
2238 m_pInfoA->setText( dirA.prettyAbsPath() );
|
joachim99@8
|
2239
|
joachim99@8
|
2240 if ( dirB.absFilePath()==dirDest.absFilePath() )
|
joachim99@8
|
2241 {
|
joachim99@51
|
2242 m_pB->setText( i18n("B (Dest): ") ); bHideDest=true;
|
joachim99@8
|
2243 }
|
joachim99@8
|
2244 else
|
joachim99@8
|
2245 m_pB->setText( "B: " );
|
joachim99@8
|
2246 m_pInfoB->setText( dirB.prettyAbsPath() );
|
joachim99@8
|
2247
|
joachim99@8
|
2248 if ( dirC.absFilePath()==dirDest.absFilePath() )
|
joachim99@8
|
2249 {
|
joachim99@51
|
2250 m_pC->setText( i18n("C (Dest): ") ); bHideDest=true;
|
joachim99@8
|
2251 }
|
joachim99@8
|
2252 else
|
joachim99@8
|
2253 m_pC->setText( "C: " );
|
joachim99@8
|
2254 m_pInfoC->setText( dirC.prettyAbsPath() );
|
joachim99@8
|
2255
|
joachim99@51
|
2256 m_pDest->setText( i18n("Dest: ") ); m_pInfoDest->setText( dirDest.prettyAbsPath() );
|
joachim99@8
|
2257
|
joachim99@8
|
2258 if (!dirC.isValid()) { m_pC->hide(); m_pInfoC->hide(); }
|
joachim99@8
|
2259 else { m_pC->show(); m_pInfoC->show(); }
|
joachim99@8
|
2260
|
joachim99@8
|
2261 if (!dirDest.isValid()||bHideDest) { m_pDest->hide(); m_pInfoDest->hide(); }
|
joachim99@8
|
2262 else { m_pDest->show(); m_pInfoDest->show(); }
|
joachim99@8
|
2263
|
joachim99@8
|
2264 m_pInfoList->clear();
|
joachim99@8
|
2265 addListViewItem( m_pInfoList, "A", dirA.prettyAbsPath(), mfi.m_fileInfoA );
|
joachim99@8
|
2266 addListViewItem( m_pInfoList, "B", dirB.prettyAbsPath(), mfi.m_fileInfoB );
|
joachim99@8
|
2267 addListViewItem( m_pInfoList, "C", dirC.prettyAbsPath(), mfi.m_fileInfoC );
|
joachim99@8
|
2268 if (!bHideDest)
|
joachim99@8
|
2269 {
|
joachim99@8
|
2270 FileAccess fiDest( dirDest.prettyAbsPath() + "/" + mfi.m_subPath, true );
|
joachim99@51
|
2271 addListViewItem( m_pInfoList, i18n("Dest"), dirDest.prettyAbsPath(), fiDest );
|
joachim99@8
|
2272 }
|
joachim99@8
|
2273 }
|
joachim99@8
|
2274
|
joachim99@51
|
2275
|
joachim99@51
|
2276 void DirectoryMergeWindow::initDirectoryMergeActions( QObject* pKDiff3App, KActionCollection* ac )
|
joachim99@51
|
2277 {
|
joachim99@51
|
2278 #include "xpm/startmerge.xpm"
|
joachim99@51
|
2279 DirectoryMergeWindow* p = this;
|
joachim99@51
|
2280
|
joachim99@51
|
2281 dirStartOperation = new KAction(i18n("Start/Continue Directory Merge"), Key_F7, p, SLOT(slotRunOperationForAllItems()), ac, "dir_start_operation");
|
joachim99@51
|
2282 dirRunOperationForCurrentItem = new KAction(i18n("Run Operation for Current Item"), Key_F6, p, SLOT(slotRunOperationForCurrentItem()), ac, "dir_run_operation_for_current_item");
|
joachim99@51
|
2283 dirCompareCurrent = new KAction(i18n("Compare Selected File"), 0, p, SLOT(compareCurrentFile()), ac, "dir_compare_current");
|
joachim99@51
|
2284 dirMergeCurrent = new KAction(i18n("Merge Current File"), QIconSet(QPixmap(startmerge)), 0, pKDiff3App, SLOT(slotMergeCurrentFile()), ac, "merge_current");
|
joachim99@51
|
2285 dirFoldAll = new KAction(i18n("Fold All Subdirs"), 0, p, SLOT(slotFoldAllSubdirs()), ac, "dir_fold_all");
|
joachim99@51
|
2286 dirUnfoldAll = new KAction(i18n("Unfold All Subdirs"), 0, p, SLOT(slotUnfoldAllSubdirs()), ac, "dir_unfold_all");
|
joachim99@53
|
2287 dirRescan = new KAction(i18n("Rescan"), SHIFT+Key_F5, p, SLOT(reload()), ac, "dir_rescan");
|
joachim99@51
|
2288 dirChooseAEverywhere = new KAction(i18n("Choose A for All Items"), 0, p, SLOT(slotChooseAEverywhere()), ac, "dir_choose_a_everywhere");
|
joachim99@51
|
2289 dirChooseBEverywhere = new KAction(i18n("Choose B for All Items"), 0, p, SLOT(slotChooseBEverywhere()), ac, "dir_choose_b_everywhere");
|
joachim99@51
|
2290 dirChooseCEverywhere = new KAction(i18n("Choose C for All Items"), 0, p, SLOT(slotChooseCEverywhere()), ac, "dir_choose_c_everywhere");
|
joachim99@51
|
2291 dirAutoChoiceEverywhere = new KAction(i18n("Auto-Choose Operation for All Items"), 0, p, SLOT(slotAutoChooseEverywhere()), ac, "dir_autochoose_everywhere");
|
joachim99@51
|
2292 dirDoNothingEverywhere = new KAction(i18n("No Operation for All Items"), 0, p, SLOT(slotNoOpEverywhere()), ac, "dir_nothing_everywhere");
|
joachim99@51
|
2293
|
joachim99@51
|
2294 dirCurrentDoNothing = new KAction(i18n("Do Nothing"), 0, p, SLOT(slotCurrentDoNothing()), ac, "dir_current_do_nothing");
|
joachim99@51
|
2295 dirCurrentChooseA = new KAction(i18n("A"), 0, p, SLOT(slotCurrentChooseA()), ac, "dir_current_choose_a");
|
joachim99@51
|
2296 dirCurrentChooseB = new KAction(i18n("B"), 0, p, SLOT(slotCurrentChooseB()), ac, "dir_current_choose_b");
|
joachim99@51
|
2297 dirCurrentChooseC = new KAction(i18n("C"), 0, p, SLOT(slotCurrentChooseC()), ac, "dir_current_choose_c");
|
joachim99@51
|
2298 dirCurrentMerge = new KAction(i18n("Merge"), 0, p, SLOT(slotCurrentMerge()), ac, "dir_current_merge");
|
joachim99@51
|
2299 dirCurrentDelete = new KAction(i18n("Delete (If Exists)"), 0, p, SLOT(slotCurrentDelete()), ac, "dir_current_delete");
|
joachim99@51
|
2300
|
joachim99@51
|
2301 dirCurrentSyncDoNothing = new KAction(i18n("Do Nothing"), 0, p, SLOT(slotCurrentDoNothing()), ac, "dir_current_sync_do_nothing");
|
joachim99@51
|
2302 dirCurrentSyncCopyAToB = new KAction(i18n("Copy A to B"), 0, p, SLOT(slotCurrentCopyAToB()), ac, "dir_current_sync_copy_a_to_b" );
|
joachim99@51
|
2303 dirCurrentSyncCopyBToA = new KAction(i18n("Copy B to A"), 0, p, SLOT(slotCurrentCopyBToA()), ac, "dir_current_sync_copy_b_to_a" );
|
joachim99@51
|
2304 dirCurrentSyncDeleteA = new KAction(i18n("Delete A"), 0, p, SLOT(slotCurrentDeleteA()), ac,"dir_current_sync_delete_a");
|
joachim99@51
|
2305 dirCurrentSyncDeleteB = new KAction(i18n("Delete B"), 0, p, SLOT(slotCurrentDeleteB()), ac,"dir_current_sync_delete_b");
|
joachim99@51
|
2306 dirCurrentSyncDeleteAAndB = new KAction(i18n("Delete A and B"), 0, p, SLOT(slotCurrentDeleteAAndB()), ac,"dir_current_sync_delete_a_and_b");
|
joachim99@51
|
2307 dirCurrentSyncMergeToA = new KAction(i18n("Merge to A"), 0, p, SLOT(slotCurrentMergeToA()), ac,"dir_current_sync_merge_to_a");
|
joachim99@51
|
2308 dirCurrentSyncMergeToB = new KAction(i18n("Merge to B"), 0, p, SLOT(slotCurrentMergeToB()), ac,"dir_current_sync_merge_to_b");
|
joachim99@51
|
2309 dirCurrentSyncMergeToAAndB = new KAction(i18n("Merge to A and B"), 0, p, SLOT(slotCurrentMergeToAAndB()), ac,"dir_current_sync_merge_to_a_and_b");
|
joachim99@51
|
2310 }
|
joachim99@51
|
2311
|
joachim99@51
|
2312
|
joachim99@53
|
2313 void DirectoryMergeWindow::updateAvailabilities( bool bDirCompare, bool bDiffWindowVisible,
|
joachim99@53
|
2314 KToggleAction* chooseA, KToggleAction* chooseB, KToggleAction* chooseC )
|
joachim99@51
|
2315 {
|
joachim99@51
|
2316 dirStartOperation->setEnabled( bDirCompare );
|
joachim99@51
|
2317 dirRunOperationForCurrentItem->setEnabled( bDirCompare );
|
joachim99@51
|
2318 dirFoldAll->setEnabled( bDirCompare );
|
joachim99@51
|
2319 dirUnfoldAll->setEnabled( bDirCompare );
|
joachim99@51
|
2320
|
joachim99@51
|
2321 dirCompareCurrent->setEnabled( bDirCompare && isVisible() && isFileSelected() );
|
joachim99@51
|
2322
|
joachim99@51
|
2323 dirMergeCurrent->setEnabled( bDirCompare && isVisible() && isFileSelected()
|
joachim99@51
|
2324 || bDiffWindowVisible );
|
joachim99@51
|
2325
|
joachim99@51
|
2326 dirRescan->setEnabled( bDirCompare );
|
joachim99@51
|
2327
|
joachim99@51
|
2328 dirAutoChoiceEverywhere->setEnabled( bDirCompare && isVisible() );
|
joachim99@51
|
2329 dirDoNothingEverywhere->setEnabled( bDirCompare && isVisible() );
|
joachim99@51
|
2330 dirChooseAEverywhere->setEnabled( bDirCompare && isVisible() );
|
joachim99@51
|
2331 dirChooseBEverywhere->setEnabled( bDirCompare && isVisible() );
|
joachim99@51
|
2332 dirChooseCEverywhere->setEnabled( bDirCompare && isVisible() );
|
joachim99@51
|
2333
|
joachim99@51
|
2334 bool bThreeDirs = m_dirC.isValid();
|
joachim99@51
|
2335
|
joachim99@51
|
2336 QListViewItem* lvi = currentItem();
|
joachim99@51
|
2337 DirMergeItem* pDMI = lvi==0 ? 0 : static_cast<DirMergeItem*>(lvi);
|
joachim99@51
|
2338 MergeFileInfos* pMFI = pDMI==0 ? 0 : pDMI->m_pMFI;
|
joachim99@51
|
2339
|
joachim99@51
|
2340 bool bItemActive = bDirCompare && isVisible() && pMFI!=0;// && hasFocus();
|
joachim99@51
|
2341 bool bMergeMode = bThreeDirs || !m_bSyncMode;
|
joachim99@51
|
2342 bool bFTConflict = pMFI==0 ? false : conflictingFileTypes(*pMFI);
|
joachim99@51
|
2343
|
joachim99@53
|
2344 bool bDirWindowHasFocus = isVisible() && hasFocus();
|
joachim99@53
|
2345
|
joachim99@51
|
2346 dirCurrentDoNothing->setEnabled( bItemActive && bMergeMode );
|
joachim99@51
|
2347 dirCurrentChooseA->setEnabled( bItemActive && bMergeMode && pMFI->m_bExistsInA );
|
joachim99@51
|
2348 dirCurrentChooseB->setEnabled( bItemActive && bMergeMode && pMFI->m_bExistsInB );
|
joachim99@51
|
2349 dirCurrentChooseC->setEnabled( bItemActive && bMergeMode && pMFI->m_bExistsInC );
|
joachim99@51
|
2350 dirCurrentMerge->setEnabled( bItemActive && bMergeMode && !bFTConflict );
|
joachim99@51
|
2351 dirCurrentDelete->setEnabled( bItemActive && bMergeMode );
|
joachim99@53
|
2352 if ( bDirWindowHasFocus )
|
joachim99@53
|
2353 {
|
joachim99@53
|
2354 chooseA->setEnabled( bItemActive && pMFI->m_bExistsInA );
|
joachim99@53
|
2355 chooseB->setEnabled( bItemActive && pMFI->m_bExistsInB );
|
joachim99@53
|
2356 chooseC->setEnabled( bItemActive && pMFI->m_bExistsInC );
|
joachim99@53
|
2357 chooseA->setChecked( false );
|
joachim99@53
|
2358 chooseB->setChecked( false );
|
joachim99@53
|
2359 chooseC->setChecked( false );
|
joachim99@53
|
2360 }
|
joachim99@53
|
2361
|
joachim99@51
|
2362 dirCurrentSyncDoNothing->setEnabled( bItemActive && !bMergeMode );
|
joachim99@51
|
2363 dirCurrentSyncCopyAToB->setEnabled( bItemActive && !bMergeMode && pMFI->m_bExistsInA );
|
joachim99@51
|
2364 dirCurrentSyncCopyBToA->setEnabled( bItemActive && !bMergeMode && pMFI->m_bExistsInB );
|
joachim99@51
|
2365 dirCurrentSyncDeleteA->setEnabled( bItemActive && !bMergeMode && pMFI->m_bExistsInA );
|
joachim99@51
|
2366 dirCurrentSyncDeleteB->setEnabled( bItemActive && !bMergeMode && pMFI->m_bExistsInB );
|
joachim99@51
|
2367 dirCurrentSyncDeleteAAndB->setEnabled( bItemActive && !bMergeMode && pMFI->m_bExistsInB && pMFI->m_bExistsInB );
|
joachim99@51
|
2368 dirCurrentSyncMergeToA->setEnabled( bItemActive && !bMergeMode && !bFTConflict );
|
joachim99@51
|
2369 dirCurrentSyncMergeToB->setEnabled( bItemActive && !bMergeMode && !bFTConflict );
|
joachim99@51
|
2370 dirCurrentSyncMergeToAAndB->setEnabled( bItemActive && !bMergeMode && !bFTConflict );
|
joachim99@51
|
2371 }
|
joachim99@51
|
2372
|
joachim99@51
|
2373
|
joachim99@8
|
2374 #include "directorymergewindow.moc"
|