annotate kdiff3/src/directorymergewindow.cpp @ 73:f7dad0aa6146

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