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