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