annotate kdiff3/src/directorymergewindow.cpp @ 69:8febbfb1148c

KDiff3 0.9.89
author joachim99
date Mon, 10 Apr 2006 08:40:51 +0000
parents d7cafcda8c99
children 5bbfe4784324
rev   line source
joachim99@8 1 /***************************************************************************
joachim99@8 2 directorymergewindow.cpp
joachim99@58 3 -----------------
joachim99@8 4 begin : Sat Oct 19 2002
joachim99@69 5 copyright : (C) 2002-2005 by Joachim Eibl
joachim99@69 6 email : joachim.eibl at 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@69 35 #include <qtextedit.h>
joachim99@8 36 #include <qprogressdialog.h>
joachim99@8 37 #include <kmessagebox.h>
joachim99@69 38 #include <kfiledialog.h>
joachim99@8 39 #include <kiconloader.h>
joachim99@8 40 #include <klocale.h>
joachim99@8 41 #include <iostream>
joachim99@8 42 #include <assert.h>
joachim99@69 43 #include <konq_popupmenu.h>
joachim99@8 44
joachim99@51 45 static bool conflictingFileTypes(MergeFileInfos& mfi);
joachim99@69 46 /*
joachim99@8 47 class StatusInfo : public QListView
joachim99@8 48 {
joachim99@8 49 public:
joachim99@69 50 StatusInfo(QWidget* pParent) : QListView( pParent, "StatusInfo", Qt::WShowModal )
joachim99@8 51 {
joachim99@8 52 addColumn("");
joachim99@8 53 setSorting(-1); //disable sorting
joachim99@8 54 }
joachim99@8 55
joachim99@8 56 QListViewItem* m_pLast;
joachim99@8 57 QListViewItem* last()
joachim99@8 58 {
joachim99@8 59 if (firstChild()==0) return 0;
joachim99@8 60 else return m_pLast;
joachim99@8 61 }
joachim99@68 62
joachim99@8 63 void addText(const QString& s )
joachim99@8 64 {
joachim99@8 65 if (firstChild()==0) m_pLast = new QListViewItem( this, s );
joachim99@8 66 else m_pLast = new QListViewItem( this, last(), s );
joachim99@8 67 }
joachim99@8 68 };
joachim99@69 69 */
joachim99@69 70 class StatusInfo : public QTextEdit
joachim99@69 71 {
joachim99@69 72 public:
joachim99@69 73 StatusInfo(QWidget* pParent) : QTextEdit( pParent, "StatusInfo" )
joachim99@69 74 {
joachim99@69 75 setWFlags(Qt::WShowModal);
joachim99@69 76 setWordWrap(QTextEdit::NoWrap);
joachim99@69 77 setReadOnly(true);
joachim99@69 78 showMaximized();
joachim99@69 79 }
joachim99@69 80
joachim99@69 81 bool isEmpty(){ return text().isEmpty(); }
joachim99@69 82
joachim99@69 83 void addText(const QString& s )
joachim99@69 84 {
joachim99@69 85 append(s);
joachim99@69 86 }
joachim99@69 87
joachim99@69 88 void show()
joachim99@69 89 {
joachim99@69 90 scrollToBottom();
joachim99@69 91 QTextEdit::show();
joachim99@69 92 }
joachim99@69 93 };
joachim99@8 94
joachim99@8 95
joachim99@8 96 class TempRemover
joachim99@8 97 {
joachim99@8 98 public:
joachim99@8 99 TempRemover( const QString& origName, FileAccess& fa );
joachim99@8 100 ~TempRemover();
joachim99@8 101 QString name() { return m_name; }
joachim99@8 102 bool success() { return m_bSuccess; }
joachim99@8 103 private:
joachim99@8 104 QString m_name;
joachim99@8 105 bool m_bTemp;
joachim99@8 106 bool m_bSuccess;
joachim99@8 107 };
joachim99@8 108 TempRemover::TempRemover(const QString& origName, FileAccess& fa)
joachim99@8 109 {
joachim99@8 110 if ( fa.isLocal() )
joachim99@8 111 {
joachim99@8 112 m_name = origName;
joachim99@8 113 m_bTemp = false;
joachim99@8 114 m_bSuccess = true;
joachim99@8 115 }
joachim99@8 116 else
joachim99@8 117 {
joachim99@8 118 m_name = FileAccess::tempFileName();
joachim99@8 119 m_bSuccess = fa.copyFile( m_name );
joachim99@8 120 m_bTemp = m_bSuccess;
joachim99@8 121 }
joachim99@8 122 }
joachim99@8 123 TempRemover::~TempRemover()
joachim99@8 124 {
joachim99@8 125 if ( m_bTemp && ! m_name.isEmpty() )
joachim99@8 126 FileAccess::removeFile(m_name);
joachim99@8 127 }
joachim99@8 128
joachim99@8 129 void DirectoryMergeWindow::fastFileComparison(
joachim99@8 130 FileAccess& fi1, FileAccess& fi2,
joachim99@8 131 bool& bEqual, bool& bError, QString& status )
joachim99@8 132 {
joachim99@66 133 ProgressProxy pp;
joachim99@8 134 status = "";
joachim99@8 135 bEqual = false;
joachim99@8 136 bError = true;
joachim99@8 137
joachim99@8 138 if ( !m_bFollowFileLinks )
joachim99@8 139 {
joachim99@8 140 if ( fi1.isSymLink() != fi2.isSymLink() )
joachim99@8 141 {
joachim99@51 142 status = i18n("Mix of links and normal files.");
joachim99@8 143 return;
joachim99@8 144 }
joachim99@8 145 else if ( fi1.isSymLink() && fi2.isSymLink() )
joachim99@8 146 {
joachim99@8 147 bError = false;
joachim99@8 148 bEqual = fi1.readLink() == fi2.readLink();
joachim99@51 149 status = i18n("Link: ");
joachim99@8 150 return;
joachim99@8 151 }
joachim99@8 152 }
joachim99@8 153
joachim99@8 154 if ( fi1.size()!=fi2.size() )
joachim99@8 155 {
joachim99@8 156 bEqual = false;
joachim99@51 157 status = i18n("Size. ");
joachim99@51 158 return;
joachim99@51 159 }
joachim99@51 160 else if ( m_pOptions->m_bDmTrustSize )
joachim99@51 161 {
joachim99@51 162 bEqual = true;
joachim99@8 163 return;
joachim99@8 164 }
joachim99@8 165
joachim99@8 166 if ( m_pOptions->m_bDmTrustDate )
joachim99@8 167 {
joachim99@8 168 bEqual = ( fi1.lastModified() == fi2.lastModified() && fi1.size()==fi2.size() );
joachim99@8 169 bError = false;
joachim99@51 170 status = i18n("Date & Size: ");
joachim99@8 171 return;
joachim99@8 172 }
joachim99@8 173
joachim99@8 174 QString fileName1 = fi1.absFilePath();
joachim99@8 175 QString fileName2 = fi2.absFilePath();
joachim99@8 176 TempRemover tr1( fileName1, fi1 );
joachim99@8 177 if ( !tr1.success() )
joachim99@8 178 {
joachim99@51 179 status = i18n("Creating temp copy of %1 failed.").arg(fileName1);
joachim99@8 180 return;
joachim99@8 181 }
joachim99@8 182 TempRemover tr2( fileName2, fi2 );
joachim99@8 183 if ( !tr2.success() )
joachim99@8 184 {
joachim99@51 185 status = i18n("Creating temp copy of %1 failed.").arg(fileName2);
joachim99@8 186 return;
joachim99@8 187 }
joachim99@8 188
joachim99@8 189 std::vector<char> buf1(100000);
joachim99@8 190 std::vector<char> buf2(buf1.size());
joachim99@8 191
joachim99@8 192 QFile file1( tr1.name() );
joachim99@8 193
joachim99@8 194 if ( ! file1.open(IO_ReadOnly) )
joachim99@8 195 {
joachim99@51 196 status = i18n("Opening %1 failed.").arg(fileName1);
joachim99@8 197 return;
joachim99@8 198 }
joachim99@8 199
joachim99@8 200 QFile file2( tr2.name() );
joachim99@8 201
joachim99@8 202 if ( ! file2.open(IO_ReadOnly) )
joachim99@8 203 {
joachim99@51 204 status = i18n("Opening %1 failed.").arg(fileName2);
joachim99@8 205 return;
joachim99@8 206 }
joachim99@8 207
joachim99@68 208 pp.setInformation( i18n("Comparing file..."), 0, false );
joachim99@8 209 typedef QFile::Offset t_FileSize;
joachim99@66 210 t_FileSize fullSize = file1.size();
joachim99@66 211 t_FileSize sizeLeft = fullSize;
joachim99@8 212
joachim99@66 213 while( sizeLeft>0 && ! pp.wasCancelled() )
joachim99@8 214 {
joachim99@66 215 int len = min2( sizeLeft, (t_FileSize)buf1.size() );
joachim99@8 216 if( len != file1.readBlock( &buf1[0], len ) )
joachim99@8 217 {
joachim99@51 218 status = i18n("Error reading from %1").arg(fileName1);
joachim99@8 219 return;
joachim99@8 220 }
joachim99@8 221
joachim99@8 222 if( len != file2.readBlock( &buf2[0], len ) )
joachim99@8 223 {
joachim99@51 224 status = i18n("Error reading from %1").arg(fileName2);
joachim99@8 225 return;
joachim99@8 226 }
joachim99@8 227
joachim99@8 228 if ( memcmp( &buf1[0], &buf2[0], len ) != 0 )
joachim99@8 229 {
joachim99@8 230 bError = false;
joachim99@8 231 return;
joachim99@8 232 }
joachim99@66 233 sizeLeft-=len;
joachim99@66 234 pp.setCurrent(double(fullSize-sizeLeft)/fullSize, false );
joachim99@8 235 }
joachim99@8 236
joachim99@8 237 // If the program really arrives here, then the files are really equal.
joachim99@8 238 bError = false;
joachim99@8 239 bEqual = true;
joachim99@8 240 }
joachim99@8 241
joachim99@8 242
joachim99@8 243
joachim99@8 244
joachim99@8 245
joachim99@8 246 static int s_nameCol = 0;
joachim99@8 247 static int s_ACol = 1;
joachim99@8 248 static int s_BCol = 2;
joachim99@8 249 static int s_CCol = 3;
joachim99@8 250 static int s_OpCol = 4;
joachim99@8 251 static int s_OpStatusCol = 5;
joachim99@66 252 static int s_UnsolvedCol = 6; // Nr of unsolved conflicts (for 3 input files)
joachim99@66 253 static int s_SolvedCol = 7; // Nr of auto-solvable conflicts (for 3 input files)
joachim99@66 254 static int s_NonWhiteCol = 8; // Nr of nonwhite deltas (for 2 input files)
joachim99@66 255 static int s_WhiteCol = 9; // Nr of white deltas (for 2 input files)
joachim99@8 256 DirectoryMergeWindow::DirectoryMergeWindow( QWidget* pParent, OptionDialog* pOptions, KIconLoader* pIconLoader )
joachim99@8 257 : QListView( pParent )
joachim99@8 258 {
joachim99@8 259 connect( this, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(onDoubleClick(QListViewItem*)));
joachim99@8 260 connect( this, SIGNAL(returnPressed(QListViewItem*)), this, SLOT(onDoubleClick(QListViewItem*)));
joachim99@69 261 connect( this, SIGNAL( mouseButtonPressed(int,QListViewItem*,const QPoint&, int)),
joachim99@69 262 this, SLOT( onClick(int,QListViewItem*,const QPoint&, int)) );
joachim99@69 263 connect( this, SIGNAL(contextMenuRequested(QListViewItem*,const QPoint &,int)),
joachim99@69 264 this, SLOT( slotShowContextMenu(QListViewItem*,const QPoint &,int)));
joachim99@8 265 connect( this, SIGNAL(selectionChanged(QListViewItem*)), this, SLOT(onSelectionChanged(QListViewItem*)));
joachim99@8 266 m_pOptions = pOptions;
joachim99@8 267 m_pIconLoader = pIconLoader;
joachim99@8 268 m_pDirectoryMergeInfo = 0;
joachim99@8 269 m_bAllowResizeEvents = true;
joachim99@8 270 m_bSimulatedMergeStarted=false;
joachim99@8 271 m_bRealMergeStarted=false;
joachim99@8 272 m_bError = false;
joachim99@8 273 m_bSyncMode = false;
joachim99@8 274 m_pStatusInfo = new StatusInfo(0);
joachim99@8 275 m_pStatusInfo->hide();
joachim99@66 276 m_bScanning = false;
joachim99@69 277 m_pSelection1Item = 0;
joachim99@69 278 m_pSelection2Item = 0;
joachim99@69 279 m_pSelection3Item = 0;
joachim99@69 280 m_bCaseSensitive = true;
joachim99@68 281
joachim99@51 282 addColumn(i18n("Name"));
joachim99@8 283 addColumn("A");
joachim99@8 284 addColumn("B");
joachim99@8 285 addColumn("C");
joachim99@51 286 addColumn(i18n("Operation"));
joachim99@51 287 addColumn(i18n("Status"));
joachim99@66 288 addColumn(i18n("Unsolved"));
joachim99@66 289 addColumn(i18n("Solved"));
joachim99@66 290 addColumn(i18n("Nonwhite"));
joachim99@66 291 addColumn(i18n("White"));
joachim99@68 292
joachim99@66 293 setColumnAlignment( s_UnsolvedCol, Qt::AlignRight );
joachim99@66 294 setColumnAlignment( s_SolvedCol, Qt::AlignRight );
joachim99@66 295 setColumnAlignment( s_NonWhiteCol, Qt::AlignRight );
joachim99@66 296 setColumnAlignment( s_WhiteCol, Qt::AlignRight );
joachim99@8 297 }
joachim99@8 298
joachim99@8 299 DirectoryMergeWindow::~DirectoryMergeWindow()
joachim99@8 300 {
joachim99@8 301 }
joachim99@8 302
joachim99@8 303
joachim99@8 304 int DirectoryMergeWindow::totalColumnWidth()
joachim99@8 305 {
joachim99@8 306 int w=0;
joachim99@8 307 for (int i=0; i<s_OpStatusCol; ++i)
joachim99@8 308 {
joachim99@8 309 w += columnWidth(i);
joachim99@8 310 }
joachim99@8 311 return w;
joachim99@8 312 }
joachim99@8 313
joachim99@8 314 void DirectoryMergeWindow::reload()
joachim99@8 315 {
joachim99@8 316 if ( isDirectoryMergeInProgress() )
joachim99@8 317 {
joachim99@8 318 int result = KMessageBox::warningYesNo(this,
joachim99@8 319 i18n("You are currently doing a directory merge. Are you sure, you want to abort the merge and rescan the directory?"),
joachim99@51 320 i18n("Warning"), i18n("Rescan"), i18n("Continue Merging") );
joachim99@8 321 if ( result!=KMessageBox::Yes )
joachim99@8 322 return;
joachim99@8 323 }
joachim99@68 324
joachim99@8 325 init( m_dirA, m_dirB, m_dirC, m_dirDest, m_bDirectoryMerge );
joachim99@8 326 }
joachim99@8 327
joachim99@8 328 // Copy pm2 onto pm1, but preserve the alpha value from pm1 where pm2 is transparent.
joachim99@69 329 static QPixmap pixCombiner( const QPixmap* pm1, const QPixmap* pm2 )
joachim99@8 330 {
joachim99@69 331 QImage img1 = pm1->convertToImage().convertDepth(32);
joachim99@69 332 QImage img2 = pm2->convertToImage().convertDepth(32);
joachim99@8 333
joachim99@8 334 for (int y = 0; y < img1.height(); y++)
joachim99@8 335 {
joachim99@8 336 Q_UINT32 *line1 = reinterpret_cast<Q_UINT32 *>(img1.scanLine(y));
joachim99@8 337 Q_UINT32 *line2 = reinterpret_cast<Q_UINT32 *>(img2.scanLine(y));
joachim99@8 338 for (int x = 0; x < img1.width(); x++)
joachim99@8 339 {
joachim99@8 340 if ( qAlpha( line2[x] ) >0 )
joachim99@8 341 line1[x] = (line2[x] | 0xff000000);
joachim99@8 342 }
joachim99@8 343 }
joachim99@8 344 QPixmap pix;
joachim99@8 345 pix.convertFromImage(img1);
joachim99@8 346 return pix;
joachim99@8 347 }
joachim99@8 348
joachim99@8 349 // like pixCombiner but let the pm1 color shine through
joachim99@69 350 static QPixmap pixCombiner2( const QPixmap* pm1, const QPixmap* pm2 )
joachim99@8 351 {
joachim99@69 352 QImage img1 = pm1->convertToImage().convertDepth(32);
joachim99@69 353 QImage img2 = pm2->convertToImage().convertDepth(32);
joachim99@8 354
joachim99@8 355 for (int y = 0; y < img1.height(); y++)
joachim99@8 356 {
joachim99@8 357 Q_UINT32 *line1 = reinterpret_cast<Q_UINT32 *>(img1.scanLine(y));
joachim99@8 358 Q_UINT32 *line2 = reinterpret_cast<Q_UINT32 *>(img2.scanLine(y));
joachim99@8 359 for (int x = 0; x < img1.width(); x++)
joachim99@8 360 {
joachim99@8 361 if ( qAlpha( line2[x] ) >0 )
joachim99@8 362 {
joachim99@8 363 int r = ( qRed( line1[x] ) + qRed( line2[x] ))/2;
joachim99@8 364 int g = ( qGreen( line1[x] ) + qGreen( line2[x] ))/2;
joachim99@8 365 int b = ( qBlue( line1[x] ) + qBlue( line2[x] ))/2;
joachim99@8 366 line1[x] = qRgba( r,g,b, 0xff );
joachim99@8 367 }
joachim99@8 368 }
joachim99@8 369 }
joachim99@8 370 QPixmap pix;
joachim99@8 371 pix.convertFromImage(img1);
joachim99@8 372 return pix;
joachim99@8 373 }
joachim99@8 374
joachim99@8 375 static void calcDirStatus( bool bThreeDirs, DirMergeItem* i, int& nofFiles,
joachim99@8 376 int& nofDirs, int& nofEqualFiles, int& nofManualMerges )
joachim99@8 377 {
joachim99@8 378 if ( i->m_pMFI->m_bDirA || i->m_pMFI->m_bDirB || i->m_pMFI->m_bDirC )
joachim99@8 379 {
joachim99@8 380 ++nofDirs;
joachim99@8 381 }
joachim99@8 382 else
joachim99@8 383 {
joachim99@8 384 ++nofFiles;
joachim99@8 385 if ( i->m_pMFI->m_bEqualAB && (!bThreeDirs || i->m_pMFI->m_bEqualAC ))
joachim99@8 386 {
joachim99@8 387 ++nofEqualFiles;
joachim99@8 388 }
joachim99@8 389 else
joachim99@8 390 {
joachim99@8 391 if ( i->m_pMFI->m_eMergeOperation==eMergeABCToDest || i->m_pMFI->m_eMergeOperation==eMergeABToDest )
joachim99@8 392 ++nofManualMerges;
joachim99@8 393 }
joachim99@8 394 }
joachim99@8 395 for( QListViewItem* p = i->firstChild(); p!=0; p = p->nextSibling() )
joachim99@8 396 calcDirStatus( bThreeDirs, static_cast<DirMergeItem*>(p), nofFiles, nofDirs, nofEqualFiles, nofManualMerges );
joachim99@8 397 }
joachim99@8 398
joachim99@69 399 static QString sortString(const QString& s, bool bCaseSensitive)
joachim99@58 400 {
joachim99@69 401 if (bCaseSensitive)
joachim99@69 402 return s;
joachim99@69 403 else
joachim99@69 404 return s.upper();
joachim99@58 405 }
joachim99@58 406
joachim99@8 407 bool DirectoryMergeWindow::init
joachim99@8 408 (
joachim99@8 409 FileAccess& dirA,
joachim99@8 410 FileAccess& dirB,
joachim99@8 411 FileAccess& dirC,
joachim99@8 412 FileAccess& dirDest,
joachim99@8 413 bool bDirectoryMerge
joachim99@8 414 )
joachim99@8 415 {
joachim99@66 416 if ( m_pOptions->m_bDmFullAnalysis )
joachim99@66 417 {
joachim99@68 418 // A full analysis uses the same ressources that a normal text-diff/merge uses.
joachim99@66 419 // So make sure that the user saves his data first.
joachim99@66 420 bool bCanContinue=false;
joachim99@66 421 checkIfCanContinue( &bCanContinue );
joachim99@66 422 if ( !bCanContinue )
joachim99@66 423 return false;
joachim99@68 424 startDiffMerge("","","","","","","",0); // hide main window
joachim99@66 425 }
joachim99@68 426
joachim99@66 427 show();
joachim99@66 428
joachim99@66 429 ProgressProxy pp;
joachim99@8 430 m_bFollowDirLinks = m_pOptions->m_bDmFollowDirLinks;
joachim99@8 431 m_bFollowFileLinks = m_pOptions->m_bDmFollowFileLinks;
joachim99@8 432 m_bSimulatedMergeStarted=false;
joachim99@8 433 m_bRealMergeStarted=false;
joachim99@8 434 m_bError=false;
joachim99@8 435 m_bDirectoryMerge = bDirectoryMerge;
joachim99@69 436 m_pSelection1Item = 0;
joachim99@69 437 m_pSelection2Item = 0;
joachim99@69 438 m_pSelection3Item = 0;
joachim99@69 439 m_bCaseSensitive = m_pOptions->m_bDmCaseSensitiveFilenameComparison;
joachim99@8 440
joachim99@8 441 clear();
joachim99@8 442
joachim99@53 443 m_mergeItemList.clear();
joachim99@51 444 m_currentItemForOperation = m_mergeItemList.end();
joachim99@8 445
joachim99@8 446 m_dirA = dirA;
joachim99@8 447 m_dirB = dirB;
joachim99@8 448 m_dirC = dirC;
joachim99@8 449 m_dirDest = dirDest;
joachim99@8 450
joachim99@69 451 m_pDirShowIdenticalFiles->setChecked(true);
joachim99@69 452 m_pDirShowDifferentFiles->setChecked(true);
joachim99@69 453 m_pDirShowFilesOnlyInA->setChecked(true);
joachim99@69 454 m_pDirShowFilesOnlyInB->setChecked(true);
joachim99@69 455 m_pDirShowFilesOnlyInC->setChecked(true);
joachim99@69 456
joachim99@8 457 // Check if all input directories exist and are valid. The dest dir is not tested now.
joachim99@8 458 // The test will happen only when we are going to write to it.
joachim99@8 459 if ( !m_dirA.isDir() || !m_dirB.isDir() ||
joachim99@8 460 (m_dirC.isValid() && !m_dirC.isDir()) )
joachim99@8 461 {
joachim99@8 462 QString text( i18n("Opening of directories failed:") );
joachim99@8 463 text += "\n\n";
joachim99@8 464 if ( !dirA.isDir() )
joachim99@51 465 { text += i18n("Dir A \"%1\" does not exist or is not a directory.\n").arg(m_dirA.prettyAbsPath()); }
joachim99@8 466
joachim99@8 467 if ( !dirB.isDir() )
joachim99@51 468 { text += i18n("Dir B \"%1\" does not exist or is not a directory.\n").arg(m_dirB.prettyAbsPath()); }
joachim99@8 469
joachim99@8 470 if ( m_dirC.isValid() && !m_dirC.isDir() )
joachim99@51 471 { text += i18n("Dir C \"%1\" does not exist or is not a directory.\n").arg(m_dirC.prettyAbsPath()); }
joachim99@8 472
joachim99@51 473 KMessageBox::sorry( this, text, i18n("Directory Open Error") );
joachim99@8 474 return false;
joachim99@8 475 }
joachim99@8 476
joachim99@8 477 if ( m_dirC.isValid() &&
joachim99@8 478 (m_dirDest.prettyAbsPath() == m_dirA.prettyAbsPath() || m_dirDest.prettyAbsPath()==m_dirB.prettyAbsPath() ) )
joachim99@8 479 {
joachim99@8 480 KMessageBox::error(this,
joachim99@53 481 i18n( "The destination directory must not be the same as A or B when "
joachim99@8 482 "three directories are merged.\nCheck again before continuing."),
joachim99@51 483 i18n("Parameter Warning"));
joachim99@8 484 return false;
joachim99@8 485 }
joachim99@68 486
joachim99@66 487 m_bScanning = true;
joachim99@68 488 statusBarMessage(i18n("Scanning directories..."));
joachim99@8 489
joachim99@8 490 m_bSyncMode = m_pOptions->m_bDmSyncMode && !m_dirC.isValid() && !m_dirDest.isValid();
joachim99@8 491
joachim99@8 492 if ( m_dirDest.isValid() )
joachim99@8 493 m_dirDestInternal = m_dirDest;
joachim99@8 494 else
joachim99@8 495 m_dirDestInternal = m_dirC.isValid() ? m_dirC : m_dirB;
joachim99@8 496
joachim99@8 497 QString origCurrentDirectory = QDir::currentDirPath();
joachim99@8 498
joachim99@8 499 m_fileMergeMap.clear();
joachim99@8 500 t_DirectoryList::iterator i;
joachim99@8 501
joachim99@8 502 // calc how many directories will be read:
joachim99@8 503 double nofScans = ( m_dirA.isValid() ? 1 : 0 )+( m_dirB.isValid() ? 1 : 0 )+( m_dirC.isValid() ? 1 : 0 );
joachim99@8 504 int currentScan = 0;
joachim99@8 505
joachim99@66 506 setColumnWidthMode(s_UnsolvedCol, QListView::Manual);
joachim99@66 507 setColumnWidthMode(s_SolvedCol, QListView::Manual);
joachim99@66 508 setColumnWidthMode(s_WhiteCol, QListView::Manual);
joachim99@66 509 setColumnWidthMode(s_NonWhiteCol, QListView::Manual);
joachim99@66 510 if ( !m_pOptions->m_bDmFullAnalysis )
joachim99@66 511 {
joachim99@66 512 setColumnWidth( s_WhiteCol, 0 );
joachim99@66 513 setColumnWidth( s_NonWhiteCol, 0 );
joachim99@66 514 setColumnWidth( s_UnsolvedCol, 0 );
joachim99@66 515 setColumnWidth( s_SolvedCol, 0 );
joachim99@68 516 }
joachim99@66 517 else if ( m_dirC.isValid() )
joachim99@66 518 {
joachim99@66 519 setColumnWidth(s_WhiteCol, 50 );
joachim99@66 520 setColumnWidth(s_NonWhiteCol, 50 );
joachim99@66 521 setColumnWidth(s_UnsolvedCol, 50 );
joachim99@66 522 setColumnWidth(s_SolvedCol, 50 );
joachim99@66 523 }
joachim99@66 524 else
joachim99@66 525 {
joachim99@66 526 setColumnWidth(s_WhiteCol, 50 );
joachim99@66 527 setColumnWidth(s_NonWhiteCol, 50 );
joachim99@66 528 setColumnWidth(s_UnsolvedCol, 50 );
joachim99@66 529 setColumnWidth(s_SolvedCol, 0 );
joachim99@66 530 }
joachim99@68 531
joachim99@8 532 bool bListDirSuccessA = true;
joachim99@8 533 bool bListDirSuccessB = true;
joachim99@8 534 bool bListDirSuccessC = true;
joachim99@8 535 if ( m_dirA.isValid() )
joachim99@8 536 {
joachim99@66 537 pp.setInformation(i18n("Reading Directory A"));
joachim99@66 538 pp.setSubRangeTransformation(currentScan/nofScans, (currentScan+1)/nofScans);
joachim99@8 539 ++currentScan;
joachim99@8 540
joachim99@8 541 t_DirectoryList dirListA;
joachim99@8 542 bListDirSuccessA = m_dirA.listDir( &dirListA,
joachim99@8 543 m_pOptions->m_bDmRecursiveDirs, m_pOptions->m_bDmFindHidden,
joachim99@8 544 m_pOptions->m_DmFilePattern, m_pOptions->m_DmFileAntiPattern,
joachim99@8 545 m_pOptions->m_DmDirAntiPattern, m_pOptions->m_bDmFollowDirLinks,
joachim99@8 546 m_pOptions->m_bDmUseCvsIgnore);
joachim99@8 547
joachim99@8 548 for (i=dirListA.begin(); i!=dirListA.end();++i )
joachim99@8 549 {
joachim99@69 550 MergeFileInfos& mfi = m_fileMergeMap[sortString(i->filePath(), m_bCaseSensitive)];
joachim99@8 551 //std::cout <<i->filePath()<<std::endl;
joachim99@8 552 mfi.m_bExistsInA = true;
joachim99@8 553 mfi.m_fileInfoA = *i;
joachim99@8 554 }
joachim99@8 555 }
joachim99@8 556
joachim99@8 557 if ( m_dirB.isValid() )
joachim99@8 558 {
joachim99@66 559 pp.setInformation(i18n("Reading Directory B"));
joachim99@66 560 pp.setSubRangeTransformation(currentScan/nofScans, (currentScan+1)/nofScans);
joachim99@8 561 ++currentScan;
joachim99@8 562
joachim99@8 563 t_DirectoryList dirListB;
joachim99@8 564 bListDirSuccessB = m_dirB.listDir( &dirListB,
joachim99@8 565 m_pOptions->m_bDmRecursiveDirs, m_pOptions->m_bDmFindHidden,
joachim99@8 566 m_pOptions->m_DmFilePattern, m_pOptions->m_DmFileAntiPattern,
joachim99@8 567 m_pOptions->m_DmDirAntiPattern, m_pOptions->m_bDmFollowDirLinks,
joachim99@8 568 m_pOptions->m_bDmUseCvsIgnore);
joachim99@8 569
joachim99@8 570 for (i=dirListB.begin(); i!=dirListB.end();++i )
joachim99@8 571 {
joachim99@69 572 MergeFileInfos& mfi = m_fileMergeMap[sortString(i->filePath(), m_bCaseSensitive)];
joachim99@8 573 mfi.m_bExistsInB = true;
joachim99@8 574 mfi.m_fileInfoB = *i;
joachim99@8 575 }
joachim99@8 576 }
joachim99@8 577
joachim99@8 578 e_MergeOperation eDefaultMergeOp;
joachim99@8 579 if ( m_dirC.isValid() )
joachim99@8 580 {
joachim99@66 581 pp.setInformation(i18n("Reading Directory C"));
joachim99@66 582 pp.setSubRangeTransformation(currentScan/nofScans, (currentScan+1)/nofScans);
joachim99@8 583 ++currentScan;
joachim99@8 584
joachim99@8 585 t_DirectoryList dirListC;
joachim99@8 586 bListDirSuccessC = m_dirC.listDir( &dirListC,
joachim99@8 587 m_pOptions->m_bDmRecursiveDirs, m_pOptions->m_bDmFindHidden,
joachim99@8 588 m_pOptions->m_DmFilePattern, m_pOptions->m_DmFileAntiPattern,
joachim99@8 589 m_pOptions->m_DmDirAntiPattern, m_pOptions->m_bDmFollowDirLinks,
joachim99@8 590 m_pOptions->m_bDmUseCvsIgnore);
joachim99@8 591
joachim99@8 592 for (i=dirListC.begin(); i!=dirListC.end();++i )
joachim99@8 593 {
joachim99@69 594 MergeFileInfos& mfi = m_fileMergeMap[sortString(i->filePath(),m_bCaseSensitive)];
joachim99@8 595 mfi.m_bExistsInC = true;
joachim99@8 596 mfi.m_fileInfoC = *i;
joachim99@8 597 }
joachim99@8 598
joachim99@8 599 eDefaultMergeOp = eMergeABCToDest;
joachim99@8 600 }
joachim99@8 601 else
joachim99@8 602 eDefaultMergeOp = m_bSyncMode ? eMergeToAB : eMergeABToDest;
joachim99@8 603
joachim99@8 604 bool bContinue = true;
joachim99@8 605 if ( !bListDirSuccessA || !bListDirSuccessB || !bListDirSuccessC )
joachim99@8 606 {
joachim99@8 607 QString s = i18n("Some subdirectories were not readable in");
joachim99@8 608 if ( !bListDirSuccessA ) s += "\nA: " + m_dirA.prettyAbsPath();
joachim99@8 609 if ( !bListDirSuccessB ) s += "\nB: " + m_dirB.prettyAbsPath();
joachim99@8 610 if ( !bListDirSuccessC ) s += "\nC: " + m_dirC.prettyAbsPath();
joachim99@8 611 s+="\n";
joachim99@8 612 s+= i18n("Check the permissions of the subdirectories.");
joachim99@8 613 bContinue = KMessageBox::Continue == KMessageBox::warningContinueCancel( this, s );
joachim99@8 614 }
joachim99@8 615
joachim99@8 616 if ( bContinue )
joachim99@8 617 {
joachim99@66 618 prepareListView(pp);
joachim99@8 619
joachim99@8 620 for( QListViewItem* p = firstChild(); p!=0; p = p->nextSibling() )
joachim99@8 621 {
joachim99@8 622 DirMergeItem* pDMI = static_cast<DirMergeItem*>( p );
joachim99@8 623 calcSuggestedOperation( *pDMI->m_pMFI, eDefaultMergeOp );
joachim99@8 624 }
joachim99@8 625 }
joachim99@8 626 else
joachim99@8 627 {
joachim99@8 628 setSelected( 0, true );
joachim99@8 629 }
joachim99@8 630
joachim99@8 631 QDir::setCurrent(origCurrentDirectory);
joachim99@8 632
joachim99@8 633 // Try to improve the view a little bit.
joachim99@8 634 QWidget* pParent = parentWidget();
joachim99@8 635 QSplitter* pSplitter = static_cast<QSplitter*>(pParent);
joachim99@8 636 if (pSplitter!=0)
joachim99@8 637 {
joachim99@8 638 QValueList<int> sizes = pSplitter->sizes();
joachim99@8 639 int total = sizes[0] + sizes[1];
joachim99@8 640 sizes[0]=total*6/10;
joachim99@8 641 sizes[1]=total - sizes[0];
joachim99@8 642 pSplitter->setSizes( sizes );
joachim99@8 643 }
joachim99@68 644
joachim99@66 645 m_bScanning = false;
joachim99@66 646 statusBarMessage(i18n("Ready."));
joachim99@8 647
joachim99@8 648 if ( bContinue )
joachim99@8 649 {
joachim99@8 650 // Generate a status report
joachim99@8 651 int nofFiles=0;
joachim99@8 652 int nofDirs=0;
joachim99@8 653 int nofEqualFiles=0;
joachim99@8 654 int nofManualMerges=0;
joachim99@8 655 for( QListViewItem* p = firstChild(); p!=0; p = p->nextSibling() )
joachim99@8 656 calcDirStatus( m_dirC.isValid(), static_cast<DirMergeItem*>(p),
joachim99@8 657 nofFiles, nofDirs, nofEqualFiles, nofManualMerges );
joachim99@8 658
joachim99@8 659 QString s;
joachim99@51 660 s = i18n("Directory Comparison Status") + "\n\n" +
joachim99@8 661 i18n("Number of subdirectories:") +" "+ QString::number(nofDirs) + "\n"+
joachim99@8 662 i18n("Number of equal files:") +" "+ QString::number(nofEqualFiles) + "\n"+
joachim99@8 663 i18n("Number of different files:") +" "+ QString::number(nofFiles-nofEqualFiles);
joachim99@8 664
joachim99@8 665 if ( m_dirC.isValid() )
joachim99@8 666 s += "\n" + i18n("Number of manual merges:") +" "+ QString::number(nofManualMerges);
joachim99@8 667 KMessageBox::information( this, s );
joachim99@8 668 setSelected( firstChild(), true );
joachim99@8 669 }
joachim99@68 670
joachim99@8 671 return true;
joachim99@8 672 }
joachim99@8 673
joachim99@8 674
joachim99@8 675
joachim99@8 676 void DirectoryMergeWindow::slotChooseAEverywhere(){ setAllMergeOperations( eCopyAToDest ); }
joachim99@8 677
joachim99@8 678 void DirectoryMergeWindow::slotChooseBEverywhere(){ setAllMergeOperations( eCopyBToDest ); }
joachim99@8 679
joachim99@8 680 void DirectoryMergeWindow::slotChooseCEverywhere(){ setAllMergeOperations( eCopyCToDest ); }
joachim99@8 681
joachim99@8 682 void DirectoryMergeWindow::slotAutoChooseEverywhere()
joachim99@8 683 {
joachim99@8 684 e_MergeOperation eDefaultMergeOp = m_dirC.isValid() ? eMergeABCToDest :
joachim99@8 685 m_bSyncMode ? eMergeToAB : eMergeABToDest;
joachim99@8 686 setAllMergeOperations(eDefaultMergeOp );
joachim99@8 687 }
joachim99@8 688
joachim99@8 689 void DirectoryMergeWindow::slotNoOpEverywhere(){ setAllMergeOperations(eNoOperation); }
joachim99@8 690
joachim99@8 691 static void setListViewItemOpen( QListViewItem* p, bool bOpen )
joachim99@8 692 {
joachim99@8 693 for( QListViewItem* pChild = p->firstChild(); pChild!=0; pChild = pChild->nextSibling() )
joachim99@8 694 setListViewItemOpen( pChild, bOpen );
joachim99@8 695
joachim99@8 696 p->setOpen( bOpen );
joachim99@8 697 }
joachim99@8 698
joachim99@8 699 void DirectoryMergeWindow::slotFoldAllSubdirs()
joachim99@8 700 {
joachim99@8 701 for( QListViewItem* p = firstChild(); p!=0; p = p->nextSibling() )
joachim99@8 702 setListViewItemOpen( p, false );
joachim99@8 703 }
joachim99@8 704
joachim99@8 705 void DirectoryMergeWindow::slotUnfoldAllSubdirs()
joachim99@8 706 {
joachim99@8 707 for( QListViewItem* p = firstChild(); p!=0; p = p->nextSibling() )
joachim99@8 708 setListViewItemOpen( p, true );
joachim99@8 709 }
joachim99@8 710
joachim99@51 711 static void setMergeOperation( QListViewItem* pLVI, e_MergeOperation eMergeOp )
joachim99@51 712 {
joachim99@51 713 if ( pLVI==0 ) return;
joachim99@51 714
joachim99@51 715 DirMergeItem* pDMI = static_cast<DirMergeItem*>(pLVI);
joachim99@51 716 MergeFileInfos& mfi = *pDMI->m_pMFI;
joachim99@51 717
joachim99@51 718 mfi.setMergeOperation(eMergeOp );
joachim99@51 719 }
joachim99@51 720
joachim99@51 721 // Merge current item (merge mode)
joachim99@51 722 void DirectoryMergeWindow::slotCurrentDoNothing() { setMergeOperation(currentItem(), eNoOperation ); }
joachim99@53 723 void DirectoryMergeWindow::slotCurrentChooseA() { setMergeOperation(currentItem(), m_bSyncMode ? eCopyAToB : eCopyAToDest ); }
joachim99@53 724 void DirectoryMergeWindow::slotCurrentChooseB() { setMergeOperation(currentItem(), m_bSyncMode ? eCopyBToA : eCopyBToDest ); }
joachim99@51 725 void DirectoryMergeWindow::slotCurrentChooseC() { setMergeOperation(currentItem(), eCopyCToDest ); }
joachim99@51 726 void DirectoryMergeWindow::slotCurrentMerge()
joachim99@51 727 {
joachim99@51 728 bool bThreeDirs = m_dirC.isValid();
joachim99@51 729 setMergeOperation(currentItem(), bThreeDirs ? eMergeABCToDest : eMergeABToDest );
joachim99@51 730 }
joachim99@51 731 void DirectoryMergeWindow::slotCurrentDelete() { setMergeOperation(currentItem(), eDeleteFromDest ); }
joachim99@51 732 // Sync current item
joachim99@51 733 void DirectoryMergeWindow::slotCurrentCopyAToB() { setMergeOperation(currentItem(), eCopyAToB ); }
joachim99@51 734 void DirectoryMergeWindow::slotCurrentCopyBToA() { setMergeOperation(currentItem(), eCopyBToA ); }
joachim99@51 735 void DirectoryMergeWindow::slotCurrentDeleteA() { setMergeOperation(currentItem(), eDeleteA ); }
joachim99@51 736 void DirectoryMergeWindow::slotCurrentDeleteB() { setMergeOperation(currentItem(), eDeleteB ); }
joachim99@51 737 void DirectoryMergeWindow::slotCurrentDeleteAAndB() { setMergeOperation(currentItem(), eDeleteAB ); }
joachim99@51 738 void DirectoryMergeWindow::slotCurrentMergeToA() { setMergeOperation(currentItem(), eMergeToA ); }
joachim99@51 739 void DirectoryMergeWindow::slotCurrentMergeToB() { setMergeOperation(currentItem(), eMergeToB ); }
joachim99@51 740 void DirectoryMergeWindow::slotCurrentMergeToAAndB() { setMergeOperation(currentItem(), eMergeToAB ); }
joachim99@51 741
joachim99@51 742
joachim99@51 743 void DirectoryMergeWindow::keyPressEvent( QKeyEvent* e )
joachim99@51 744 {
joachim99@51 745 if ( (e->state() & Qt::ControlButton)!=0 )
joachim99@51 746 {
joachim99@51 747 bool bThreeDirs = m_dirC.isValid();
joachim99@51 748
joachim99@51 749 QListViewItem* lvi = currentItem();
joachim99@51 750 DirMergeItem* pDMI = lvi==0 ? 0 : static_cast<DirMergeItem*>(lvi);
joachim99@51 751 MergeFileInfos* pMFI = pDMI==0 ? 0 : pDMI->m_pMFI;
joachim99@51 752
joachim99@51 753 if ( pMFI==0 ) return;
joachim99@51 754 bool bMergeMode = bThreeDirs || !m_bSyncMode;
joachim99@51 755 bool bFTConflict = pMFI==0 ? false : conflictingFileTypes(*pMFI);
joachim99@51 756
joachim99@51 757 if ( bMergeMode )
joachim99@51 758 {
joachim99@51 759 switch(e->key())
joachim99@51 760 {
joachim99@51 761 case Key_1: if(pMFI->m_bExistsInA){ slotCurrentChooseA(); } return;
joachim99@51 762 case Key_2: if(pMFI->m_bExistsInB){ slotCurrentChooseB(); } return;
joachim99@51 763 case Key_3: if(pMFI->m_bExistsInC){ slotCurrentChooseC(); } return;
joachim99@51 764 case Key_Space: slotCurrentDoNothing(); return;
joachim99@51 765 case Key_4: if ( !bFTConflict ) { slotCurrentMerge(); } return;
joachim99@51 766 case Key_Delete: slotCurrentDelete(); return;
joachim99@51 767 default: break;
joachim99@51 768 }
joachim99@51 769 }
joachim99@51 770 else
joachim99@51 771 {
joachim99@51 772 switch(e->key())
joachim99@51 773 {
joachim99@51 774 case Key_1: if(pMFI->m_bExistsInA){ slotCurrentCopyAToB(); } return;
joachim99@51 775 case Key_2: if(pMFI->m_bExistsInB){ slotCurrentCopyBToA(); } return;
joachim99@51 776 case Key_Space: slotCurrentDoNothing(); return;
joachim99@51 777 case Key_4: if ( !bFTConflict ) { slotCurrentMergeToAAndB(); } return;
joachim99@51 778 case Key_Delete: if( pMFI->m_bExistsInA && pMFI->m_bExistsInB ) slotCurrentDeleteAAndB();
joachim99@51 779 else if( pMFI->m_bExistsInA ) slotCurrentDeleteA();
joachim99@51 780 else if( pMFI->m_bExistsInB ) slotCurrentDeleteB();
joachim99@51 781 return;
joachim99@51 782 default: break;
joachim99@51 783 }
joachim99@51 784 }
joachim99@51 785 }
joachim99@51 786
joachim99@51 787 QListView::keyPressEvent(e);
joachim99@51 788 }
joachim99@51 789
joachim99@53 790 void DirectoryMergeWindow::focusInEvent(QFocusEvent*)
joachim99@53 791 {
joachim99@53 792 updateAvailabilities();
joachim99@53 793 }
joachim99@53 794 void DirectoryMergeWindow::focusOutEvent(QFocusEvent*)
joachim99@53 795 {
joachim99@53 796 updateAvailabilities();
joachim99@53 797 }
joachim99@51 798
joachim99@8 799 void DirectoryMergeWindow::setAllMergeOperations( e_MergeOperation eDefaultOperation )
joachim99@8 800 {
joachim99@8 801 if ( KMessageBox::Yes == KMessageBox::warningYesNo(this,
joachim99@8 802 i18n("This affects all merge operations."),
joachim99@51 803 i18n("Changing All Merge Operations"),i18n("C&ontinue"), i18n("&Cancel") ) )
joachim99@8 804 {
joachim99@8 805 for( QListViewItem* p = firstChild(); p!=0; p = p->nextSibling() )
joachim99@8 806 {
joachim99@8 807 DirMergeItem* pDMI = static_cast<DirMergeItem*>( p );
joachim99@8 808 calcSuggestedOperation( *pDMI->m_pMFI, eDefaultOperation );
joachim99@8 809 }
joachim99@8 810 }
joachim99@8 811 }
joachim99@8 812
joachim99@8 813
joachim99@8 814 void DirectoryMergeWindow::compareFilesAndCalcAges( MergeFileInfos& mfi )
joachim99@8 815 {
joachim99@8 816 std::map<QDateTime,int> dateMap;
joachim99@8 817
joachim99@8 818 if( mfi.m_bExistsInA )
joachim99@8 819 {
joachim99@8 820 mfi.m_bLinkA = mfi.m_fileInfoA.isSymLink();
joachim99@8 821 mfi.m_bDirA = mfi.m_fileInfoA.isDir();
joachim99@8 822 dateMap[ mfi.m_fileInfoA.lastModified() ] = 0;
joachim99@8 823 }
joachim99@8 824 if( mfi.m_bExistsInB )
joachim99@8 825 {
joachim99@8 826 mfi.m_bLinkB = mfi.m_fileInfoB.isSymLink();
joachim99@8 827 mfi.m_bDirB = mfi.m_fileInfoB.isDir();
joachim99@8 828 dateMap[ mfi.m_fileInfoB.lastModified() ] = 1;
joachim99@8 829 }
joachim99@8 830 if( mfi.m_bExistsInC )
joachim99@8 831 {
joachim99@8 832 mfi.m_bLinkC = mfi.m_fileInfoC.isSymLink();
joachim99@8 833 mfi.m_bDirC = mfi.m_fileInfoC.isDir();
joachim99@8 834 dateMap[ mfi.m_fileInfoC.lastModified() ] = 2;
joachim99@8 835 }
joachim99@8 836
joachim99@66 837 if ( m_pOptions->m_bDmFullAnalysis )
joachim99@8 838 {
joachim99@66 839 if( mfi.m_bExistsInA && mfi.m_bDirA || mfi.m_bExistsInB && mfi.m_bDirB || mfi.m_bExistsInC && mfi.m_bDirC )
joachim99@66 840 {
joachim99@66 841 // If any input is a directory, don't start any comparison.
joachim99@66 842 mfi.m_bEqualAB=mfi.m_bExistsInA && mfi.m_bExistsInB;
joachim99@66 843 mfi.m_bEqualAC=mfi.m_bExistsInA && mfi.m_bExistsInC;
joachim99@66 844 mfi.m_bEqualBC=mfi.m_bExistsInB && mfi.m_bExistsInC;
joachim99@66 845 }
joachim99@8 846 else
joachim99@8 847 {
joachim99@66 848 emit startDiffMerge(
joachim99@66 849 mfi.m_bExistsInA ? mfi.m_fileInfoA.absFilePath() : QString(""),
joachim99@66 850 mfi.m_bExistsInB ? mfi.m_fileInfoB.absFilePath() : QString(""),
joachim99@66 851 mfi.m_bExistsInC ? mfi.m_fileInfoC.absFilePath() : QString(""),
joachim99@66 852 "",
joachim99@66 853 "","","",&mfi.m_totalDiffStatus
joachim99@66 854 );
joachim99@68 855 int nofNonwhiteConflicts = mfi.m_totalDiffStatus.nofUnsolvedConflicts +
joachim99@68 856 mfi.m_totalDiffStatus.nofSolvedConflicts - mfi.m_totalDiffStatus.nofWhitespaceConflicts;
joachim99@68 857
joachim99@68 858 if (m_pOptions->m_bDmWhiteSpaceEqual && nofNonwhiteConflicts == 0)
joachim99@68 859 {
joachim99@68 860 mfi.m_bEqualAB = mfi.m_bEqualBC = mfi.m_bEqualAC = true;
joachim99@68 861 }
joachim99@68 862 else
joachim99@68 863 {
joachim99@68 864 mfi.m_bEqualAB = mfi.m_totalDiffStatus.bBinaryAEqB;
joachim99@68 865 mfi.m_bEqualBC = mfi.m_totalDiffStatus.bBinaryBEqC;
joachim99@68 866 mfi.m_bEqualAC = mfi.m_totalDiffStatus.bBinaryAEqC;
joachim99@68 867 }
joachim99@66 868 }
joachim99@66 869 }
joachim99@66 870 else
joachim99@68 871 {
joachim99@66 872 bool bError;
joachim99@66 873 QString eqStatus;
joachim99@66 874 if( mfi.m_bExistsInA && mfi.m_bExistsInB )
joachim99@66 875 {
joachim99@66 876 if( mfi.m_bDirA ) mfi.m_bEqualAB=true;
joachim99@66 877 else fastFileComparison( mfi.m_fileInfoA, mfi.m_fileInfoB, mfi.m_bEqualAB, bError, eqStatus );
joachim99@66 878 }
joachim99@66 879 if( mfi.m_bExistsInA && mfi.m_bExistsInC )
joachim99@66 880 {
joachim99@66 881 if( mfi.m_bDirA ) mfi.m_bEqualAC=true;
joachim99@66 882 else fastFileComparison( mfi.m_fileInfoA, mfi.m_fileInfoC, mfi.m_bEqualAC, bError, eqStatus );
joachim99@66 883 }
joachim99@66 884 if( mfi.m_bExistsInB && mfi.m_bExistsInC )
joachim99@66 885 {
joachim99@66 886 if (mfi.m_bEqualAB && mfi.m_bEqualAC)
joachim99@66 887 mfi.m_bEqualBC = true;
joachim99@66 888 else
joachim99@66 889 {
joachim99@66 890 if( mfi.m_bDirB ) mfi.m_bEqualBC=true;
joachim99@66 891 else fastFileComparison( mfi.m_fileInfoB, mfi.m_fileInfoC, mfi.m_bEqualBC, bError, eqStatus );
joachim99@66 892 }
joachim99@8 893 }
joachim99@8 894 }
joachim99@8 895
joachim99@8 896 if (mfi.m_bLinkA!=mfi.m_bLinkB) mfi.m_bEqualAB=false;
joachim99@8 897 if (mfi.m_bLinkA!=mfi.m_bLinkC) mfi.m_bEqualAC=false;
joachim99@8 898 if (mfi.m_bLinkB!=mfi.m_bLinkC) mfi.m_bEqualBC=false;
joachim99@8 899
joachim99@8 900 if (mfi.m_bDirA!=mfi.m_bDirB) mfi.m_bEqualAB=false;
joachim99@8 901 if (mfi.m_bDirA!=mfi.m_bDirC) mfi.m_bEqualAC=false;
joachim99@8 902 if (mfi.m_bDirB!=mfi.m_bDirC) mfi.m_bEqualBC=false;
joachim99@8 903
joachim99@8 904 assert(eNew==0 && eMiddle==1 && eOld==2);
joachim99@8 905
joachim99@8 906 // The map automatically sorts the keys.
joachim99@8 907 int age = eNew;
joachim99@8 908 std::map<QDateTime,int>::reverse_iterator i;
joachim99@8 909 for( i=dateMap.rbegin(); i!=dateMap.rend(); ++i )
joachim99@8 910 {
joachim99@8 911 int n = i->second;
joachim99@8 912 if ( n==0 && mfi.m_ageA==eNotThere )
joachim99@8 913 {
joachim99@8 914 mfi.m_ageA = (e_Age)age; ++age;
joachim99@8 915 if ( mfi.m_bEqualAB ) { mfi.m_ageB = mfi.m_ageA; ++age; }
joachim99@8 916 if ( mfi.m_bEqualAC ) { mfi.m_ageC = mfi.m_ageA; ++age; }
joachim99@8 917 }
joachim99@8 918 else if ( n==1 && mfi.m_ageB==eNotThere )
joachim99@8 919 {
joachim99@8 920 mfi.m_ageB = (e_Age)age; ++age;
joachim99@8 921 if ( mfi.m_bEqualAB ) { mfi.m_ageA = mfi.m_ageB; ++age; }
joachim99@8 922 if ( mfi.m_bEqualBC ) { mfi.m_ageC = mfi.m_ageB; ++age; }
joachim99@8 923 }
joachim99@8 924 else if ( n==2 && mfi.m_ageC==eNotThere)
joachim99@8 925 {
joachim99@8 926 mfi.m_ageC = (e_Age)age; ++age;
joachim99@8 927 if ( mfi.m_bEqualAC ) { mfi.m_ageA = mfi.m_ageC; ++age; }
joachim99@8 928 if ( mfi.m_bEqualBC ) { mfi.m_ageB = mfi.m_ageC; ++age; }
joachim99@8 929 }
joachim99@8 930 }
joachim99@8 931
joachim99@8 932 // The checks below are necessary when the dates of the file are equal but the
joachim99@8 933 // files are not. One wouldn't expect this to happen, yet it happens sometimes.
joachim99@8 934 if ( mfi.m_bExistsInC && mfi.m_ageC==eNotThere )
joachim99@8 935 {
joachim99@8 936 mfi.m_ageC = (e_Age)age; ++age;
joachim99@8 937 mfi.m_bConflictingAges = true;
joachim99@8 938 }
joachim99@8 939 if ( mfi.m_bExistsInB && mfi.m_ageB==eNotThere )
joachim99@8 940 {
joachim99@8 941 mfi.m_ageB = (e_Age)age; ++age;
joachim99@8 942 mfi.m_bConflictingAges = true;
joachim99@8 943 }
joachim99@8 944 if ( mfi.m_bExistsInA && mfi.m_ageA==eNotThere )
joachim99@8 945 {
joachim99@8 946 mfi.m_ageA = (e_Age)age; ++age;
joachim99@8 947 mfi.m_bConflictingAges = true;
joachim99@8 948 }
joachim99@8 949
joachim99@8 950 if ( mfi.m_ageA != eOld && mfi.m_ageB != eOld && mfi.m_ageC != eOld )
joachim99@8 951 {
joachim99@8 952 if (mfi.m_ageA == eMiddle) mfi.m_ageA = eOld;
joachim99@8 953 if (mfi.m_ageB == eMiddle) mfi.m_ageB = eOld;
joachim99@8 954 if (mfi.m_ageC == eMiddle) mfi.m_ageC = eOld;
joachim99@8 955 }
joachim99@8 956 }
joachim99@8 957
joachim99@8 958 static QPixmap* s_pm_dir;
joachim99@8 959 static QPixmap* s_pm_file;
joachim99@8 960
joachim99@69 961 static QPixmap* pmNotThere;
joachim99@69 962 static QPixmap* pmNew;
joachim99@69 963 static QPixmap* pmOld;
joachim99@69 964 static QPixmap* pmMiddle;
joachim99@69 965
joachim99@69 966 static QPixmap* pmLink;
joachim99@69 967
joachim99@69 968 static QPixmap* pmDirLink;
joachim99@69 969 static QPixmap* pmFileLink;
joachim99@69 970
joachim99@69 971 static QPixmap* pmNewLink;
joachim99@69 972 static QPixmap* pmOldLink;
joachim99@69 973 static QPixmap* pmMiddleLink;
joachim99@69 974
joachim99@69 975 static QPixmap* pmNewDir;
joachim99@69 976 static QPixmap* pmMiddleDir;
joachim99@69 977 static QPixmap* pmOldDir;
joachim99@69 978
joachim99@69 979 static QPixmap* pmNewDirLink;
joachim99@69 980 static QPixmap* pmMiddleDirLink;
joachim99@69 981 static QPixmap* pmOldDirLink;
joachim99@69 982
joachim99@69 983
joachim99@69 984 static QPixmap colorToPixmap(QColor c)
joachim99@69 985 {
joachim99@69 986 QPixmap pm(16,16);
joachim99@69 987 QPainter p(&pm);
joachim99@69 988 p.setPen( Qt::black );
joachim99@69 989 p.setBrush( c );
joachim99@69 990 p.drawRect(0,0,pm.width(),pm.height());
joachim99@69 991 return pm;
joachim99@69 992 }
joachim99@69 993
joachim99@69 994 static void initPixmaps( QColor newest, QColor oldest, QColor middle, QColor notThere )
joachim99@69 995 {
joachim99@69 996 if (pmNew==0)
joachim99@69 997 {
joachim99@69 998 pmNotThere = new QPixmap;
joachim99@69 999 pmNew = new QPixmap;
joachim99@69 1000 pmOld = new QPixmap;
joachim99@69 1001 pmMiddle = new QPixmap;
joachim99@69 1002
joachim99@69 1003 #include "xpm/link_arrow.xpm"
joachim99@69 1004 pmLink = new QPixmap(link_arrow);
joachim99@69 1005
joachim99@69 1006 pmDirLink = new QPixmap;
joachim99@69 1007 pmFileLink = new QPixmap;
joachim99@69 1008
joachim99@69 1009 pmNewLink = new QPixmap;
joachim99@69 1010 pmOldLink = new QPixmap;
joachim99@69 1011 pmMiddleLink = new QPixmap;
joachim99@69 1012
joachim99@69 1013 pmNewDir = new QPixmap;
joachim99@69 1014 pmMiddleDir = new QPixmap;
joachim99@69 1015 pmOldDir = new QPixmap;
joachim99@69 1016
joachim99@69 1017 pmNewDirLink = new QPixmap;
joachim99@69 1018 pmMiddleDirLink = new QPixmap;
joachim99@69 1019 pmOldDirLink = new QPixmap;
joachim99@69 1020 }
joachim99@69 1021
joachim99@69 1022
joachim99@69 1023 *pmNotThere = colorToPixmap(notThere);
joachim99@69 1024 *pmNew = colorToPixmap(newest);
joachim99@69 1025 *pmOld = colorToPixmap(oldest);
joachim99@69 1026 *pmMiddle = colorToPixmap(middle);
joachim99@69 1027
joachim99@69 1028 *pmDirLink = pixCombiner( s_pm_dir, pmLink);
joachim99@69 1029 *pmFileLink = pixCombiner( s_pm_file, pmLink );
joachim99@69 1030
joachim99@69 1031 *pmNewLink = pixCombiner( pmNew, pmLink);
joachim99@69 1032 *pmOldLink = pixCombiner( pmOld, pmLink);
joachim99@69 1033 *pmMiddleLink = pixCombiner( pmMiddle, pmLink);
joachim99@69 1034
joachim99@69 1035 *pmNewDir = pixCombiner2( pmNew, s_pm_dir);
joachim99@69 1036 *pmMiddleDir = pixCombiner2( pmMiddle, s_pm_dir);
joachim99@69 1037 *pmOldDir = pixCombiner2( pmOld, s_pm_dir);
joachim99@69 1038
joachim99@69 1039 *pmNewDirLink = pixCombiner( pmNewDir, pmLink);
joachim99@69 1040 *pmMiddleDirLink = pixCombiner( pmMiddleDir, pmLink);
joachim99@69 1041 *pmOldDirLink = pixCombiner( pmOldDir, pmLink);
joachim99@69 1042 }
joachim99@69 1043
joachim99@69 1044
joachim99@8 1045 static void setOnePixmap( QListViewItem* pLVI, int col, e_Age eAge, bool bLink, bool bDir )
joachim99@8 1046 {
joachim99@69 1047 static QPixmap* ageToPm[]= { pmNew, pmMiddle, pmOld, pmNotThere, s_pm_file };
joachim99@69 1048 static QPixmap* ageToPmLink[]= { pmNewLink, pmMiddleLink, pmOldLink, pmNotThere, pmFileLink };
joachim99@69 1049 static QPixmap* ageToPmDir[]= { pmNewDir, pmMiddleDir, pmOldDir, pmNotThere, s_pm_dir };
joachim99@69 1050 static QPixmap* ageToPmDirLink[]={ pmNewDirLink, pmMiddleDirLink, pmOldDirLink, pmNotThere, pmDirLink };
joachim99@8 1051
joachim99@8 1052 QPixmap** ppPm = bDir ? ( bLink ? ageToPmDirLink : ageToPmDir ):
joachim99@8 1053 ( bLink ? ageToPmLink : ageToPm );
joachim99@8 1054
joachim99@8 1055 pLVI->setPixmap( col, *ppPm[eAge] );
joachim99@8 1056 }
joachim99@8 1057
joachim99@8 1058 static void setPixmaps( MergeFileInfos& mfi, bool bCheckC )
joachim99@8 1059 {
joachim99@8 1060 setOnePixmap( mfi.m_pDMI, s_nameCol, eAgeEnd,
joachim99@8 1061 mfi.m_bLinkA || mfi.m_bLinkB || mfi.m_bLinkC,
joachim99@8 1062 mfi.m_bDirA || mfi.m_bDirB || mfi.m_bDirC
joachim99@8 1063 );
joachim99@8 1064
joachim99@8 1065 if ( mfi.m_bDirA || mfi.m_bDirB || mfi.m_bDirC )
joachim99@8 1066 {
joachim99@8 1067 mfi.m_ageA=eNotThere;
joachim99@8 1068 mfi.m_ageB=eNotThere;
joachim99@8 1069 mfi.m_ageC=eNotThere;
joachim99@8 1070 int age = eNew;
joachim99@8 1071 if ( mfi.m_bExistsInC )
joachim99@8 1072 {
joachim99@8 1073 mfi.m_ageC = (e_Age)age;
joachim99@8 1074 if (mfi.m_bEqualAC) mfi.m_ageA = (e_Age)age;
joachim99@8 1075 if (mfi.m_bEqualBC) mfi.m_ageB = (e_Age)age;
joachim99@8 1076 ++age;
joachim99@8 1077 }
joachim99@8 1078 if ( mfi.m_bExistsInB && mfi.m_ageB==eNotThere )
joachim99@8 1079 {
joachim99@8 1080 mfi.m_ageB = (e_Age)age;
joachim99@8 1081 if (mfi.m_bEqualAB) mfi.m_ageA = (e_Age)age;
joachim99@8 1082 ++age;
joachim99@8 1083 }
joachim99@8 1084 if ( mfi.m_bExistsInA && mfi.m_ageA==eNotThere )
joachim99@8 1085 {
joachim99@8 1086 mfi.m_ageA = (e_Age)age;
joachim99@8 1087 }
joachim99@8 1088 if ( mfi.m_ageA != eOld && mfi.m_ageB != eOld && mfi.m_ageC != eOld )
joachim99@8 1089 {
joachim99@8 1090 if (mfi.m_ageA == eMiddle) mfi.m_ageA = eOld;
joachim99@8 1091 if (mfi.m_ageB == eMiddle) mfi.m_ageB = eOld;
joachim99@8 1092 if (mfi.m_ageC == eMiddle) mfi.m_ageC = eOld;
joachim99@8 1093 }
joachim99@8 1094 }
joachim99@8 1095
joachim99@8 1096 setOnePixmap( mfi.m_pDMI, s_ACol, mfi.m_ageA, mfi.m_bLinkA, mfi.m_bDirA );
joachim99@8 1097 setOnePixmap( mfi.m_pDMI, s_BCol, mfi.m_ageB, mfi.m_bLinkB, mfi.m_bDirB );
joachim99@8 1098 if ( bCheckC )
joachim99@8 1099 setOnePixmap( mfi.m_pDMI, s_CCol, mfi.m_ageC, mfi.m_bLinkC, mfi.m_bDirC );
joachim99@8 1100 }
joachim99@8 1101
joachim99@8 1102 // Iterate through the complete tree. Start by specifying QListView::firstChild().
joachim99@69 1103 static QListViewItem* treeIterator( QListViewItem* p, bool bVisitChildren=true, bool bFindInvisible=false )
joachim99@8 1104 {
joachim99@8 1105 if( p!=0 )
joachim99@8 1106 {
joachim99@69 1107 do
joachim99@8 1108 {
joachim99@69 1109 if ( bVisitChildren && p->firstChild() != 0 ) p = p->firstChild();
joachim99@69 1110 else if ( p->nextSibling() !=0 ) p = p->nextSibling();
joachim99@69 1111 else
joachim99@8 1112 {
joachim99@69 1113 p = p->parent();
joachim99@69 1114 while ( p!=0 )
joachim99@69 1115 {
joachim99@69 1116 if( p->nextSibling()!=0 ) { p = p->nextSibling(); break; }
joachim99@69 1117 else { p = p->parent(); }
joachim99@69 1118 }
joachim99@8 1119 }
joachim99@8 1120 }
joachim99@69 1121 while( p && !(p->isVisible() || bFindInvisible) );
joachim99@8 1122 }
joachim99@8 1123 return p;
joachim99@8 1124 }
joachim99@8 1125
joachim99@66 1126 void DirectoryMergeWindow::prepareListView( ProgressProxy& pp )
joachim99@8 1127 {
joachim99@8 1128 static bool bFirstTime = true;
joachim99@8 1129 if (bFirstTime)
joachim99@8 1130 {
joachim99@8 1131 #include "xpm/file.xpm"
joachim99@8 1132 #include "xpm/folder.xpm"
joachim99@8 1133 s_pm_dir = new QPixmap( m_pIconLoader->loadIcon("folder", KIcon::Small ) );
joachim99@8 1134 if (s_pm_dir->size()!=QSize(16,16))
joachim99@8 1135 {
joachim99@8 1136 delete s_pm_dir;
joachim99@8 1137 s_pm_dir = new QPixmap( folder_pm );
joachim99@8 1138 }
joachim99@8 1139 s_pm_file= new QPixmap( file_pm );
joachim99@8 1140 bFirstTime=false;
joachim99@8 1141 }
joachim99@8 1142
joachim99@8 1143 clear();
joachim99@69 1144 initPixmaps( m_pOptions->m_newestFileColor, m_pOptions->m_oldestFileColor,
joachim99@69 1145 m_pOptions->m_midAgeFileColor, m_pOptions->m_missingFileColor );
joachim99@8 1146
joachim99@8 1147 setRootIsDecorated( true );
joachim99@8 1148
joachim99@8 1149 bool bCheckC = m_dirC.isValid();
joachim99@8 1150
joachim99@8 1151 std::map<QString, MergeFileInfos>::iterator j;
joachim99@8 1152 int nrOfFiles = m_fileMergeMap.size();
joachim99@8 1153 int currentIdx = 1;
joachim99@8 1154 QTime t;
joachim99@8 1155 t.start();
joachim99@8 1156 for( j=m_fileMergeMap.begin(); j!=m_fileMergeMap.end(); ++j )
joachim99@8 1157 {
joachim99@8 1158 MergeFileInfos& mfi = j->second;
joachim99@8 1159
joachim99@8 1160 mfi.m_subPath = mfi.m_fileInfoA.exists() ? mfi.m_fileInfoA.filePath() :
joachim99@8 1161 mfi.m_fileInfoB.exists() ? mfi.m_fileInfoB.filePath() :
joachim99@25 1162 mfi.m_fileInfoC.exists() ? mfi.m_fileInfoC.filePath() :
joachim99@25 1163 QString("");
joachim99@8 1164
joachim99@58 1165 // const QString& fileName = j->first;
joachim99@58 1166 const QString& fileName = mfi.m_subPath;
joachim99@58 1167
joachim99@66 1168 pp.setInformation(
joachim99@51 1169 i18n("Processing ") + QString::number(currentIdx) +" / "+ QString::number(nrOfFiles)
joachim99@8 1170 +"\n" + fileName, double(currentIdx) / nrOfFiles, false );
joachim99@66 1171 if ( pp.wasCancelled() ) break;
joachim99@8 1172 ++currentIdx;
joachim99@8 1173
joachim99@8 1174
joachim99@8 1175 // The comparisons and calculations for each file take place here.
joachim99@8 1176 compareFilesAndCalcAges( mfi );
joachim99@8 1177
joachim99@8 1178 bool bEqual = bCheckC ? mfi.m_bEqualAB && mfi.m_bEqualAC : mfi.m_bEqualAB;
joachim99@69 1179 //bool bDir = mfi.m_bDirA || mfi.m_bDirB || mfi.m_bDirC;
joachim99@69 1180
joachim99@69 1181 //if ( m_pOptions->m_bDmShowOnlyDeltas && !bDir && bEqual )
joachim99@69 1182 // continue;
joachim99@8 1183
joachim99@8 1184 // Get dirname from fileName: Search for "/" from end:
joachim99@8 1185 int pos = fileName.findRev('/');
joachim99@8 1186 QString dirPart;
joachim99@8 1187 QString filePart;
joachim99@8 1188 if (pos==-1)
joachim99@8 1189 {
joachim99@8 1190 // Top dir
joachim99@8 1191 filePart = fileName;
joachim99@8 1192 }
joachim99@8 1193 else
joachim99@8 1194 {
joachim99@8 1195 dirPart = fileName.left(pos);
joachim99@8 1196 filePart = fileName.mid(pos+1);
joachim99@8 1197 }
joachim99@8 1198
joachim99@8 1199 if ( dirPart.isEmpty() ) // Top level
joachim99@8 1200 {
joachim99@8 1201 new DirMergeItem( this, filePart, &mfi );
joachim99@8 1202 }
joachim99@8 1203 else
joachim99@8 1204 {
joachim99@69 1205 MergeFileInfos& dirMfi = m_fileMergeMap[sortString(dirPart, m_bCaseSensitive)]; // parent
joachim99@8 1206 assert(dirMfi.m_pDMI!=0);
joachim99@8 1207 new DirMergeItem( dirMfi.m_pDMI, filePart, &mfi );
joachim99@8 1208 mfi.m_pParent = &dirMfi;
joachim99@8 1209
joachim99@8 1210 if ( !bEqual ) // Set all parents to "not equal"
joachim99@8 1211 {
joachim99@8 1212 MergeFileInfos* p = mfi.m_pParent;
joachim99@8 1213 while(p!=0)
joachim99@8 1214 {
joachim99@8 1215 bool bChange = false;
joachim99@8 1216 if ( !mfi.m_bEqualAB && p->m_bEqualAB ){ p->m_bEqualAB = false; bChange=true; }
joachim99@8 1217 if ( !mfi.m_bEqualAC && p->m_bEqualAC ){ p->m_bEqualAC = false; bChange=true; }
joachim99@8 1218 if ( !mfi.m_bEqualBC && p->m_bEqualBC ){ p->m_bEqualBC = false; bChange=true; }
joachim99@8 1219
joachim99@8 1220 if ( bChange )
joachim99@8 1221 setPixmaps( *p, bCheckC );
joachim99@8 1222 else
joachim99@8 1223 break;
joachim99@8 1224
joachim99@8 1225 p = p->m_pParent;
joachim99@8 1226 }
joachim99@8 1227 }
joachim99@8 1228 }
joachim99@8 1229
joachim99@8 1230 setPixmaps( mfi, bCheckC );
joachim99@8 1231 }
joachim99@8 1232
joachim99@69 1233 /*if ( m_pOptions->m_bDmShowOnlyDeltas )
joachim99@8 1234 {
joachim99@8 1235 // Remove all equals. (Search tree depth first)
joachim99@8 1236 QListViewItem* p = firstChild();
joachim99@8 1237 while( p!=0 && firstChild() != 0 )
joachim99@8 1238 {
joachim99@8 1239 QListViewItem* pParent = p->parent();
joachim99@8 1240 QListViewItem* pNextSibling = p->nextSibling();
joachim99@8 1241
joachim99@8 1242 DirMergeItem* pDMI = static_cast<DirMergeItem*>(p);
joachim99@8 1243 bool bDirEqual = bCheckC ? pDMI->m_pMFI->m_bEqualAB && pDMI->m_pMFI->m_bEqualAC
joachim99@8 1244 : pDMI->m_pMFI->m_bEqualAB;
joachim99@8 1245 if ( pDMI!=0 && pDMI->m_pMFI->m_bDirA && bDirEqual )
joachim99@8 1246 {
joachim99@8 1247 delete p;
joachim99@8 1248 p=0;
joachim99@8 1249 }
joachim99@8 1250
joachim99@8 1251 if ( p!=0 && p->firstChild() != 0 ) p = p->firstChild();
joachim99@8 1252 else if ( pNextSibling!=0 ) p = pNextSibling;
joachim99@8 1253 else
joachim99@8 1254 {
joachim99@8 1255 p=pParent;
joachim99@8 1256 while ( p!=0 )
joachim99@8 1257 {
joachim99@8 1258 if( p->nextSibling()!=0 ) { p = p->nextSibling(); break; }
joachim99@8 1259 else { p = p->parent(); }
joachim99@8 1260 }
joachim99@8 1261 }
joachim99@8 1262 }
joachim99@69 1263 }*/
joachim99@8 1264 }
joachim99@8 1265
joachim99@8 1266 static bool conflictingFileTypes(MergeFileInfos& mfi)
joachim99@8 1267 {
joachim99@8 1268 // Now check if file/dir-types fit.
joachim99@8 1269 if ( mfi.m_bLinkA || mfi.m_bLinkB || mfi.m_bLinkC )
joachim99@8 1270 {
joachim99@8 1271 if ( mfi.m_bExistsInA && ! mfi.m_bLinkA ||
joachim99@8 1272 mfi.m_bExistsInB && ! mfi.m_bLinkB ||
joachim99@8 1273 mfi.m_bExistsInC && ! mfi.m_bLinkC )
joachim99@8 1274 {
joachim99@8 1275 return true;
joachim99@8 1276 }
joachim99@8 1277 }
joachim99@8 1278
joachim99@8 1279 if ( mfi.m_bDirA || mfi.m_bDirB || mfi.m_bDirC )
joachim99@8 1280 {
joachim99@8 1281 if ( mfi.m_bExistsInA && ! mfi.m_bDirA ||
joachim99@8 1282 mfi.m_bExistsInB && ! mfi.m_bDirB ||
joachim99@8 1283 mfi.m_bExistsInC && ! mfi.m_bDirC )
joachim99@8 1284 {
joachim99@8 1285 return true;
joachim99@8 1286 }
joachim99@8 1287 }
joachim99@8 1288 return false;
joachim99@8 1289 }
joachim99@8 1290
joachim99@8 1291 void DirectoryMergeWindow::calcSuggestedOperation( MergeFileInfos& mfi, e_MergeOperation eDefaultMergeOp )
joachim99@8 1292 {
joachim99@8 1293 bool bCheckC = m_dirC.isValid();
joachim99@8 1294 bool bCopyNewer = m_pOptions->m_bDmCopyNewer;
joachim99@8 1295
joachim99@8 1296 if ( eDefaultMergeOp == eMergeABCToDest && !bCheckC ) { eDefaultMergeOp = eMergeABToDest; }
joachim99@8 1297 if ( eDefaultMergeOp == eMergeToAB && bCheckC ) { assert(false); }
joachim99@51 1298
joachim99@8 1299 if ( eDefaultMergeOp == eMergeToA || eDefaultMergeOp == eMergeToB ||
joachim99@8 1300 eDefaultMergeOp == eMergeABCToDest || eDefaultMergeOp == eMergeABToDest || eDefaultMergeOp == eMergeToAB )
joachim99@51 1301 {
joachim99@8 1302 if ( !bCheckC )
joachim99@8 1303 {
joachim99@8 1304 if ( mfi.m_bEqualAB )
joachim99@8 1305 {
joachim99@8 1306 mfi.setMergeOperation( eNoOperation ); // All is well, nothing to do.
joachim99@8 1307 }
joachim99@8 1308 else if ( mfi.m_bExistsInA && mfi.m_bExistsInB )
joachim99@8 1309 {
joachim99@8 1310 if ( !bCopyNewer || mfi.m_bDirA )
joachim99@8 1311 mfi.setMergeOperation( eDefaultMergeOp );
joachim99@8 1312 else if ( bCopyNewer && mfi.m_bConflictingAges )
joachim99@8 1313 {
joachim99@8 1314 mfi.setMergeOperation( eConflictingAges );
joachim99@8 1315 }
joachim99@8 1316 else
joachim99@8 1317 {
joachim99@8 1318 if ( mfi.m_ageA == eNew )
joachim99@8 1319 mfi.setMergeOperation( eDefaultMergeOp == eMergeToAB ? eCopyAToB : eCopyAToDest );
joachim99@8 1320 else
joachim99@8 1321 mfi.setMergeOperation( eDefaultMergeOp == eMergeToAB ? eCopyBToA : eCopyBToDest );
joachim99@8 1322 }
joachim99@8 1323 }
joachim99@8 1324 else if ( !mfi.m_bExistsInA && mfi.m_bExistsInB )
joachim99@8 1325 {
joachim99@8 1326 if ( eDefaultMergeOp==eMergeABToDest ) mfi.setMergeOperation( eCopyBToDest );
joachim99@8 1327 else if ( eDefaultMergeOp==eMergeToB ) mfi.setMergeOperation( eNoOperation );
joachim99@8 1328 else mfi.setMergeOperation( eCopyBToA );
joachim99@8 1329 }
joachim99@8 1330 else if ( mfi.m_bExistsInA && !mfi.m_bExistsInB )
joachim99@8 1331 {
joachim99@8 1332 if ( eDefaultMergeOp==eMergeABToDest ) mfi.setMergeOperation( eCopyAToDest );
joachim99@8 1333 else if ( eDefaultMergeOp==eMergeToA ) mfi.setMergeOperation( eNoOperation );
joachim99@8 1334 else mfi.setMergeOperation( eCopyAToB );
joachim99@8 1335 }
joachim99@8 1336 else //if ( !mfi.m_bExistsInA && !mfi.m_bExistsInB )
joachim99@8 1337 {
joachim99@8 1338 mfi.setMergeOperation( eNoOperation ); assert(false);
joachim99@8 1339 }
joachim99@8 1340 }
joachim99@8 1341 else
joachim99@8 1342 {
joachim99@8 1343 if ( mfi.m_bEqualAB && mfi.m_bEqualAC )
joachim99@8 1344 {
joachim99@8 1345 mfi.setMergeOperation( eCopyCToDest );
joachim99@8 1346 }
joachim99@8 1347 else if ( mfi.m_bExistsInA && mfi.m_bExistsInB && mfi.m_bExistsInC)
joachim99@8 1348 {
joachim99@8 1349 if ( mfi.m_bEqualAB )
joachim99@8 1350 mfi.setMergeOperation( eCopyCToDest );
joachim99@8 1351 else if ( mfi.m_bEqualAC )
joachim99@8 1352 mfi.setMergeOperation( eCopyBToDest );
joachim99@8 1353 else if ( mfi.m_bEqualBC )
joachim99@8 1354 mfi.setMergeOperation( eCopyCToDest );
joachim99@8 1355 else
joachim99@8 1356 mfi.setMergeOperation( eMergeABCToDest );
joachim99@8 1357 }
joachim99@8 1358 else if ( mfi.m_bExistsInA && mfi.m_bExistsInB && !mfi.m_bExistsInC )
joachim99@8 1359 {
joachim99@8 1360 if ( mfi.m_bEqualAB )
joachim99@8 1361 mfi.setMergeOperation( eDeleteFromDest );
joachim99@8 1362 else
joachim99@8 1363 mfi.setMergeOperation( eCopyBToDest );
joachim99@8 1364 }
joachim99@8 1365 else if ( mfi.m_bExistsInA && !mfi.m_bExistsInB && mfi.m_bExistsInC )
joachim99@8 1366 {
joachim99@8 1367 if ( mfi.m_bEqualAC )
joachim99@8 1368 mfi.setMergeOperation( eDeleteFromDest );
joachim99@8 1369 else
joachim99@8 1370 mfi.setMergeOperation( eCopyCToDest );
joachim99@8 1371 }
joachim99@8 1372 else if ( !mfi.m_bExistsInA && mfi.m_bExistsInB && mfi.m_bExistsInC )
joachim99@8 1373 {
joachim99@8 1374 if ( mfi.m_bEqualBC )
joachim99@8 1375 mfi.setMergeOperation( eCopyCToDest );
joachim99@8 1376 else
joachim99@8 1377 mfi.setMergeOperation( eMergeABCToDest );
joachim99@8 1378 }
joachim99@8 1379 else if ( !mfi.m_bExistsInA && !mfi.m_bExistsInB && mfi.m_bExistsInC )
joachim99@8 1380 {
joachim99@8 1381 mfi.setMergeOperation( eCopyCToDest );
joachim99@8 1382 }
joachim99@8 1383 else if ( !mfi.m_bExistsInA && mfi.m_bExistsInB && !mfi.m_bExistsInC )
joachim99@8 1384 {
joachim99@8 1385 mfi.setMergeOperation( eCopyBToDest );
joachim99@8 1386 }
joachim99@8 1387 else if ( mfi.m_bExistsInA && !mfi.m_bExistsInB && !mfi.m_bExistsInC)
joachim99@8 1388 {
joachim99@8 1389 mfi.setMergeOperation( eDeleteFromDest );
joachim99@8 1390 }
joachim99@8 1391 else //if ( !mfi.m_bExistsInA && !mfi.m_bExistsInB && !mfi.m_bExistsInC )
joachim99@8 1392 {
joachim99@8 1393 mfi.setMergeOperation( eNoOperation ); assert(false);
joachim99@8 1394 }
joachim99@8 1395 }
joachim99@8 1396
joachim99@8 1397 // Now check if file/dir-types fit.
joachim99@8 1398 if ( conflictingFileTypes(mfi) )
joachim99@8 1399 {
joachim99@8 1400 mfi.setMergeOperation( eConflictingFileTypes );
joachim99@8 1401 }
joachim99@8 1402 }
joachim99@8 1403 else
joachim99@8 1404 {
joachim99@8 1405 e_MergeOperation eMO = eDefaultMergeOp;
joachim99@8 1406 switch ( eDefaultMergeOp )
joachim99@8 1407 {
joachim99@8 1408 case eConflictingFileTypes:
joachim99@8 1409 case eConflictingAges:
joachim99@8 1410 case eDeleteA:
joachim99@8 1411 case eDeleteB:
joachim99@8 1412 case eDeleteAB:
joachim99@8 1413 case eDeleteFromDest:
joachim99@8 1414 case eNoOperation: break;
joachim99@8 1415 case eCopyAToB: if ( !mfi.m_bExistsInA ) { eMO = eDeleteB; } break;
joachim99@8 1416 case eCopyBToA: if ( !mfi.m_bExistsInB ) { eMO = eDeleteA; } break;
joachim99@8 1417 case eCopyAToDest: if ( !mfi.m_bExistsInA ) { eMO = eDeleteFromDest; } break;
joachim99@8 1418 case eCopyBToDest: if ( !mfi.m_bExistsInB ) { eMO = eDeleteFromDest; } break;
joachim99@8 1419 case eCopyCToDest: if ( !mfi.m_bExistsInC ) { eMO = eDeleteFromDest; } break;
joachim99@8 1420
joachim99@8 1421 case eMergeToA:
joachim99@8 1422 case eMergeToB:
joachim99@8 1423 case eMergeToAB:
joachim99@8 1424 case eMergeABCToDest:
joachim99@8 1425 case eMergeABToDest:
joachim99@8 1426 default:
joachim99@8 1427 assert(false);
joachim99@8 1428 }
joachim99@8 1429 mfi.setMergeOperation( eMO );
joachim99@8 1430 }
joachim99@8 1431 }
joachim99@8 1432
joachim99@8 1433 void DirectoryMergeWindow::onDoubleClick( QListViewItem* lvi )
joachim99@8 1434 {
joachim99@8 1435 if (lvi==0) return;
joachim99@8 1436
joachim99@8 1437 if ( m_bDirectoryMerge )
joachim99@8 1438 mergeCurrentFile();
joachim99@8 1439 else
joachim99@8 1440 compareCurrentFile();
joachim99@8 1441 }
joachim99@8 1442
joachim99@8 1443 void DirectoryMergeWindow::onSelectionChanged( QListViewItem* lvi )
joachim99@8 1444 {
joachim99@8 1445 if ( lvi==0 ) return;
joachim99@8 1446
joachim99@8 1447 DirMergeItem* pDMI = static_cast<DirMergeItem*>(lvi);
joachim99@8 1448
joachim99@8 1449 MergeFileInfos& mfi = *pDMI->m_pMFI;
joachim99@8 1450 assert( mfi.m_pDMI==pDMI );
joachim99@8 1451
joachim99@8 1452 m_pDirectoryMergeInfo->setInfo( m_dirA, m_dirB, m_dirC, m_dirDestInternal, mfi );
joachim99@8 1453 }
joachim99@8 1454
joachim99@69 1455 void DirectoryMergeWindow::onClick( int button, QListViewItem* lvi, const QPoint& p, int c )
joachim99@8 1456 {
joachim99@8 1457 if ( lvi==0 ) return;
joachim99@8 1458
joachim99@8 1459 DirMergeItem* pDMI = static_cast<DirMergeItem*>(lvi);
joachim99@8 1460
joachim99@8 1461 MergeFileInfos& mfi = *pDMI->m_pMFI;
joachim99@8 1462 assert( mfi.m_pDMI==pDMI );
joachim99@8 1463
joachim99@69 1464 if ( c==s_OpCol )
joachim99@8 1465 {
joachim99@69 1466 bool bThreeDirs = m_dirC.isValid();
joachim99@69 1467
joachim99@69 1468 KPopupMenu m(this);
joachim99@69 1469 if ( bThreeDirs )
joachim99@8 1470 {
joachim99@69 1471 m_pDirCurrentDoNothing->plug(&m);
joachim99@69 1472 int count=0;
joachim99@69 1473 if ( mfi.m_bExistsInA ) { m_pDirCurrentChooseA->plug(&m); ++count; }
joachim99@69 1474 if ( mfi.m_bExistsInB ) { m_pDirCurrentChooseB->plug(&m); ++count; }
joachim99@69 1475 if ( mfi.m_bExistsInC ) { m_pDirCurrentChooseC->plug(&m); ++count; }
joachim99@69 1476 if ( !conflictingFileTypes(mfi) && count>1 ) m_pDirCurrentMerge->plug(&m);
joachim99@69 1477 m_pDirCurrentDelete->plug(&m);
joachim99@69 1478 }
joachim99@69 1479 else if ( m_bSyncMode )
joachim99@69 1480 {
joachim99@69 1481 m_pDirCurrentSyncDoNothing->plug(&m);
joachim99@69 1482 if ( mfi.m_bExistsInA ) m_pDirCurrentSyncCopyAToB->plug(&m);
joachim99@69 1483 if ( mfi.m_bExistsInB ) m_pDirCurrentSyncCopyBToA->plug(&m);
joachim99@69 1484 if ( mfi.m_bExistsInA ) m_pDirCurrentSyncDeleteA->plug(&m);
joachim99@69 1485 if ( mfi.m_bExistsInB ) m_pDirCurrentSyncDeleteB->plug(&m);
joachim99@69 1486 if ( mfi.m_bExistsInA && mfi.m_bExistsInB )
joachim99@8 1487 {
joachim99@69 1488 m_pDirCurrentSyncDeleteAAndB->plug(&m);
joachim99@69 1489 if ( !conflictingFileTypes(mfi))
joachim99@69 1490 {
joachim99@69 1491 m_pDirCurrentSyncMergeToA->plug(&m);
joachim99@69 1492 m_pDirCurrentSyncMergeToB->plug(&m);
joachim99@69 1493 m_pDirCurrentSyncMergeToAAndB->plug(&m);
joachim99@69 1494 }
joachim99@8 1495 }
joachim99@8 1496 }
joachim99@69 1497 else
joachim99@69 1498 {
joachim99@69 1499 m_pDirCurrentDoNothing->plug(&m);
joachim99@69 1500 if ( mfi.m_bExistsInA ) { m_pDirCurrentChooseA->plug(&m); }
joachim99@69 1501 if ( mfi.m_bExistsInB ) { m_pDirCurrentChooseB->plug(&m); }
joachim99@69 1502 if ( !conflictingFileTypes(mfi) && mfi.m_bExistsInA && mfi.m_bExistsInB ) m_pDirCurrentMerge->plug(&m);
joachim99@69 1503 m_pDirCurrentDelete->plug(&m);
joachim99@69 1504 }
joachim99@69 1505
joachim99@69 1506 m.exec( p );
joachim99@8 1507 }
joachim99@69 1508 else if ( c == s_ACol || c==s_BCol || c==s_CCol )
joachim99@8 1509 {
joachim99@69 1510 QString itemPath;
joachim99@69 1511 if ( c == s_ACol && mfi.m_bExistsInA ){ itemPath = fullNameA(mfi); }
joachim99@69 1512 else if ( c == s_BCol && mfi.m_bExistsInB ){ itemPath = fullNameB(mfi); }
joachim99@69 1513 else if ( c == s_CCol && mfi.m_bExistsInC ){ itemPath = fullNameC(mfi); }
joachim99@69 1514
joachim99@69 1515 if (!itemPath.isEmpty())
joachim99@69 1516 {
joachim99@69 1517 selectItemAndColumn( pDMI, c, button==Qt::RightButton );
joachim99@69 1518 }
joachim99@8 1519 }
joachim99@69 1520 }
joachim99@69 1521
joachim99@69 1522 void DirectoryMergeWindow::slotShowContextMenu(QListViewItem* lvi,const QPoint & p,int c)
joachim99@69 1523 {
joachim99@69 1524 if ( lvi==0 ) return;
joachim99@69 1525
joachim99@69 1526 DirMergeItem* pDMI = static_cast<DirMergeItem*>(lvi);
joachim99@69 1527
joachim99@69 1528 MergeFileInfos& mfi = *pDMI->m_pMFI;
joachim99@69 1529 assert( mfi.m_pDMI==pDMI );
joachim99@69 1530 if ( c == s_ACol || c==s_BCol || c==s_CCol )
joachim99@69 1531 {
joachim99@69 1532 QString itemPath;
joachim99@69 1533 if ( c == s_ACol && mfi.m_bExistsInA ){ itemPath = fullNameA(mfi); }
joachim99@69 1534 else if ( c == s_BCol && mfi.m_bExistsInB ){ itemPath = fullNameB(mfi); }
joachim99@69 1535 else if ( c == s_CCol && mfi.m_bExistsInC ){ itemPath = fullNameC(mfi); }
joachim99@69 1536
joachim99@69 1537 if (!itemPath.isEmpty())
joachim99@69 1538 {
joachim99@69 1539 selectItemAndColumn(pDMI, c, true);
joachim99@69 1540 KPopupMenu m(this);
joachim99@69 1541 m_pDirCompareExplicit->plug(&m);
joachim99@69 1542 m_pDirMergeExplicit->plug(&m);
joachim99@69 1543
joachim99@69 1544 #ifndef _WIN32
joachim99@69 1545 m.exec( p );
joachim99@69 1546 #else
joachim99@69 1547 void showShellContextMenu( const QString&, QPoint, QWidget*, QPopupMenu* );
joachim99@69 1548 showShellContextMenu( itemPath, p, this, &m );
joachim99@69 1549 #endif
joachim99@69 1550 }
joachim99@69 1551 }
joachim99@69 1552 }
joachim99@69 1553
joachim99@69 1554 static QString getFileName( DirMergeItem* pDMI, int column )
joachim99@69 1555 {
joachim99@69 1556 if ( pDMI != 0 )
joachim99@69 1557 {
joachim99@69 1558 MergeFileInfos& mfi = *pDMI->m_pMFI;
joachim99@69 1559 return column == s_ACol ? mfi.m_fileInfoA.absFilePath() :
joachim99@69 1560 column == s_BCol ? mfi.m_fileInfoB.absFilePath() :
joachim99@69 1561 column == s_CCol ? mfi.m_fileInfoC.absFilePath() :
joachim99@69 1562 QString("");
joachim99@69 1563 }
joachim99@69 1564 return "";
joachim99@69 1565 }
joachim99@69 1566
joachim99@69 1567 static bool isDir( DirMergeItem* pDMI, int column )
joachim99@69 1568 {
joachim99@69 1569 if ( pDMI != 0 )
joachim99@69 1570 {
joachim99@69 1571 MergeFileInfos& mfi = *pDMI->m_pMFI;
joachim99@69 1572 return column == s_ACol ? mfi.m_bDirA :
joachim99@69 1573 column == s_BCol ? mfi.m_bDirB :
joachim99@69 1574 mfi.m_bDirC;
joachim99@69 1575 }
joachim99@69 1576 return false;
joachim99@69 1577 }
joachim99@69 1578
joachim99@69 1579
joachim99@69 1580 void DirectoryMergeWindow::selectItemAndColumn(DirMergeItem* pDMI, int c, bool bContextMenu)
joachim99@69 1581 {
joachim99@69 1582 if ( bContextMenu && (
joachim99@69 1583 pDMI==m_pSelection1Item && c==m_selection1Column && m_pSelection2Item==0 ||
joachim99@69 1584 pDMI==m_pSelection2Item && c==m_selection2Column && m_pSelection3Item==0 ||
joachim99@69 1585 pDMI==m_pSelection3Item && c==m_selection3Column ) )
joachim99@69 1586 return;
joachim99@69 1587
joachim99@69 1588 DirMergeItem* pOld1=m_pSelection1Item;
joachim99@69 1589 DirMergeItem* pOld2=m_pSelection2Item;
joachim99@69 1590 DirMergeItem* pOld3=m_pSelection3Item;
joachim99@69 1591
joachim99@69 1592 bool bReset = false;
joachim99@69 1593
joachim99@69 1594 if ( m_pSelection1Item )
joachim99@69 1595 {
joachim99@69 1596 if (isDir( m_pSelection1Item, m_selection1Column )!=isDir( pDMI, c ))
joachim99@69 1597 bReset = true;
joachim99@69 1598 }
joachim99@69 1599
joachim99@69 1600 if ( bReset || m_pSelection3Item!=0 ||
joachim99@69 1601 pDMI==m_pSelection1Item && c==m_selection1Column ||
joachim99@69 1602 pDMI==m_pSelection2Item && c==m_selection2Column ||
joachim99@69 1603 pDMI==m_pSelection3Item && c==m_selection3Column)
joachim99@69 1604 {
joachim99@69 1605 m_pSelection1Item = 0;
joachim99@69 1606 m_pSelection2Item = 0;
joachim99@69 1607 m_pSelection3Item = 0;
joachim99@69 1608 }
joachim99@69 1609 else if ( m_pSelection1Item==0 )
joachim99@69 1610 {
joachim99@69 1611 m_pSelection1Item = pDMI;
joachim99@69 1612 m_selection1Column = c;
joachim99@69 1613 m_pSelection2Item = 0;
joachim99@69 1614 m_pSelection3Item = 0;
joachim99@69 1615 }
joachim99@69 1616 else if ( m_pSelection2Item==0 )
joachim99@69 1617 {
joachim99@69 1618 m_pSelection2Item = pDMI;
joachim99@69 1619 m_selection2Column = c;
joachim99@69 1620 m_pSelection3Item = 0;
joachim99@69 1621 }
joachim99@69 1622 else if ( m_pSelection3Item==0 )
joachim99@69 1623 {
joachim99@69 1624 m_pSelection3Item = pDMI;
joachim99@69 1625 m_selection3Column = c;
joachim99@69 1626 }
joachim99@69 1627 if (pOld1) repaintItem( pOld1 );
joachim99@69 1628 if (pOld2) repaintItem( pOld2 );
joachim99@69 1629 if (pOld3) repaintItem( pOld3 );
joachim99@69 1630 if (m_pSelection1Item) repaintItem( m_pSelection1Item );
joachim99@69 1631 if (m_pSelection2Item) repaintItem( m_pSelection2Item );
joachim99@69 1632 if (m_pSelection3Item) repaintItem( m_pSelection3Item );
joachim99@69 1633 emit updateAvailabilities();
joachim99@8 1634 }
joachim99@8 1635
joachim99@8 1636 // Since Qt 2.3.0 doesn't allow the specification of a compare operator, this trick emulates it.
joachim99@8 1637 #if QT_VERSION==230
joachim99@8 1638 #define DIRSORT(x) ( pMFI->m_bDirA ? " " : "" )+x
joachim99@8 1639 #else
joachim99@8 1640 #define DIRSORT(x) x
joachim99@8 1641 #endif
joachim99@8 1642
joachim99@8 1643 DirMergeItem::DirMergeItem( QListView* pParent, const QString& fileName, MergeFileInfos* pMFI )
joachim99@66 1644 : QListViewItem( pParent, DIRSORT( fileName ), "","","", i18n("To do."), "" )
joachim99@66 1645 {
joachim99@66 1646 init(pMFI);
joachim99@66 1647 }
joachim99@66 1648
joachim99@66 1649 DirMergeItem::DirMergeItem( DirMergeItem* pParent, const QString& fileName, MergeFileInfos* pMFI )
joachim99@66 1650 : QListViewItem( pParent, DIRSORT( fileName ), "","","", i18n("To do."), "" )
joachim99@66 1651 {
joachim99@66 1652 init(pMFI);
joachim99@66 1653 }
joachim99@66 1654
joachim99@66 1655
joachim99@66 1656 void DirMergeItem::init(MergeFileInfos* pMFI)
joachim99@8 1657 {
joachim99@8 1658 pMFI->m_pDMI = this;
joachim99@8 1659 m_pMFI = pMFI;
joachim99@66 1660 TotalDiffStatus& tds = pMFI->m_totalDiffStatus;
joachim99@66 1661 if ( m_pMFI->m_bDirA || m_pMFI->m_bDirB || m_pMFI->m_bDirC )
joachim99@66 1662 {
joachim99@66 1663 }
joachim99@66 1664 else
joachim99@66 1665 {
joachim99@66 1666 setText( s_UnsolvedCol, QString::number( tds.nofUnsolvedConflicts ) );
joachim99@66 1667 setText( s_SolvedCol, QString::number( tds.nofSolvedConflicts ) );
joachim99@66 1668 setText( s_NonWhiteCol, QString::number( tds.nofUnsolvedConflicts + tds.nofSolvedConflicts - tds.nofWhitespaceConflicts ) );
joachim99@66 1669 setText( s_WhiteCol, QString::number( tds.nofWhitespaceConflicts ) );
joachim99@66 1670 }
joachim99@8 1671 }
joachim99@8 1672
joachim99@66 1673 int DirMergeItem::compare(QListViewItem *i, int col, bool ascending) const
joachim99@8 1674 {
joachim99@66 1675 DirMergeItem* pDMI = static_cast<DirMergeItem*>(i);
joachim99@66 1676 bool bDir1 = m_pMFI->m_bDirA || m_pMFI->m_bDirB || m_pMFI->m_bDirC;
joachim99@66 1677 bool bDir2 = pDMI->m_pMFI->m_bDirA || pDMI->m_pMFI->m_bDirB || pDMI->m_pMFI->m_bDirC;
joachim99@66 1678 if ( m_pMFI==0 || pDMI->m_pMFI==0 || bDir1 == bDir2 )
joachim99@66 1679 {
joachim99@66 1680 if(col==s_UnsolvedCol || col==s_SolvedCol || col==s_NonWhiteCol || col==s_WhiteCol)
joachim99@66 1681 return key(col,ascending).toInt() > i->key(col,ascending).toInt() ? -1 : 1;
joachim99@66 1682 else
joachim99@66 1683 return QListViewItem::compare( i, col, ascending );
joachim99@66 1684 }
joachim99@66 1685 else
joachim99@66 1686 return bDir1 ? -1 : 1;
joachim99@8 1687 }
joachim99@8 1688
joachim99@69 1689 void DirMergeItem::paintCell(QPainter * p, const QColorGroup & cg, int column, int width, int align )
joachim99@69 1690 {
joachim99@69 1691 if (column == s_ACol || column == s_BCol || column == s_CCol )
joachim99@69 1692 {
joachim99@69 1693 const QPixmap* icon = pixmap(column);
joachim99@69 1694 if ( icon )
joachim99@69 1695 {
joachim99@69 1696 int yOffset = (height() - icon->height()) / 2;
joachim99@69 1697 p->drawPixmap( 2, yOffset, *icon );
joachim99@69 1698 if ( listView() )
joachim99@69 1699 {
joachim99@69 1700 DirectoryMergeWindow* pDMW = static_cast<DirectoryMergeWindow*>(listView());
joachim99@69 1701 int i = this==pDMW->m_pSelection1Item && column == pDMW->m_selection1Column ? 1 :
joachim99@69 1702 this==pDMW->m_pSelection2Item && column == pDMW->m_selection2Column ? 2 :
joachim99@69 1703 this==pDMW->m_pSelection3Item && column == pDMW->m_selection3Column ? 3 :
joachim99@69 1704 0;
joachim99@69 1705 if ( i!=0 )
joachim99@69 1706 {
joachim99@69 1707 OptionDialog* pOD = pDMW->m_pOptions;
joachim99@69 1708 QColor c ( i==1 ? pOD->m_colorA : i==2 ? pOD->m_colorB : pOD->m_colorC );
joachim99@69 1709 p->setPen( c );// highlight() );
joachim99@69 1710 p->drawRect( 2, yOffset, icon->width(), icon->height());
joachim99@69 1711 p->setPen( QPen( c, 0, Qt::DotLine) );
joachim99@69 1712 p->drawRect( 1, yOffset-1, icon->width()+2, icon->height()+2);
joachim99@69 1713 p->setPen( cg.background() );
joachim99@69 1714 QString s( QChar('A'+i-1) );
joachim99@69 1715 p->drawText( 2 + (icon->width() - p->fontMetrics().width(s))/2,
joachim99@69 1716 yOffset + (icon->height() + p->fontMetrics().ascent())/2-1,
joachim99@69 1717 s );
joachim99@69 1718 }
joachim99@69 1719 else
joachim99@69 1720 {
joachim99@69 1721 p->setPen( cg.background() );
joachim99@69 1722 p->drawRect( 1, yOffset-1, icon->width()+2, icon->height()+2);
joachim99@69 1723 }
joachim99@69 1724 }
joachim99@69 1725 return;
joachim99@69 1726 }
joachim99@69 1727 }
joachim99@69 1728 QListViewItem::paintCell(p,cg,column,width,align);
joachim99@69 1729 }
joachim99@66 1730
joachim99@8 1731 DirMergeItem::~DirMergeItem()
joachim99@8 1732 {
joachim99@8 1733 m_pMFI->m_pDMI = 0;
joachim99@8 1734 }
joachim99@8 1735
joachim99@8 1736 void MergeFileInfos::setMergeOperation( e_MergeOperation eMOp )
joachim99@8 1737 {
joachim99@51 1738 if ( eMOp != m_eMergeOperation )
joachim99@51 1739 {
joachim99@51 1740 m_bOperationComplete = false;
joachim99@51 1741 m_pDMI->setText( s_OpStatusCol, "" );
joachim99@51 1742 }
joachim99@51 1743
joachim99@8 1744 m_eMergeOperation = eMOp;
joachim99@51 1745 QString s;
joachim99@8 1746 bool bDir = m_bDirA || m_bDirB || m_bDirC;
joachim99@8 1747 if( m_pDMI!=0 )
joachim99@8 1748 {
joachim99@8 1749 switch( m_eMergeOperation )
joachim99@8 1750 {
joachim99@8 1751 case eNoOperation: s=""; m_pDMI->setText(s_OpCol,""); break;
joachim99@51 1752 case eCopyAToB: s=i18n("Copy A to B"); break;
joachim99@51 1753 case eCopyBToA: s=i18n("Copy B to A"); break;
joachim99@51 1754 case eDeleteA: s=i18n("Delete A"); break;
joachim99@51 1755 case eDeleteB: s=i18n("Delete B"); break;
joachim99@51 1756 case eDeleteAB: s=i18n("Delete A & B"); break;
joachim99@51 1757 case eMergeToA: s=i18n("Merge to A"); break;
joachim99@51 1758 case eMergeToB: s=i18n("Merge to B"); break;
joachim99@51 1759 case eMergeToAB: s=i18n("Merge to A & B"); break;
joachim99@8 1760 case eCopyAToDest: s="A"; break;
joachim99@8 1761 case eCopyBToDest: s="B"; break;
joachim99@8 1762 case eCopyCToDest: s="C"; break;
joachim99@51 1763 case eDeleteFromDest: s=i18n("Delete (if exists)"); break;
joachim99@51 1764 case eMergeABCToDest: s= bDir ? i18n("Merge") : i18n("Merge (manual)"); break;
joachim99@51 1765 case eMergeABToDest: s= bDir ? i18n("Merge") : i18n("Merge (manual)"); break;
joachim99@51 1766 case eConflictingFileTypes: s=i18n("Error: Conflicting File Types"); break;
joachim99@51 1767 case eConflictingAges: s=i18n("Error: Dates are equal but files are not."); break;
joachim99@8 1768 default: assert(false); break;
joachim99@8 1769 }
joachim99@8 1770 m_pDMI->setText(s_OpCol,s);
joachim99@8 1771
joachim99@8 1772 e_MergeOperation eChildrenMergeOp = m_eMergeOperation;
joachim99@8 1773 if ( eChildrenMergeOp == eConflictingFileTypes ) eChildrenMergeOp = eMergeABCToDest;
joachim99@8 1774 QListViewItem* p = m_pDMI->firstChild();
joachim99@8 1775 while ( p!=0 )
joachim99@8 1776 {
joachim99@8 1777 DirMergeItem* pDMI = static_cast<DirMergeItem*>( p );
joachim99@8 1778 DirectoryMergeWindow* pDMW = static_cast<DirectoryMergeWindow*>( p->listView() );
joachim99@8 1779 pDMW->calcSuggestedOperation( *pDMI->m_pMFI, eChildrenMergeOp );
joachim99@8 1780 p = p->nextSibling();
joachim99@8 1781 }
joachim99@8 1782 }
joachim99@8 1783 }
joachim99@8 1784
joachim99@8 1785 void DirectoryMergeWindow::compareCurrentFile()
joachim99@8 1786 {
joachim99@8 1787 if (!canContinue()) return;
joachim99@8 1788
joachim99@8 1789 if ( m_bRealMergeStarted )
joachim99@8 1790 {
joachim99@51 1791 KMessageBox::sorry(this,i18n("This operation is currently not possible."),i18n("Operation Not Possible"));
joachim99@8 1792 return;
joachim99@8 1793 }
joachim99@8 1794
joachim99@8 1795 DirMergeItem* pDMI = static_cast<DirMergeItem*>( selectedItem() );
joachim99@8 1796 if ( pDMI != 0 )
joachim99@8 1797 {
joachim99@8 1798 MergeFileInfos& mfi = *pDMI->m_pMFI;
joachim99@8 1799 if ( !(mfi.m_bDirA || mfi.m_bDirB || mfi.m_bDirC) )
joachim99@8 1800 {
joachim99@8 1801 emit startDiffMerge(
joachim99@8 1802 mfi.m_bExistsInA ? mfi.m_fileInfoA.absFilePath() : QString(""),
joachim99@8 1803 mfi.m_bExistsInB ? mfi.m_fileInfoB.absFilePath() : QString(""),
joachim99@8 1804 mfi.m_bExistsInC ? mfi.m_fileInfoC.absFilePath() : QString(""),
joachim99@8 1805 "",
joachim99@66 1806 "","","",0
joachim99@8 1807 );
joachim99@8 1808 }
joachim99@8 1809 }
joachim99@8 1810 emit updateAvailabilities();
joachim99@8 1811 }
joachim99@8 1812
joachim99@8 1813
joachim99@69 1814 void DirectoryMergeWindow::slotCompareExplicitlySelectedFiles()
joachim99@69 1815 {
joachim99@69 1816 if ( ! isDir(m_pSelection1Item,m_selection1Column) && !canContinue() ) return;
joachim99@69 1817
joachim99@69 1818 if ( m_bRealMergeStarted )
joachim99@69 1819 {
joachim99@69 1820 KMessageBox::sorry(this,i18n("This operation is currently not possible."),i18n("Operation Not Possible"));
joachim99@69 1821 return;
joachim99@69 1822 }
joachim99@69 1823
joachim99@69 1824 emit startDiffMerge(
joachim99@69 1825 getFileName( m_pSelection1Item, m_selection1Column ),
joachim99@69 1826 getFileName( m_pSelection2Item, m_selection2Column ),
joachim99@69 1827 getFileName( m_pSelection3Item, m_selection3Column ),
joachim99@69 1828 "",
joachim99@69 1829 "","","",0
joachim99@69 1830 );
joachim99@69 1831 m_pSelection1Item=0;
joachim99@69 1832 m_pSelection2Item=0;
joachim99@69 1833 m_pSelection3Item=0;
joachim99@69 1834
joachim99@69 1835 emit updateAvailabilities();
joachim99@69 1836 triggerUpdate();
joachim99@69 1837 }
joachim99@69 1838
joachim99@69 1839 void DirectoryMergeWindow::slotMergeExplicitlySelectedFiles()
joachim99@69 1840 {
joachim99@69 1841 if ( ! isDir(m_pSelection1Item,m_selection1Column) && !canContinue() ) return;
joachim99@69 1842
joachim99@69 1843 if ( m_bRealMergeStarted )
joachim99@69 1844 {
joachim99@69 1845 KMessageBox::sorry(this,i18n("This operation is currently not possible."),i18n("Operation Not Possible"));
joachim99@69 1846 return;
joachim99@69 1847 }
joachim99@69 1848
joachim99@69 1849 QString fn1 = getFileName( m_pSelection1Item, m_selection1Column );
joachim99@69 1850 QString fn2 = getFileName( m_pSelection2Item, m_selection2Column );
joachim99@69 1851 QString fn3 = getFileName( m_pSelection3Item, m_selection3Column );
joachim99@69 1852
joachim99@69 1853 emit startDiffMerge( fn1, fn2, fn3,
joachim99@69 1854 fn3.isEmpty() ? fn2 : fn3,
joachim99@69 1855 "","","",0
joachim99@69 1856 );
joachim99@69 1857 m_pSelection1Item=0;
joachim99@69 1858 m_pSelection2Item=0;
joachim99@69 1859 m_pSelection3Item=0;
joachim99@69 1860
joachim99@69 1861 emit updateAvailabilities();
joachim99@69 1862 triggerUpdate();
joachim99@69 1863 }
joachim99@8 1864
joachim99@8 1865 bool DirectoryMergeWindow::isFileSelected()
joachim99@8 1866 {
joachim99@8 1867 DirMergeItem* pDMI = static_cast<DirMergeItem*>( selectedItem() );
joachim99@8 1868 if ( pDMI != 0 )
joachim99@8 1869 {
joachim99@8 1870 MergeFileInfos& mfi = *pDMI->m_pMFI;
joachim99@8 1871 return ! (mfi.m_bDirA || mfi.m_bDirB || mfi.m_bDirC || conflictingFileTypes(mfi) );
joachim99@8 1872 }
joachim99@8 1873 return false;
joachim99@8 1874 }
joachim99@8 1875
joachim99@8 1876 void DirectoryMergeWindow::mergeResultSaved(const QString& fileName)
joachim99@8 1877 {
joachim99@51 1878 DirMergeItem* pCurrentItemForOperation = (m_mergeItemList.empty() || m_currentItemForOperation==m_mergeItemList.end() )
joachim99@51 1879 ? 0
joachim99@51 1880 : *m_currentItemForOperation;
joachim99@51 1881
joachim99@51 1882 if ( pCurrentItemForOperation!=0 && pCurrentItemForOperation->m_pMFI==0 )
joachim99@8 1883 {
joachim99@51 1884 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 1885 return;
joachim99@8 1886 }
joachim99@51 1887 if ( pCurrentItemForOperation!=0 && fileName == fullNameDest(*pCurrentItemForOperation->m_pMFI) )
joachim99@8 1888 {
joachim99@51 1889 if ( pCurrentItemForOperation->m_pMFI->m_eMergeOperation==eMergeToAB )
joachim99@8 1890 {
joachim99@51 1891 MergeFileInfos& mfi = *pCurrentItemForOperation->m_pMFI;
joachim99@8 1892 bool bSuccess = copyFLD( fullNameB(mfi), fullNameA(mfi) );
joachim99@8 1893 if (!bSuccess)
joachim99@8 1894 {
joachim99@51 1895 KMessageBox::error(this, i18n("An error occurred while copying.\n"), i18n("Error") );
joachim99@51 1896 m_pStatusInfo->setCaption(i18n("Merge Error"));
joachim99@8 1897 m_pStatusInfo->show();
joachim99@69 1898 //if ( m_pStatusInfo->firstChild()!=0 )
joachim99@69 1899 // m_pStatusInfo->ensureItemVisible( m_pStatusInfo->last() );
joachim99@8 1900 m_bError = true;
joachim99@51 1901 pCurrentItemForOperation->setText( s_OpStatusCol, i18n("Error.") );
joachim99@8 1902 mfi.m_eMergeOperation = eCopyBToA;
joachim99@8 1903 return;
joachim99@8 1904 }
joachim99@8 1905 }
joachim99@51 1906 pCurrentItemForOperation->setText( s_OpStatusCol, i18n("Done.") );
joachim99@51 1907 pCurrentItemForOperation->m_pMFI->m_bOperationComplete = true;
joachim99@51 1908 if ( m_mergeItemList.size()==1 )
joachim99@51 1909 {
joachim99@51 1910 m_mergeItemList.clear();
joachim99@51 1911 m_bRealMergeStarted=false;
joachim99@51 1912 }
joachim99@8 1913 }
joachim99@8 1914
joachim99@8 1915 emit updateAvailabilities();
joachim99@8 1916 }
joachim99@8 1917
joachim99@8 1918 bool DirectoryMergeWindow::canContinue()
joachim99@8 1919 {
joachim99@8 1920 bool bCanContinue=false;
joachim99@8 1921 checkIfCanContinue( &bCanContinue );
joachim99@8 1922 if ( bCanContinue && !m_bError )
joachim99@8 1923 {
joachim99@51 1924 DirMergeItem* pCurrentItemForOperation =
joachim99@51 1925 (m_mergeItemList.empty() || m_currentItemForOperation==m_mergeItemList.end() ) ? 0 : *m_currentItemForOperation;
joachim99@51 1926
joachim99@51 1927 if ( pCurrentItemForOperation!=0 && ! pCurrentItemForOperation->m_pMFI->m_bOperationComplete )
joachim99@8 1928 {
joachim99@51 1929 pCurrentItemForOperation->setText( s_OpStatusCol, i18n("Not saved.") );
joachim99@51 1930 pCurrentItemForOperation->m_pMFI->m_bOperationComplete = true;
joachim99@51 1931 if ( m_mergeItemList.size()==1 )
joachim99@51 1932 {
joachim99@51 1933 m_mergeItemList.clear();
joachim99@51 1934 m_bRealMergeStarted=false;
joachim99@51 1935 }
joachim99@8 1936 }
joachim99@8 1937 }
joachim99@8 1938 return bCanContinue;
joachim99@8 1939 }
joachim99@8 1940
joachim99@51 1941 bool DirectoryMergeWindow::executeMergeOperation( MergeFileInfos& mfi, bool& bSingleFileMerge )
joachim99@8 1942 {
joachim99@51 1943 bool bCreateBackups = m_pOptions->m_bDmCreateBakFiles;
joachim99@51 1944 // First decide destname
joachim99@51 1945 QString destName;
joachim99@51 1946 switch( mfi.m_eMergeOperation )
joachim99@51 1947 {
joachim99@51 1948 case eNoOperation: break;
joachim99@51 1949 case eDeleteAB: break;
joachim99@51 1950 case eMergeToAB: // let the user save in B. In mergeResultSaved() the file will be copied to A.
joachim99@51 1951 case eMergeToB:
joachim99@51 1952 case eDeleteB:
joachim99@51 1953 case eCopyAToB: destName = fullNameB(mfi); break;
joachim99@51 1954 case eMergeToA:
joachim99@51 1955 case eDeleteA:
joachim99@51 1956 case eCopyBToA: destName = fullNameA(mfi); break;
joachim99@51 1957 case eMergeABToDest:
joachim99@51 1958 case eMergeABCToDest:
joachim99@51 1959 case eCopyAToDest:
joachim99@51 1960 case eCopyBToDest:
joachim99@51 1961 case eCopyCToDest:
joachim99@51 1962 case eDeleteFromDest: destName = fullNameDest(mfi); break;
joachim99@51 1963 default:
joachim99@51 1964 KMessageBox::error( this, i18n("Unknown merge operation. (This must never happen!)"), i18n("Error") );
joachim99@51 1965 assert(false);
joachim99@51 1966 }
joachim99@8 1967
joachim99@51 1968 bool bSuccess = false;
joachim99@51 1969 bSingleFileMerge = false;
joachim99@51 1970 switch( mfi.m_eMergeOperation )
joachim99@51 1971 {
joachim99@51 1972 case eNoOperation: bSuccess = true; break;
joachim99@51 1973 case eCopyAToDest:
joachim99@51 1974 case eCopyAToB: bSuccess = copyFLD( fullNameA(mfi), destName ); break;
joachim99@51 1975 case eCopyBToDest:
joachim99@51 1976 case eCopyBToA: bSuccess = copyFLD( fullNameB(mfi), destName ); break;
joachim99@51 1977 case eCopyCToDest: bSuccess = copyFLD( fullNameC(mfi), destName ); break;
joachim99@51 1978 case eDeleteFromDest:
joachim99@51 1979 case eDeleteA:
joachim99@51 1980 case eDeleteB: bSuccess = deleteFLD( destName, bCreateBackups ); break;
joachim99@51 1981 case eDeleteAB: bSuccess = deleteFLD( fullNameA(mfi), bCreateBackups ) &&
joachim99@51 1982 deleteFLD( fullNameB(mfi), bCreateBackups ); break;
joachim99@51 1983 case eMergeABToDest:
joachim99@51 1984 case eMergeToA:
joachim99@51 1985 case eMergeToAB:
joachim99@51 1986 case eMergeToB: bSuccess = mergeFLD( fullNameA(mfi), fullNameB(mfi), "",
joachim99@51 1987 destName, bSingleFileMerge );
joachim99@51 1988 break;
joachim99@51 1989 case eMergeABCToDest:bSuccess = mergeFLD(
joachim99@51 1990 mfi.m_bExistsInA ? fullNameA(mfi) : QString(""),
joachim99@51 1991 mfi.m_bExistsInB ? fullNameB(mfi) : QString(""),
joachim99@51 1992 mfi.m_bExistsInC ? fullNameC(mfi) : QString(""),
joachim99@51 1993 destName, bSingleFileMerge );
joachim99@51 1994 break;
joachim99@51 1995 default:
joachim99@51 1996 KMessageBox::error( this, i18n("Unknown merge operation."), i18n("Error") );
joachim99@51 1997 assert(false);
joachim99@51 1998 }
joachim99@8 1999
joachim99@51 2000 return bSuccess;
joachim99@51 2001 }
joachim99@8 2002
joachim99@51 2003
joachim99@51 2004 // Check if the merge can start, and prepare the m_mergeItemList which then contains all
joachim99@51 2005 // items that must be merged.
joachim99@51 2006 void DirectoryMergeWindow::prepareMergeStart( QListViewItem* pBegin, QListViewItem* pEnd, bool bVerbose )
joachim99@51 2007 {
joachim99@51 2008 if ( bVerbose )
joachim99@8 2009 {
joachim99@51 2010 int status = KMessageBox::warningYesNoCancel(this,
joachim99@51 2011 i18n("The merge is about to begin.\n\n"
joachim99@51 2012 "Choose \"Do it\" if you have read the instructions and know what you are doing.\n"
joachim99@51 2013 "Choosing \"Simulate it\" will tell you what would happen.\n\n"
joachim99@51 2014 "Be aware that this program still has beta status "
joachim99@51 2015 "and there is NO WARRANTY whatsoever! Make backups of your vital data!"),
joachim99@51 2016 i18n("Starting Merge"), i18n("Do It"), i18n("Simulate It") );
joachim99@51 2017 if (status==KMessageBox::Yes) m_bRealMergeStarted = true;
joachim99@51 2018 else if (status==KMessageBox::No ) m_bSimulatedMergeStarted = true;
joachim99@51 2019 else return;
joachim99@51 2020 }
joachim99@51 2021 else
joachim99@51 2022 {
joachim99@51 2023 m_bRealMergeStarted = true;
joachim99@51 2024 }
joachim99@51 2025
joachim99@51 2026 m_mergeItemList.clear();
joachim99@51 2027 if (pBegin == 0)
joachim99@51 2028 return;
joachim99@51 2029
joachim99@51 2030 for( QListViewItem* p = pBegin; p!= pEnd; p = treeIterator( p ) )
joachim99@51 2031 {
joachim99@51 2032 DirMergeItem* pDMI = static_cast<DirMergeItem*>(p);
joachim99@51 2033
joachim99@69 2034 if ( pDMI && ! pDMI->m_pMFI->m_bOperationComplete )
joachim99@8 2035 {
joachim99@51 2036 m_mergeItemList.push_back(pDMI);
joachim99@51 2037
joachim99@8 2038 if (pDMI!=0 && pDMI->m_pMFI->m_eMergeOperation == eConflictingFileTypes )
joachim99@8 2039 {
joachim99@8 2040 ensureItemVisible( pDMI );
joachim99@8 2041 setSelected( pDMI, true );
joachim99@51 2042 KMessageBox::error(this, i18n("The highlighted item has a different type in the different directories. Select what to do."), i18n("Error"));
joachim99@51 2043 m_mergeItemList.clear();
joachim99@51 2044 m_bRealMergeStarted=false;
joachim99@8 2045 return;
joachim99@8 2046 }
joachim99@8 2047 if (pDMI!=0 && pDMI->m_pMFI->m_eMergeOperation == eConflictingAges )
joachim99@8 2048 {
joachim99@8 2049 ensureItemVisible( pDMI );
joachim99@8 2050 setSelected( pDMI, true );
joachim99@51 2051 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 2052 m_mergeItemList.clear();
joachim99@51 2053 m_bRealMergeStarted=false;
joachim99@8 2054 return;
joachim99@8 2055 }
joachim99@8 2056 }
joachim99@8 2057 }
joachim99@8 2058
joachim99@51 2059 m_currentItemForOperation = m_mergeItemList.begin();
joachim99@51 2060 return;
joachim99@51 2061 }
joachim99@51 2062
joachim99@51 2063 void DirectoryMergeWindow::slotRunOperationForCurrentItem()
joachim99@51 2064 {
joachim99@51 2065 if ( ! canContinue() ) return;
joachim99@51 2066
joachim99@51 2067 bool bVerbose = false;
joachim99@51 2068 if ( m_mergeItemList.empty() )
joachim99@51 2069 {
joachim99@51 2070 QListViewItem* pBegin = currentItem();
joachim99@69 2071 QListViewItem* pEnd = treeIterator(pBegin,false,false); // find next visible sibling (no children)
joachim99@51 2072
joachim99@53 2073 prepareMergeStart( pBegin, pEnd, bVerbose );
joachim99@51 2074 mergeContinue(true, bVerbose);
joachim99@51 2075 }
joachim99@51 2076 else
joachim99@51 2077 mergeContinue(false, bVerbose);
joachim99@51 2078 }
joachim99@51 2079
joachim99@51 2080 void DirectoryMergeWindow::slotRunOperationForAllItems()
joachim99@51 2081 {
joachim99@51 2082 if ( ! canContinue() ) return;
joachim99@51 2083
joachim99@51 2084 bool bVerbose = true;
joachim99@51 2085 if ( m_mergeItemList.empty() )
joachim99@51 2086 {
joachim99@51 2087 QListViewItem* pBegin = firstChild();
joachim99@51 2088
joachim99@51 2089 prepareMergeStart( pBegin, 0, bVerbose );
joachim99@51 2090 mergeContinue(true, bVerbose);
joachim99@51 2091 }
joachim99@51 2092 else
joachim99@51 2093 mergeContinue(false, bVerbose);
joachim99@51 2094 }
joachim99@51 2095
joachim99@51 2096 void DirectoryMergeWindow::mergeCurrentFile()
joachim99@51 2097 {
joachim99@51 2098 if (!canContinue()) return;
joachim99@51 2099
joachim99@51 2100 if ( m_bRealMergeStarted )
joachim99@51 2101 {
joachim99@66 2102 KMessageBox::sorry(this,i18n("This operation is currently not possible because directory merge is currently running."),i18n("Operation Not Possible"));
joachim99@51 2103 return;
joachim99@51 2104 }
joachim99@51 2105
joachim99@51 2106 if ( isFileSelected() )
joachim99@51 2107 {
joachim99@51 2108 DirMergeItem* pDMI = static_cast<DirMergeItem*>( selectedItem() );
joachim99@51 2109 if ( pDMI != 0 )
joachim99@51 2110 {
joachim99@51 2111 MergeFileInfos& mfi = *pDMI->m_pMFI;
joachim99@51 2112 m_mergeItemList.clear();
joachim99@51 2113 m_mergeItemList.push_back( pDMI );
joachim99@51 2114 m_currentItemForOperation=m_mergeItemList.begin();
joachim99@51 2115 bool bDummy=false;
joachim99@51 2116 mergeFLD(
joachim99@51 2117 mfi.m_bExistsInA ? mfi.m_fileInfoA.absFilePath() : QString(""),
joachim99@51 2118 mfi.m_bExistsInB ? mfi.m_fileInfoB.absFilePath() : QString(""),
joachim99@51 2119 mfi.m_bExistsInC ? mfi.m_fileInfoC.absFilePath() : QString(""),
joachim99@51 2120 fullNameDest(mfi),
joachim99@51 2121 bDummy
joachim99@51 2122 );
joachim99@51 2123 }
joachim99@51 2124 }
joachim99@51 2125 emit updateAvailabilities();
joachim99@51 2126 }
joachim99@51 2127
joachim99@51 2128
joachim99@51 2129 // When bStart is true then m_currentItemForOperation must still be processed.
joachim99@51 2130 // When bVerbose is true then a messagebox will tell when the merge is complete.
joachim99@51 2131 void DirectoryMergeWindow::mergeContinue(bool bStart, bool bVerbose)
joachim99@51 2132 {
joachim99@66 2133 ProgressProxy pp;
joachim99@51 2134 if ( m_mergeItemList.empty() )
joachim99@51 2135 return;
joachim99@51 2136
joachim99@51 2137 int nrOfItems = 0;
joachim99@51 2138 int nrOfCompletedItems = 0;
joachim99@51 2139 int nrOfCompletedSimItems = 0;
joachim99@51 2140
joachim99@51 2141 // Count the number of completed items (for the progress bar).
joachim99@51 2142 for( MergeItemList::iterator i = m_mergeItemList.begin(); i!=m_mergeItemList.end(); ++i )
joachim99@51 2143 {
joachim99@53 2144 DirMergeItem* pDMI = *i;
joachim99@51 2145 ++nrOfItems;
joachim99@51 2146 if ( pDMI->m_pMFI->m_bOperationComplete )
joachim99@51 2147 ++nrOfCompletedItems;
joachim99@51 2148 if ( pDMI->m_pMFI->m_bSimOpComplete )
joachim99@51 2149 ++nrOfCompletedSimItems;
joachim99@51 2150 }
joachim99@51 2151
joachim99@51 2152 m_pStatusInfo->hide();
joachim99@51 2153 m_pStatusInfo->clear();
joachim99@51 2154
joachim99@51 2155 DirMergeItem* pCurrentItemForOperation = m_currentItemForOperation==m_mergeItemList.end() ? 0 : *m_currentItemForOperation;
joachim99@51 2156
joachim99@51 2157 bool bContinueWithCurrentItem = bStart; // true for first item, else false
joachim99@8 2158 bool bSkipItem = false;
joachim99@51 2159 if ( !bStart && m_bError && pCurrentItemForOperation!=0 )
joachim99@8 2160 {
joachim99@8 2161 int status = KMessageBox::warningYesNoCancel(this,
joachim99@8 2162 i18n("There was an error in the last step.\n"
joachim99@8 2163 "Do you want to continue with the item that caused the error or do you want to skip this item?"),
joachim99@51 2164 i18n("Continue merge after an error"), i18n("Continue With Last Item"), i18n("Skip Item") );
joachim99@51 2165 if (status==KMessageBox::Yes) bContinueWithCurrentItem = true;
joachim99@8 2166 else if (status==KMessageBox::No ) bSkipItem = true;
joachim99@8 2167 else return;
joachim99@8 2168 m_bError = false;
joachim99@8 2169 }
joachim99@8 2170
joachim99@8 2171 bool bSuccess = true;
joachim99@8 2172 bool bSingleFileMerge = false;
joachim99@8 2173 bool bSim = m_bSimulatedMergeStarted;
joachim99@8 2174 while( bSuccess )
joachim99@8 2175 {
joachim99@51 2176 if ( pCurrentItemForOperation==0 )
joachim99@51 2177 {
joachim99@51 2178 m_mergeItemList.clear();
joachim99@51 2179 m_bRealMergeStarted=false;
joachim99@51 2180 break;
joachim99@51 2181 }
joachim99@51 2182
joachim99@51 2183 if ( pCurrentItemForOperation!=0 && !bContinueWithCurrentItem )
joachim99@8 2184 {
joachim99@8 2185 if ( bSim )
joachim99@8 2186 {
joachim99@51 2187 if( pCurrentItemForOperation->firstChild()==0 )
joachim99@8 2188 {
joachim99@51 2189 pCurrentItemForOperation->m_pMFI->m_bSimOpComplete = true;
joachim99@8 2190 }
joachim99@8 2191 }
joachim99@8 2192 else
joachim99@8 2193 {
joachim99@51 2194 if( pCurrentItemForOperation->firstChild()==0 )
joachim99@8 2195 {
joachim99@51 2196 if( !pCurrentItemForOperation->m_pMFI->m_bOperationComplete )
joachim99@8 2197 {
joachim99@51 2198 pCurrentItemForOperation->setText( s_OpStatusCol, bSkipItem ? i18n("Skipped.") : i18n("Done.") );
joachim99@51 2199 pCurrentItemForOperation->m_pMFI->m_bOperationComplete = true;
joachim99@8 2200 bSkipItem = false;
joachim99@8 2201 }
joachim99@8 2202 }
joachim99@8 2203 else
joachim99@8 2204 {
joachim99@51 2205 pCurrentItemForOperation->setText( s_OpStatusCol, i18n("In progress...") );
joachim99@8 2206 }
joachim99@8 2207 }
joachim99@8 2208 }
joachim99@8 2209
joachim99@51 2210 if ( ! bContinueWithCurrentItem )
joachim99@8 2211 {
joachim99@51 2212 // Depth first
joachim99@51 2213 QListViewItem* pPrevItem = pCurrentItemForOperation;
joachim99@51 2214 ++m_currentItemForOperation;
joachim99@51 2215 pCurrentItemForOperation = m_currentItemForOperation==m_mergeItemList.end() ? 0 : *m_currentItemForOperation;
joachim99@51 2216 if ( (pCurrentItemForOperation==0 || pCurrentItemForOperation->parent()!=pPrevItem->parent()) && pPrevItem->parent()!=0 )
joachim99@8 2217 {
joachim99@51 2218 // Check if the parent may be set to "Done"
joachim99@51 2219 QListViewItem* pParent = pPrevItem->parent();
joachim99@51 2220 bool bDone = true;
joachim99@51 2221 while ( bDone && pParent!=0 )
joachim99@8 2222 {
joachim99@51 2223 for( QListViewItem* p = pParent->firstChild(); p!=0; p=p->nextSibling() )
joachim99@8 2224 {
joachim99@51 2225 DirMergeItem* pDMI = static_cast<DirMergeItem*>(p);
joachim99@51 2226 if ( !bSim && ! pDMI->m_pMFI->m_bOperationComplete || bSim && pDMI->m_pMFI->m_bSimOpComplete )
joachim99@8 2227 {
joachim99@51 2228 bDone=false;
joachim99@51 2229 break;
joachim99@8 2230 }
joachim99@8 2231 }
joachim99@51 2232 if ( bDone )
joachim99@51 2233 {
joachim99@51 2234 if (bSim)
joachim99@51 2235 static_cast<DirMergeItem*>(pParent)->m_pMFI->m_bSimOpComplete = bDone;
joachim99@51 2236 else
joachim99@51 2237 {
joachim99@51 2238 pParent->setText( s_OpStatusCol, i18n("Done.") );
joachim99@51 2239 static_cast<DirMergeItem*>(pParent)->m_pMFI->m_bOperationComplete = bDone;
joachim99@51 2240 }
joachim99@51 2241 }
joachim99@51 2242 pParent = pParent->parent();
joachim99@8 2243 }
joachim99@8 2244 }
joachim99@8 2245 }
joachim99@8 2246
joachim99@51 2247 if ( pCurrentItemForOperation == 0 ) // end?
joachim99@8 2248 {
joachim99@8 2249 if ( m_bRealMergeStarted )
joachim99@8 2250 {
joachim99@51 2251 if (bVerbose)
joachim99@51 2252 {
joachim99@51 2253 KMessageBox::information( this, i18n("Merge operation complete."), i18n("Merge Complete") );
joachim99@51 2254 }
joachim99@8 2255 m_bRealMergeStarted = false;
joachim99@51 2256 m_pStatusInfo->setCaption(i18n("Merge Complete"));
joachim99@8 2257 }
joachim99@8 2258 if ( m_bSimulatedMergeStarted )
joachim99@8 2259 {
joachim99@8 2260 m_bSimulatedMergeStarted = false;
joachim99@8 2261 for( QListViewItem* p=firstChild(); p!=0; p=treeIterator(p) )
joachim99@8 2262 {
joachim99@8 2263 static_cast<DirMergeItem*>(p)->m_pMFI->m_bSimOpComplete = false;
joachim99@8 2264 }
joachim99@51 2265 m_pStatusInfo->setCaption(i18n("Simulated merge complete: Check if you agree with the proposed operations."));
joachim99@8 2266 m_pStatusInfo->show();
joachim99@8 2267 }
joachim99@66 2268 //g_pProgressDialog->hide();
joachim99@51 2269 m_mergeItemList.clear();
joachim99@51 2270 m_bRealMergeStarted=false;
joachim99@8 2271 return;
joachim99@8 2272 }
joachim99@8 2273
joachim99@51 2274 MergeFileInfos& mfi = *pCurrentItemForOperation->m_pMFI;
joachim99@8 2275
joachim99@66 2276 pp.setInformation( mfi.m_subPath,
joachim99@8 2277 bSim ? double(nrOfCompletedSimItems)/nrOfItems : double(nrOfCompletedItems)/nrOfItems,
joachim99@51 2278 false // bRedrawUpdate
joachim99@8 2279 );
joachim99@66 2280 //g_pProgressDialog->show();
joachim99@8 2281
joachim99@51 2282 bSuccess = executeMergeOperation( mfi, bSingleFileMerge ); // Here the real operation happens.
joachim99@8 2283
joachim99@8 2284 if ( bSuccess )
joachim99@8 2285 {
joachim99@8 2286 if(bSim) ++nrOfCompletedSimItems;
joachim99@8 2287 else ++nrOfCompletedItems;
joachim99@8 2288 bContinueWithCurrentItem = false;
joachim99@8 2289 }
joachim99@51 2290
joachim99@66 2291 if( pp.wasCancelled() )
joachim99@51 2292 break;
joachim99@8 2293 } // end while
joachim99@8 2294
joachim99@66 2295 //g_pProgressDialog->hide();
joachim99@8 2296
joachim99@51 2297 setCurrentItem( pCurrentItemForOperation );
joachim99@51 2298 ensureItemVisible( pCurrentItemForOperation );
joachim99@8 2299 if ( !bSuccess && !bSingleFileMerge )
joachim99@8 2300 {
joachim99@51 2301 KMessageBox::error(this, i18n("An error occurred. Press OK to see detailed information.\n"), i18n("Error") );
joachim99@51 2302 m_pStatusInfo->setCaption(i18n("Merge Error"));
joachim99@8 2303 m_pStatusInfo->show();
joachim99@69 2304 //if ( m_pStatusInfo->firstChild()!=0 )
joachim99@69 2305 // m_pStatusInfo->ensureItemVisible( m_pStatusInfo->last() );
joachim99@8 2306 m_bError = true;
joachim99@51 2307 pCurrentItemForOperation->setText( s_OpStatusCol, i18n("Error.") );
joachim99@8 2308 }
joachim99@8 2309 else
joachim99@8 2310 {
joachim99@8 2311 m_bError = false;
joachim99@8 2312 }
joachim99@8 2313 emit updateAvailabilities();
joachim99@51 2314
joachim99@51 2315 if ( m_currentItemForOperation==m_mergeItemList.end() )
joachim99@51 2316 {
joachim99@51 2317 m_mergeItemList.clear();
joachim99@51 2318 m_bRealMergeStarted=false;
joachim99@51 2319 }
joachim99@8 2320 }
joachim99@8 2321
joachim99@8 2322 void DirectoryMergeWindow::allowResizeEvents(bool bAllowResizeEvents )
joachim99@8 2323 {
joachim99@8 2324 m_bAllowResizeEvents = bAllowResizeEvents;
joachim99@8 2325 }
joachim99@8 2326
joachim99@8 2327 void DirectoryMergeWindow::resizeEvent( QResizeEvent* e )
joachim99@8 2328 {
joachim99@8 2329 if (m_bAllowResizeEvents)
joachim99@8 2330 QListView::resizeEvent(e);
joachim99@8 2331 }
joachim99@8 2332
joachim99@8 2333 bool DirectoryMergeWindow::deleteFLD( const QString& name, bool bCreateBackup )
joachim99@8 2334 {
joachim99@8 2335 FileAccess fi(name, true);
joachim99@8 2336 if ( !fi.exists() )
joachim99@8 2337 return true;
joachim99@8 2338
joachim99@8 2339 if ( bCreateBackup )
joachim99@8 2340 {
joachim99@8 2341 bool bSuccess = renameFLD( name, name+".orig" );
joachim99@8 2342 if (!bSuccess)
joachim99@8 2343 {
joachim99@51 2344 m_pStatusInfo->addText( i18n("Error: While deleting %1: Creating backup failed.").arg(name) );
joachim99@8 2345 return false;
joachim99@8 2346 }
joachim99@8 2347 }
joachim99@8 2348 else
joachim99@8 2349 {
joachim99@8 2350 if ( fi.isDir() && !fi.isSymLink() )
joachim99@51 2351 m_pStatusInfo->addText(i18n("delete directory recursively( %1 )").arg(name));
joachim99@8 2352 else
joachim99@51 2353 m_pStatusInfo->addText(i18n("delete( %1 )").arg(name));
joachim99@8 2354
joachim99@8 2355 if ( m_bSimulatedMergeStarted )
joachim99@8 2356 {
joachim99@8 2357 return true;
joachim99@8 2358 }
joachim99@8 2359
joachim99@8 2360 if ( fi.isDir() && !fi.isSymLink() )// recursive directory delete only for real dirs, not symlinks
joachim99@8 2361 {
joachim99@8 2362 t_DirectoryList dirList;
joachim99@8 2363 bool bSuccess = fi.listDir( &dirList, false, true, "*", "", "", false, false ); // not recursive, find hidden files
joachim99@8 2364
joachim99@8 2365 if ( !bSuccess )
joachim99@8 2366 {
joachim99@8 2367 // No Permission to read directory or other error.
joachim99@51 2368 m_pStatusInfo->addText( i18n("Error: delete dir operation failed while trying to read the directory.") );
joachim99@8 2369 return false;
joachim99@8 2370 }
joachim99@8 2371
joachim99@8 2372 t_DirectoryList::iterator it; // create list iterator
joachim99@8 2373
joachim99@8 2374 for ( it=dirList.begin(); it!=dirList.end(); ++it ) // for each file...
joachim99@8 2375 {
joachim99@8 2376 FileAccess& fi2 = *it;
joachim99@8 2377 if ( fi2.fileName() == "." || fi2.fileName()==".." )
joachim99@8 2378 continue;
joachim99@8 2379 bSuccess = deleteFLD( fi2.absFilePath(), false );
joachim99@8 2380 if (!bSuccess) break;
joachim99@8 2381 }
joachim99@8 2382 if (bSuccess)
joachim99@8 2383 {
joachim99@8 2384 bSuccess = FileAccess::removeDir( name );
joachim99@8 2385 if ( !bSuccess )
joachim99@8 2386 {
joachim99@51 2387 m_pStatusInfo->addText( i18n("Error: rmdir( %1 ) operation failed.").arg(name));
joachim99@8 2388 return false;
joachim99@8 2389 }
joachim99@8 2390 }
joachim99@8 2391 }
joachim99@8 2392 else
joachim99@8 2393 {
joachim99@8 2394 bool bSuccess = FileAccess::removeFile( name );
joachim99@8 2395 if ( !bSuccess )
joachim99@8 2396 {
joachim99@51 2397 m_pStatusInfo->addText( i18n("Error: delete operation failed.") );
joachim99@8 2398 return false;
joachim99@8 2399 }
joachim99@8 2400 }
joachim99@8 2401 }
joachim99@8 2402 return true;
joachim99@8 2403 }
joachim99@8 2404
joachim99@8 2405 bool DirectoryMergeWindow::mergeFLD( const QString& nameA,const QString& nameB,const QString& nameC,const QString& nameDest, bool& bSingleFileMerge )
joachim99@8 2406 {
joachim99@8 2407 FileAccess fi(nameA);
joachim99@8 2408 if (fi.isDir())
joachim99@8 2409 {
joachim99@8 2410 return makeDir(nameDest);
joachim99@8 2411 }
joachim99@8 2412
joachim99@8 2413 // Make sure that the dir exists, into which we will save the file later.
joachim99@8 2414 int pos=nameDest.findRev('/');
joachim99@8 2415 if ( pos>0 )
joachim99@8 2416 {
joachim99@8 2417 QString parentName = nameDest.left(pos);
joachim99@8 2418 bool bSuccess = makeDir(parentName, true /*quiet*/);
joachim99@8 2419 if (!bSuccess)
joachim99@8 2420 return false;
joachim99@8 2421 }
joachim99@8 2422
joachim99@51 2423 m_pStatusInfo->addText(i18n("manual merge( %1, %2, %3 -> %4)").arg(nameA).arg(nameB).arg(nameC).arg(nameDest));
joachim99@8 2424 if ( m_bSimulatedMergeStarted )
joachim99@8 2425 {
joachim99@66 2426 m_pStatusInfo->addText(i18n(" Note: After a manual merge the user should continue by pressing F7.") );
joachim99@8 2427 return true;
joachim99@8 2428 }
joachim99@8 2429
joachim99@8 2430 bSingleFileMerge = true;
joachim99@51 2431 (*m_currentItemForOperation)->setText( s_OpStatusCol, i18n("In progress...") );
joachim99@51 2432 ensureItemVisible( *m_currentItemForOperation );
joachim99@8 2433
joachim99@66 2434 emit startDiffMerge( nameA, nameB, nameC, nameDest, "","","",0 );
joachim99@8 2435
joachim99@8 2436 return false;
joachim99@8 2437 }
joachim99@8 2438
joachim99@8 2439 bool DirectoryMergeWindow::copyFLD( const QString& srcName, const QString& destName )
joachim99@8 2440 {
joachim99@8 2441 if ( srcName == destName )
joachim99@8 2442 return true;
joachim99@8 2443
joachim99@8 2444 if ( FileAccess(destName, true).exists() )
joachim99@8 2445 {
joachim99@8 2446 bool bSuccess = deleteFLD( destName, m_pOptions->m_bDmCreateBakFiles );
joachim99@8 2447 if ( !bSuccess )
joachim99@8 2448 {
joachim99@51 2449 m_pStatusInfo->addText(i18n("Error: copy( %1 -> %2 ) failed."
joachim99@51 2450 "Deleting existing destination failed.").arg(srcName).arg(destName));
joachim99@8 2451 return false;
joachim99@8 2452 }
joachim99@8 2453 }
joachim99@8 2454
joachim99@8 2455 FileAccess fi( srcName );
joachim99@8 2456
joachim99@69 2457 if ( fi.isSymLink() && (fi.isDir() && !m_bFollowDirLinks || !fi.isDir() && !m_bFollowFileLinks) )
joachim99@8 2458 {
joachim99@51 2459 m_pStatusInfo->addText(i18n("copyLink( %1 -> %2 )").arg(srcName).arg(destName));
joachim99@8 2460 #ifdef _WIN32
joachim99@8 2461 // What are links?
joachim99@8 2462 #else
joachim99@8 2463 if ( m_bSimulatedMergeStarted )
joachim99@8 2464 {
joachim99@8 2465 return true;
joachim99@8 2466 }
joachim99@8 2467 FileAccess destFi(destName);
joachim99@8 2468 if ( !destFi.isLocal() || !fi.isLocal() )
joachim99@8 2469 {
joachim99@51 2470 m_pStatusInfo->addText(i18n("Error: copyLink failed: Remote links are not yet supported."));
joachim99@8 2471 return false;
joachim99@8 2472 }
joachim99@8 2473 QString linkTarget = fi.readLink();
joachim99@8 2474 bool bSuccess = FileAccess::symLink( linkTarget, destName );
joachim99@8 2475 if (!bSuccess)
joachim99@51 2476 m_pStatusInfo->addText(i18n("Error: copyLink failed."));
joachim99@8 2477 return bSuccess;
joachim99@8 2478 #endif
joachim99@8 2479 }
joachim99@8 2480
joachim99@8 2481 if ( fi.isDir() )
joachim99@8 2482 {
joachim99@8 2483 bool bSuccess = makeDir( destName );
joachim99@8 2484 return bSuccess;
joachim99@8 2485 }
joachim99@8 2486
joachim99@8 2487 int pos=destName.findRev('/');
joachim99@8 2488 if ( pos>0 )
joachim99@8 2489 {
joachim99@8 2490 QString parentName = destName.left(pos);
joachim99@8 2491 bool bSuccess = makeDir(parentName, true /*quiet*/);
joachim99@8 2492 if (!bSuccess)
joachim99@8 2493 return false;
joachim99@8 2494 }
joachim99@8 2495
joachim99@51 2496 m_pStatusInfo->addText(i18n("copy( %1 -> %2 )").arg(srcName).arg(destName));
joachim99@8 2497
joachim99@8 2498 if ( m_bSimulatedMergeStarted )
joachim99@8 2499 {
joachim99@8 2500 return true;
joachim99@8 2501 }
joachim99@8 2502
joachim99@8 2503 FileAccess faSrc ( srcName );
joachim99@8 2504 bool bSuccess = faSrc.copyFile( destName );
joachim99@8 2505 if (! bSuccess ) m_pStatusInfo->addText( faSrc.getStatusText() );
joachim99@8 2506 return bSuccess;
joachim99@8 2507 }
joachim99@8 2508
joachim99@8 2509 // Rename is not an operation that can be selected by the user.
joachim99@8 2510 // It will only be used to create backups.
joachim99@8 2511 // Hence it will delete an existing destination without making a backup (of the old backup.)
joachim99@8 2512 bool DirectoryMergeWindow::renameFLD( const QString& srcName, const QString& destName )
joachim99@8 2513 {
joachim99@8 2514 if ( srcName == destName )
joachim99@8 2515 return true;
joachim99@8 2516
joachim99@8 2517 if ( FileAccess(destName, true).exists() )
joachim99@8 2518 {
joachim99@8 2519 bool bSuccess = deleteFLD( destName, false /*no backup*/ );
joachim99@8 2520 if (!bSuccess)
joachim99@8 2521 {
joachim99@51 2522 m_pStatusInfo->addText( i18n("Error during rename( %1 -> %2 ): "
joachim99@51 2523 "Cannot delete existing destination." ).arg(srcName).arg(destName));
joachim99@8 2524 return false;
joachim99@8 2525 }
joachim99@8 2526 }
joachim99@8 2527
joachim99@68 2528 m_pStatusInfo->addText(i18n("rename( %1 -> %2 )").arg(srcName).arg(destName));
joachim99@8 2529 if ( m_bSimulatedMergeStarted )
joachim99@8 2530 {
joachim99@8 2531 return true;
joachim99@8 2532 }
joachim99@8 2533
joachim99@8 2534 bool bSuccess = FileAccess( srcName ).rename( destName );
joachim99@8 2535 if (!bSuccess)
joachim99@8 2536 {
joachim99@51 2537 m_pStatusInfo->addText( i18n("Error: Rename failed.") );
joachim99@8 2538 return false;
joachim99@8 2539 }
joachim99@8 2540
joachim99@8 2541 return true;
joachim99@8 2542 }
joachim99@8 2543
joachim99@8 2544 bool DirectoryMergeWindow::makeDir( const QString& name, bool bQuiet )
joachim99@8 2545 {
joachim99@8 2546 FileAccess fi(name, true);
joachim99@8 2547 if( fi.exists() && fi.isDir() )
joachim99@8 2548 return true;
joachim99@8 2549
joachim99@8 2550 if( fi.exists() && !fi.isDir() )
joachim99@8 2551 {
joachim99@8 2552 bool bSuccess = deleteFLD( name, true );
joachim99@8 2553 if (!bSuccess)
joachim99@8 2554 {
joachim99@51 2555 m_pStatusInfo->addText( i18n("Error during makeDir of %1. "
joachim99@51 2556 "Cannot delete existing file." ).arg(name));
joachim99@8 2557 return false;
joachim99@8 2558 }
joachim99@8 2559 }
joachim99@8 2560
joachim99@8 2561 int pos=name.findRev('/');
joachim99@8 2562 if ( pos>0 )
joachim99@8 2563 {
joachim99@8 2564 QString parentName = name.left(pos);
joachim99@8 2565 bool bSuccess = makeDir(parentName,true);
joachim99@8 2566 if (!bSuccess)
joachim99@8 2567 return false;
joachim99@8 2568 }
joachim99@8 2569
joachim99@8 2570 if ( ! bQuiet )
joachim99@51 2571 m_pStatusInfo->addText(i18n("makeDir( %1 )").arg(name));
joachim99@8 2572
joachim99@8 2573 if ( m_bSimulatedMergeStarted )
joachim99@8 2574 {
joachim99@8 2575 return true;
joachim99@8 2576 }
joachim99@8 2577
joachim99@8 2578 bool bSuccess = FileAccess::makeDir( name );
joachim99@8 2579 if ( bSuccess == false )
joachim99@8 2580 {
joachim99@51 2581 m_pStatusInfo->addText( i18n("Error while creating directory.") );
joachim99@8 2582 return false;
joachim99@8 2583 }
joachim99@8 2584 return true;
joachim99@8 2585 }
joachim99@8 2586
joachim99@8 2587
joachim99@8 2588 DirectoryMergeInfo::DirectoryMergeInfo( QWidget* pParent )
joachim99@8 2589 : QFrame(pParent)
joachim99@8 2590 {
joachim99@8 2591 QVBoxLayout *topLayout = new QVBoxLayout( this );
joachim99@8 2592
joachim99@8 2593 QGridLayout *grid = new QGridLayout( topLayout );
joachim99@8 2594 grid->setColStretch(1,10);
joachim99@8 2595
joachim99@8 2596 int line=0;
joachim99@8 2597
joachim99@8 2598 m_pA = new QLabel("A",this); grid->addWidget( m_pA,line, 0 );
joachim99@8 2599 m_pInfoA = new QLabel(this); grid->addWidget( m_pInfoA,line,1 ); ++line;
joachim99@8 2600 m_pB = new QLabel("B",this); grid->addWidget( m_pB,line, 0 );
joachim99@8 2601 m_pInfoB = new QLabel(this); grid->addWidget( m_pInfoB,line,1 ); ++line;
joachim99@8 2602 m_pC = new QLabel("C",this); grid->addWidget( m_pC,line, 0 );
joachim99@8 2603 m_pInfoC = new QLabel(this); grid->addWidget( m_pInfoC,line,1 ); ++line;
joachim99@51 2604 m_pDest = new QLabel(i18n("Dest"),this); grid->addWidget( m_pDest,line, 0 );
joachim99@8 2605 m_pInfoDest = new QLabel(this); grid->addWidget( m_pInfoDest,line,1 ); ++line;
joachim99@8 2606
joachim99@8 2607 m_pInfoList = new QListView(this); topLayout->addWidget( m_pInfoList );
joachim99@51 2608 m_pInfoList->addColumn(i18n("Dir"));
joachim99@51 2609 m_pInfoList->addColumn(i18n("Type"));
joachim99@51 2610 m_pInfoList->addColumn(i18n("Size"));
joachim99@51 2611 m_pInfoList->addColumn(i18n("Attr"));
joachim99@51 2612 m_pInfoList->addColumn(i18n("Last Modification"));
joachim99@51 2613 m_pInfoList->addColumn(i18n("Link-Destination"));
joachim99@8 2614 setMinimumSize( 100,100 );
joachim99@68 2615
joachim99@66 2616 m_pInfoList->installEventFilter(this);
joachim99@66 2617 }
joachim99@66 2618
joachim99@66 2619 bool DirectoryMergeInfo::eventFilter(QObject*o, QEvent* e)
joachim99@66 2620 {
joachim99@66 2621 if ( e->type()==QEvent::FocusIn && o==m_pInfoList )
joachim99@66 2622 emit gotFocus();
joachim99@66 2623 return false;
joachim99@8 2624 }
joachim99@8 2625
joachim99@8 2626 static void addListViewItem( QListView* pListView, const QString& dir,
joachim99@8 2627 const QString& basePath, FileAccess& fi )
joachim99@8 2628 {
joachim99@8 2629 if ( basePath.isEmpty() )
joachim99@8 2630 {
joachim99@8 2631 return;
joachim99@8 2632 }
joachim99@8 2633 else
joachim99@8 2634 {
joachim99@8 2635 if ( fi.exists() )
joachim99@8 2636 {
joachim99@8 2637 #if QT_VERSION==230
joachim99@8 2638 QString dateString = fi.lastModified().toString();
joachim99@8 2639 #else
joachim99@8 2640 QString dateString = fi.lastModified().toString("yyyy-MM-dd hh:mm:ss");
joachim99@8 2641 #endif
joachim99@8 2642
joachim99@8 2643 new QListViewItem(
joachim99@8 2644 pListView,
joachim99@8 2645 dir,
joachim99@51 2646 QString( fi.isDir() ? i18n("Dir") : i18n("File") ) + (fi.isSymLink() ? "-Link" : ""),
joachim99@8 2647 QString::number(fi.size()),
joachim99@8 2648 QString(fi.isReadable() ? "r" : " ") + (fi.isWritable()?"w" : " ")
joachim99@8 2649 #ifdef _WIN32
joachim99@8 2650 /*Future: Use GetFileAttributes()*/,
joachim99@8 2651 #else
joachim99@8 2652 + (fi.isExecutable()?"x" : " "),
joachim99@8 2653 #endif
joachim99@8 2654 dateString,
joachim99@8 2655 QString(fi.isSymLink() ? (" -> " + fi.readLink()) : QString(""))
joachim99@8 2656 );
joachim99@8 2657 }
joachim99@8 2658 else
joachim99@8 2659 {
joachim99@8 2660 new QListViewItem(
joachim99@8 2661 pListView,
joachim99@8 2662 dir,
joachim99@51 2663 i18n("not available"),
joachim99@8 2664 "",
joachim99@8 2665 "",
joachim99@8 2666 "",
joachim99@8 2667 ""
joachim99@8 2668 );
joachim99@8 2669 }
joachim99@8 2670 }
joachim99@8 2671 }
joachim99@8 2672
joachim99@8 2673 void DirectoryMergeInfo::setInfo(
joachim99@8 2674 const FileAccess& dirA,
joachim99@8 2675 const FileAccess& dirB,
joachim99@8 2676 const FileAccess& dirC,
joachim99@8 2677 const FileAccess& dirDest,
joachim99@8 2678 MergeFileInfos& mfi )
joachim99@8 2679 {
joachim99@8 2680 bool bHideDest = false;
joachim99@8 2681 if ( dirA.absFilePath()==dirDest.absFilePath() )
joachim99@8 2682 {
joachim99@51 2683 m_pA->setText( i18n("A (Dest): ") ); bHideDest=true;
joachim99@8 2684 }
joachim99@8 2685 else
joachim99@51 2686 m_pA->setText( !dirC.isValid() ? QString("A: ") : i18n("A (Base): "));
joachim99@8 2687
joachim99@8 2688 m_pInfoA->setText( dirA.prettyAbsPath() );
joachim99@8 2689
joachim99@8 2690 if ( dirB.absFilePath()==dirDest.absFilePath() )
joachim99@8 2691 {
joachim99@51 2692 m_pB->setText( i18n("B (Dest): ") ); bHideDest=true;
joachim99@8 2693 }
joachim99@8 2694 else
joachim99@8 2695 m_pB->setText( "B: " );
joachim99@8 2696 m_pInfoB->setText( dirB.prettyAbsPath() );
joachim99@8 2697
joachim99@8 2698 if ( dirC.absFilePath()==dirDest.absFilePath() )
joachim99@8 2699 {
joachim99@51 2700 m_pC->setText( i18n("C (Dest): ") ); bHideDest=true;
joachim99@8 2701 }
joachim99@8 2702 else
joachim99@8 2703 m_pC->setText( "C: " );
joachim99@8 2704 m_pInfoC->setText( dirC.prettyAbsPath() );
joachim99@8 2705
joachim99@51 2706 m_pDest->setText( i18n("Dest: ") ); m_pInfoDest->setText( dirDest.prettyAbsPath() );
joachim99@8 2707
joachim99@8 2708 if (!dirC.isValid()) { m_pC->hide(); m_pInfoC->hide(); }
joachim99@8 2709 else { m_pC->show(); m_pInfoC->show(); }
joachim99@8 2710
joachim99@8 2711 if (!dirDest.isValid()||bHideDest) { m_pDest->hide(); m_pInfoDest->hide(); }
joachim99@8 2712 else { m_pDest->show(); m_pInfoDest->show(); }
joachim99@8 2713
joachim99@8 2714 m_pInfoList->clear();
joachim99@8 2715 addListViewItem( m_pInfoList, "A", dirA.prettyAbsPath(), mfi.m_fileInfoA );
joachim99@8 2716 addListViewItem( m_pInfoList, "B", dirB.prettyAbsPath(), mfi.m_fileInfoB );
joachim99@8 2717 addListViewItem( m_pInfoList, "C", dirC.prettyAbsPath(), mfi.m_fileInfoC );
joachim99@8 2718 if (!bHideDest)
joachim99@8 2719 {
joachim99@8 2720 FileAccess fiDest( dirDest.prettyAbsPath() + "/" + mfi.m_subPath, true );
joachim99@51 2721 addListViewItem( m_pInfoList, i18n("Dest"), dirDest.prettyAbsPath(), fiDest );
joachim99@8 2722 }
joachim99@8 2723 }
joachim99@8 2724
joachim99@69 2725 QTextStream& operator<<( QTextStream& ts, MergeFileInfos& mfi )
joachim99@69 2726 {
joachim99@69 2727 ts << "{\n";
joachim99@69 2728 ValueMap vm;
joachim99@69 2729 vm.writeEntry( "SubPath", mfi.m_subPath );
joachim99@69 2730 vm.writeEntry( "ExistsInA", mfi.m_bExistsInA );
joachim99@69 2731 vm.writeEntry( "ExistsInB", mfi.m_bExistsInB );
joachim99@69 2732 vm.writeEntry( "ExistsInC", mfi.m_bExistsInC );
joachim99@69 2733 vm.writeEntry( "EqualAB", mfi.m_bEqualAB );
joachim99@69 2734 vm.writeEntry( "EqualAC", mfi.m_bEqualAC );
joachim99@69 2735 vm.writeEntry( "EqualBC", mfi.m_bEqualBC );
joachim99@69 2736 //DirMergeItem* m_pDMI;
joachim99@69 2737 //MergeFileInfos* m_pParent;
joachim99@69 2738 vm.writeEntry( "MergeOperation", (int) mfi.m_eMergeOperation );
joachim99@69 2739 vm.writeEntry( "DirA", mfi.m_bDirA );
joachim99@69 2740 vm.writeEntry( "DirB", mfi.m_bDirB );
joachim99@69 2741 vm.writeEntry( "DirC", mfi.m_bDirC );
joachim99@69 2742 vm.writeEntry( "LinkA", mfi.m_bLinkA );
joachim99@69 2743 vm.writeEntry( "LinkB", mfi.m_bLinkB );
joachim99@69 2744 vm.writeEntry( "LinkC", mfi.m_bLinkC );
joachim99@69 2745 vm.writeEntry( "OperationComplete", mfi.m_bOperationComplete );
joachim99@69 2746 //bool m_bSimOpComplete );
joachim99@69 2747
joachim99@69 2748 vm.writeEntry( "AgeA", (int) mfi.m_ageA );
joachim99@69 2749 vm.writeEntry( "AgeB", (int) mfi.m_ageB );
joachim99@69 2750 vm.writeEntry( "AgeC", (int) mfi.m_ageC );
joachim99@69 2751 vm.writeEntry( "ConflictingAges", mfi.m_bConflictingAges ); // Equal age but files are not!
joachim99@69 2752
joachim99@69 2753 //FileAccess m_fileInfoA;
joachim99@69 2754 //FileAccess m_fileInfoB;
joachim99@69 2755 //FileAccess m_fileInfoC;
joachim99@69 2756
joachim99@69 2757 //TotalDiffStatus m_totalDiffStatus;
joachim99@69 2758
joachim99@69 2759 vm.save(ts);
joachim99@69 2760
joachim99@69 2761 ts << "}\n";
joachim99@69 2762
joachim99@69 2763 return ts;
joachim99@69 2764 }
joachim99@69 2765
joachim99@69 2766 void DirectoryMergeWindow::slotSaveMergeState()
joachim99@69 2767 {
joachim99@69 2768 //slotStatusMsg(i18n("Saving Directory Merge State ..."));
joachim99@69 2769
joachim99@69 2770 //QString s = KFileDialog::getSaveURL( QDir::currentDirPath(), 0, this, i18n("Save As...") ).url();
joachim99@69 2771 QString s = KFileDialog::getSaveFileName( QDir::currentDirPath(), 0, this, i18n("Save Directory Merge State As...") );
joachim99@69 2772 if(!s.isEmpty())
joachim99@69 2773 {
joachim99@69 2774 m_dirMergeStateFilename = s;
joachim99@69 2775
joachim99@69 2776
joachim99@69 2777 QFile file(m_dirMergeStateFilename);
joachim99@69 2778 bool bSuccess = file.open( IO_WriteOnly );
joachim99@69 2779 if ( bSuccess )
joachim99@69 2780 {
joachim99@69 2781 QTextStream ts( &file );
joachim99@69 2782
joachim99@69 2783 QListViewItemIterator it( this );
joachim99@69 2784 while ( it.current() ) {
joachim99@69 2785 DirMergeItem* item = static_cast<DirMergeItem*>(it.current());
joachim99@69 2786 MergeFileInfos* pMFI = item->m_pMFI;
joachim99@69 2787 ts << *pMFI;
joachim99@69 2788 ++it;
joachim99@69 2789 }
joachim99@69 2790 }
joachim99@69 2791 }
joachim99@69 2792
joachim99@69 2793 //slotStatusMsg(i18n("Ready."));
joachim99@69 2794
joachim99@69 2795 }
joachim99@69 2796
joachim99@69 2797 void DirectoryMergeWindow::slotLoadMergeState()
joachim99@69 2798 {
joachim99@69 2799 }
joachim99@69 2800
joachim99@69 2801 void DirectoryMergeWindow::updateFileVisibilities()
joachim99@69 2802 {
joachim99@69 2803 bool bShowIdentical = m_pDirShowIdenticalFiles->isChecked();
joachim99@69 2804 bool bShowDifferent = m_pDirShowDifferentFiles->isChecked();
joachim99@69 2805 bool bShowOnlyInA = m_pDirShowFilesOnlyInA->isChecked();
joachim99@69 2806 bool bShowOnlyInB = m_pDirShowFilesOnlyInB->isChecked();
joachim99@69 2807 bool bShowOnlyInC = m_pDirShowFilesOnlyInC->isChecked();
joachim99@69 2808 bool bThreeDirs = m_dirC.isValid();
joachim99@69 2809 m_pSelection1Item = 0;
joachim99@69 2810 m_pSelection2Item = 0;
joachim99@69 2811 m_pSelection3Item = 0;
joachim99@69 2812
joachim99@69 2813 QListViewItem* p = firstChild();
joachim99@69 2814 while(p)
joachim99@69 2815 {
joachim99@69 2816 DirMergeItem* pDMI = static_cast<DirMergeItem*>(p);
joachim99@69 2817 MergeFileInfos* pMFI = pDMI->m_pMFI;
joachim99@69 2818 bool bDir = pMFI->m_bDirA || pMFI->m_bDirB || pMFI->m_bDirC;
joachim99@69 2819 bool bExistsEverywhere = pMFI->m_bExistsInA && pMFI->m_bExistsInB && (pMFI->m_bExistsInC || !bThreeDirs);
joachim99@69 2820 int existCount = int(pMFI->m_bExistsInA) + int(pMFI->m_bExistsInB) + int(pMFI->m_bExistsInC);
joachim99@69 2821 bool bVisible =
joachim99@69 2822 ( bShowIdentical && bExistsEverywhere && pMFI->m_bEqualAB && (pMFI->m_bEqualAC || !bThreeDirs) )
joachim99@69 2823 || ( (bShowDifferent||bDir) && existCount>=2 && (!pMFI->m_bEqualAB || !(pMFI->m_bEqualAC || !bThreeDirs)))
joachim99@69 2824 || ( bShowOnlyInA && pMFI->m_bExistsInA && !pMFI->m_bExistsInB && !pMFI->m_bExistsInC )
joachim99@69 2825 || ( bShowOnlyInB && !pMFI->m_bExistsInA && pMFI->m_bExistsInB && !pMFI->m_bExistsInC )
joachim99@69 2826 || ( bShowOnlyInC && !pMFI->m_bExistsInA && !pMFI->m_bExistsInB && pMFI->m_bExistsInC );
joachim99@69 2827
joachim99@69 2828 QString fileName = pMFI->m_subPath.section( '/', -1 );
joachim99@69 2829 bVisible = bVisible && (
joachim99@69 2830 bDir && ! wildcardMultiMatch( m_pOptions->m_DmDirAntiPattern, fileName, m_bCaseSensitive )
joachim99@69 2831 || wildcardMultiMatch( m_pOptions->m_DmFilePattern, fileName, m_bCaseSensitive )
joachim99@69 2832 && !wildcardMultiMatch( m_pOptions->m_DmFileAntiPattern, fileName, m_bCaseSensitive ) );
joachim99@69 2833
joachim99@69 2834 p->setVisible(bVisible);
joachim99@69 2835 p = treeIterator( p, true, true );
joachim99@69 2836 }
joachim99@69 2837 }
joachim99@69 2838
joachim99@69 2839 void DirectoryMergeWindow::slotShowIdenticalFiles() { m_pOptions->m_bDmShowIdenticalFiles=m_pDirShowIdenticalFiles->isChecked();
joachim99@69 2840 updateFileVisibilities(); }
joachim99@69 2841 void DirectoryMergeWindow::slotShowDifferentFiles() { updateFileVisibilities(); }
joachim99@69 2842 void DirectoryMergeWindow::slotShowFilesOnlyInA() { updateFileVisibilities(); }
joachim99@69 2843 void DirectoryMergeWindow::slotShowFilesOnlyInB() { updateFileVisibilities(); }
joachim99@69 2844 void DirectoryMergeWindow::slotShowFilesOnlyInC() { updateFileVisibilities(); }
joachim99@69 2845
joachim99@69 2846 void DirectoryMergeWindow::slotSynchronizeDirectories() { }
joachim99@69 2847 void DirectoryMergeWindow::slotChooseNewerFiles() { }
joachim99@51 2848
joachim99@51 2849 void DirectoryMergeWindow::initDirectoryMergeActions( QObject* pKDiff3App, KActionCollection* ac )
joachim99@51 2850 {
joachim99@51 2851 #include "xpm/startmerge.xpm"
joachim99@69 2852 #include "xpm/showequalfiles.xpm"
joachim99@69 2853 #include "xpm/showfilesonlyina.xpm"
joachim99@69 2854 #include "xpm/showfilesonlyinb.xpm"
joachim99@69 2855 #include "xpm/showfilesonlyinc.xpm"
joachim99@51 2856 DirectoryMergeWindow* p = this;
joachim99@51 2857
joachim99@69 2858 m_pDirStartOperation = new KAction(i18n("Start/Continue Directory Merge"), Qt::Key_F7, p, SLOT(slotRunOperationForAllItems()), ac, "dir_start_operation");
joachim99@69 2859 m_pDirRunOperationForCurrentItem = new KAction(i18n("Run Operation for Current Item"), Qt::Key_F6, p, SLOT(slotRunOperationForCurrentItem()), ac, "dir_run_operation_for_current_item");
joachim99@69 2860 m_pDirCompareCurrent = new KAction(i18n("Compare Selected File"), 0, p, SLOT(compareCurrentFile()), ac, "dir_compare_current");
joachim99@69 2861 m_pDirMergeCurrent = new KAction(i18n("Merge Current File"), QIconSet(QPixmap(startmerge)), 0, pKDiff3App, SLOT(slotMergeCurrentFile()), ac, "merge_current");
joachim99@69 2862 m_pDirFoldAll = new KAction(i18n("Fold All Subdirs"), 0, p, SLOT(slotFoldAllSubdirs()), ac, "dir_fold_all");
joachim99@69 2863 m_pDirUnfoldAll = new KAction(i18n("Unfold All Subdirs"), 0, p, SLOT(slotUnfoldAllSubdirs()), ac, "dir_unfold_all");
joachim99@69 2864 m_pDirRescan = new KAction(i18n("Rescan"), Qt::SHIFT+Qt::Key_F5, p, SLOT(reload()), ac, "dir_rescan");
joachim99@69 2865 m_pDirSaveMergeState = new KAction(i18n("Save Directory Merge State ..."), 0, p, SLOT(slotSaveMergeState()), ac, "dir_save_merge_state");
joachim99@69 2866 m_pDirLoadMergeState = new KAction(i18n("Load Directory Merge State ..."), 0, p, SLOT(slotLoadMergeState()), ac, "dir_load_merge_state");
joachim99@69 2867 m_pDirChooseAEverywhere = new KAction(i18n("Choose A for All Items"), 0, p, SLOT(slotChooseAEverywhere()), ac, "dir_choose_a_everywhere");
joachim99@69 2868 m_pDirChooseBEverywhere = new KAction(i18n("Choose B for All Items"), 0, p, SLOT(slotChooseBEverywhere()), ac, "dir_choose_b_everywhere");
joachim99@69 2869 m_pDirChooseCEverywhere = new KAction(i18n("Choose C for All Items"), 0, p, SLOT(slotChooseCEverywhere()), ac, "dir_choose_c_everywhere");
joachim99@69 2870 m_pDirAutoChoiceEverywhere = new KAction(i18n("Auto-Choose Operation for All Items"), 0, p, SLOT(slotAutoChooseEverywhere()), ac, "dir_autochoose_everywhere");
joachim99@69 2871 m_pDirDoNothingEverywhere = new KAction(i18n("No Operation for All Items"), 0, p, SLOT(slotNoOpEverywhere()), ac, "dir_nothing_everywhere");
joachim99@69 2872
joachim99@69 2873 // m_pDirSynchronizeDirectories = new KToggleAction(i18n("Synchronize Directories"), 0, this, SLOT(slotSynchronizeDirectories()), ac, "dir_synchronize_directories");
joachim99@69 2874 // m_pDirChooseNewerFiles = new KToggleAction(i18n("Copy Newer Files Instead of Merging"), 0, this, SLOT(slotChooseNewerFiles()), ac, "dir_choose_newer_files");
joachim99@69 2875
joachim99@69 2876 m_pDirShowIdenticalFiles = new KToggleAction(i18n("Show Identical Files"), QIconSet(QPixmap(showequalfiles)), 0, this, SLOT(slotShowIdenticalFiles()), ac, "dir_show_identical_files");
joachim99@69 2877 m_pDirShowDifferentFiles = new KToggleAction(i18n("Show Different Files"), 0, this, SLOT(slotShowDifferentFiles()), ac, "dir_show_different_files");
joachim99@69 2878 m_pDirShowFilesOnlyInA = new KToggleAction(i18n("Show Files only in A"), QIconSet(QPixmap(showfilesonlyina)), 0, this, SLOT(slotShowFilesOnlyInA()), ac, "dir_show_files_only_in_a");
joachim99@69 2879 m_pDirShowFilesOnlyInB = new KToggleAction(i18n("Show Files only in B"), QIconSet(QPixmap(showfilesonlyinb)), 0, this, SLOT(slotShowFilesOnlyInB()), ac, "dir_show_files_only_in_b");
joachim99@69 2880 m_pDirShowFilesOnlyInC = new KToggleAction(i18n("Show Files only in C"), QIconSet(QPixmap(showfilesonlyinc)), 0, this, SLOT(slotShowFilesOnlyInC()), ac, "dir_show_files_only_in_c");
joachim99@69 2881
joachim99@69 2882 m_pDirShowIdenticalFiles->setChecked( m_pOptions->m_bDmShowIdenticalFiles );
joachim99@69 2883
joachim99@69 2884 m_pDirCompareExplicit = new KAction(i18n("Compare Explicitly Selected Files"), 0, p, SLOT(slotCompareExplicitlySelectedFiles()), ac, "dir_compare_explicitly_selected_files");
joachim99@69 2885 m_pDirMergeExplicit = new KAction(i18n("Merge Explicitly Selected Files"), 0, p, SLOT(slotMergeExplicitlySelectedFiles()), ac, "dir_merge_explicitly_selected_files");
joachim99@69 2886
joachim99@69 2887 m_pDirCurrentDoNothing = new KAction(i18n("Do Nothing"), 0, p, SLOT(slotCurrentDoNothing()), ac, "dir_current_do_nothing");
joachim99@69 2888 m_pDirCurrentChooseA = new KAction(i18n("A"), 0, p, SLOT(slotCurrentChooseA()), ac, "dir_current_choose_a");
joachim99@69 2889 m_pDirCurrentChooseB = new KAction(i18n("B"), 0, p, SLOT(slotCurrentChooseB()), ac, "dir_current_choose_b");
joachim99@69 2890 m_pDirCurrentChooseC = new KAction(i18n("C"), 0, p, SLOT(slotCurrentChooseC()), ac, "dir_current_choose_c");
joachim99@69 2891 m_pDirCurrentMerge = new KAction(i18n("Merge"), 0, p, SLOT(slotCurrentMerge()), ac, "dir_current_merge");
joachim99@69 2892 m_pDirCurrentDelete = new KAction(i18n("Delete (if exists)"), 0, p, SLOT(slotCurrentDelete()), ac, "dir_current_delete");
joachim99@69 2893
joachim99@69 2894 m_pDirCurrentSyncDoNothing = new KAction(i18n("Do Nothing"), 0, p, SLOT(slotCurrentDoNothing()), ac, "dir_current_sync_do_nothing");
joachim99@69 2895 m_pDirCurrentSyncCopyAToB = new KAction(i18n("Copy A to B"), 0, p, SLOT(slotCurrentCopyAToB()), ac, "dir_current_sync_copy_a_to_b" );
joachim99@69 2896 m_pDirCurrentSyncCopyBToA = new KAction(i18n("Copy B to A"), 0, p, SLOT(slotCurrentCopyBToA()), ac, "dir_current_sync_copy_b_to_a" );
joachim99@69 2897 m_pDirCurrentSyncDeleteA = new KAction(i18n("Delete A"), 0, p, SLOT(slotCurrentDeleteA()), ac,"dir_current_sync_delete_a");
joachim99@69 2898 m_pDirCurrentSyncDeleteB = new KAction(i18n("Delete B"), 0, p, SLOT(slotCurrentDeleteB()), ac,"dir_current_sync_delete_b");
joachim99@69 2899 m_pDirCurrentSyncDeleteAAndB = new KAction(i18n("Delete A && B"), 0, p, SLOT(slotCurrentDeleteAAndB()), ac,"dir_current_sync_delete_a_and_b");
joachim99@69 2900 m_pDirCurrentSyncMergeToA = new KAction(i18n("Merge to A"), 0, p, SLOT(slotCurrentMergeToA()), ac,"dir_current_sync_merge_to_a");
joachim99@69 2901 m_pDirCurrentSyncMergeToB = new KAction(i18n("Merge to B"), 0, p, SLOT(slotCurrentMergeToB()), ac,"dir_current_sync_merge_to_b");
joachim99@69 2902 m_pDirCurrentSyncMergeToAAndB = new KAction(i18n("Merge to A && B"), 0, p, SLOT(slotCurrentMergeToAAndB()), ac,"dir_current_sync_merge_to_a_and_b");
joachim99@69 2903
joachim99@69 2904
joachim99@51 2905 }
joachim99@51 2906
joachim99@51 2907
joachim99@53 2908 void DirectoryMergeWindow::updateAvailabilities( bool bDirCompare, bool bDiffWindowVisible,
joachim99@53 2909 KToggleAction* chooseA, KToggleAction* chooseB, KToggleAction* chooseC )
joachim99@51 2910 {
joachim99@69 2911 m_pDirStartOperation->setEnabled( bDirCompare );
joachim99@69 2912 m_pDirRunOperationForCurrentItem->setEnabled( bDirCompare );
joachim99@69 2913 m_pDirFoldAll->setEnabled( bDirCompare );
joachim99@69 2914 m_pDirUnfoldAll->setEnabled( bDirCompare );
joachim99@69 2915
joachim99@69 2916 m_pDirCompareCurrent->setEnabled( bDirCompare && isVisible() && isFileSelected() );
joachim99@69 2917
joachim99@69 2918 m_pDirMergeCurrent->setEnabled( bDirCompare && isVisible() && isFileSelected()
joachim99@51 2919 || bDiffWindowVisible );
joachim99@51 2920
joachim99@69 2921 m_pDirRescan->setEnabled( bDirCompare );
joachim99@69 2922
joachim99@69 2923 m_pDirAutoChoiceEverywhere->setEnabled( bDirCompare && isVisible() );
joachim99@69 2924 m_pDirDoNothingEverywhere->setEnabled( bDirCompare && isVisible() );
joachim99@69 2925 m_pDirChooseAEverywhere->setEnabled( bDirCompare && isVisible() );
joachim99@69 2926 m_pDirChooseBEverywhere->setEnabled( bDirCompare && isVisible() );
joachim99@69 2927 m_pDirChooseCEverywhere->setEnabled( bDirCompare && isVisible() );
joachim99@51 2928
joachim99@51 2929 bool bThreeDirs = m_dirC.isValid();
joachim99@51 2930
joachim99@51 2931 QListViewItem* lvi = currentItem();
joachim99@51 2932 DirMergeItem* pDMI = lvi==0 ? 0 : static_cast<DirMergeItem*>(lvi);
joachim99@51 2933 MergeFileInfos* pMFI = pDMI==0 ? 0 : pDMI->m_pMFI;
joachim99@51 2934
joachim99@51 2935 bool bItemActive = bDirCompare && isVisible() && pMFI!=0;// && hasFocus();
joachim99@51 2936 bool bMergeMode = bThreeDirs || !m_bSyncMode;
joachim99@51 2937 bool bFTConflict = pMFI==0 ? false : conflictingFileTypes(*pMFI);
joachim99@51 2938
joachim99@53 2939 bool bDirWindowHasFocus = isVisible() && hasFocus();
joachim99@68 2940
joachim99@69 2941 m_pDirShowIdenticalFiles->setEnabled( bDirCompare && isVisible() );
joachim99@69 2942 m_pDirShowDifferentFiles->setEnabled( bDirCompare && isVisible() );
joachim99@69 2943 m_pDirShowFilesOnlyInA->setEnabled( bDirCompare && isVisible() );
joachim99@69 2944 m_pDirShowFilesOnlyInB->setEnabled( bDirCompare && isVisible() );
joachim99@69 2945 m_pDirShowFilesOnlyInC->setEnabled( bDirCompare && isVisible() && bThreeDirs );
joachim99@69 2946
joachim99@69 2947 m_pDirCompareExplicit->setEnabled( bDirCompare && isVisible() && m_pSelection2Item!=0 );
joachim99@69 2948 m_pDirMergeExplicit->setEnabled( bDirCompare && isVisible() && m_pSelection2Item!=0 );
joachim99@69 2949
joachim99@69 2950 m_pDirCurrentDoNothing->setEnabled( bItemActive && bMergeMode );
joachim99@69 2951 m_pDirCurrentChooseA->setEnabled( bItemActive && bMergeMode && pMFI->m_bExistsInA );
joachim99@69 2952 m_pDirCurrentChooseB->setEnabled( bItemActive && bMergeMode && pMFI->m_bExistsInB );
joachim99@69 2953 m_pDirCurrentChooseC->setEnabled( bItemActive && bMergeMode && pMFI->m_bExistsInC );
joachim99@69 2954 m_pDirCurrentMerge->setEnabled( bItemActive && bMergeMode && !bFTConflict );
joachim99@69 2955 m_pDirCurrentDelete->setEnabled( bItemActive && bMergeMode );
joachim99@53 2956 if ( bDirWindowHasFocus )
joachim99@53 2957 {
joachim99@53 2958 chooseA->setEnabled( bItemActive && pMFI->m_bExistsInA );
joachim99@53 2959 chooseB->setEnabled( bItemActive && pMFI->m_bExistsInB );
joachim99@53 2960 chooseC->setEnabled( bItemActive && pMFI->m_bExistsInC );
joachim99@53 2961 chooseA->setChecked( false );
joachim99@53 2962 chooseB->setChecked( false );
joachim99@53 2963 chooseC->setChecked( false );
joachim99@53 2964 }
joachim99@68 2965
joachim99@69 2966 m_pDirCurrentSyncDoNothing->setEnabled( bItemActive && !bMergeMode );
joachim99@69 2967 m_pDirCurrentSyncCopyAToB->setEnabled( bItemActive && !bMergeMode && pMFI->m_bExistsInA );
joachim99@69 2968 m_pDirCurrentSyncCopyBToA->setEnabled( bItemActive && !bMergeMode && pMFI->m_bExistsInB );
joachim99@69 2969 m_pDirCurrentSyncDeleteA->setEnabled( bItemActive && !bMergeMode && pMFI->m_bExistsInA );
joachim99@69 2970 m_pDirCurrentSyncDeleteB->setEnabled( bItemActive && !bMergeMode && pMFI->m_bExistsInB );
joachim99@69 2971 m_pDirCurrentSyncDeleteAAndB->setEnabled( bItemActive && !bMergeMode && pMFI->m_bExistsInB && pMFI->m_bExistsInB );
joachim99@69 2972 m_pDirCurrentSyncMergeToA->setEnabled( bItemActive && !bMergeMode && !bFTConflict );
joachim99@69 2973 m_pDirCurrentSyncMergeToB->setEnabled( bItemActive && !bMergeMode && !bFTConflict );
joachim99@69 2974 m_pDirCurrentSyncMergeToAAndB->setEnabled( bItemActive && !bMergeMode && !bFTConflict );
joachim99@51 2975 }
joachim99@51 2976
joachim99@51 2977
joachim99@8 2978 #include "directorymergewindow.moc"