/***************************************************************************
directorymergewindow . cpp
- - - - - - - - - - - - - - - - -
begin : Sat Oct 19 2002
copyright : ( C ) 2002 - 2007 by Joachim Eibl
email : joachim . eibl at gmx . de
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/***************************************************************************
* *
* This program is free software ; you can redistribute it and / or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation ; either version 2 of the License , or *
* ( at your option ) any later version . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "directorymergewindow.h"
# include "optiondialog.h"
# include <vector>
# include <map>
# include <tqdir.h>
# include <tqapplication.h>
# include <tqpixmap.h>
# include <tqimage.h>
# include <tdepopupmenu.h>
# include <tdeaction.h>
# include <tqregexp.h>
# include <tqmessagebox.h>
# include <tqlayout.h>
# include <tqlabel.h>
# include <tqtable.h>
# include <tqsplitter.h>
# include <tqtextedit.h>
# include <tqprogressdialog.h>
# include <tdemessagebox.h>
# include <tdefiledialog.h>
# include <kiconloader.h>
# include <tdelocale.h>
# include <iostream>
# include <assert.h>
//#include <konq_popupmenu.h>
static bool conflictingFileTypes ( MergeFileInfos & mfi ) ;
/*
class StatusInfo : public TQListView
{
public :
StatusInfo ( TQWidget * pParent ) : TQListView ( pParent , " StatusInfo " , TQt : : WShowModal )
{
addColumn ( " " ) ;
setSorting ( - 1 ) ; //disable sorting
}
TQListViewItem * m_pLast ;
TQListViewItem * last ( )
{
if ( firstChild ( ) = = 0 ) return 0 ;
else return m_pLast ;
}
void addText ( const TQString & s )
{
if ( firstChild ( ) = = 0 ) m_pLast = new TQListViewItem ( this , s ) ;
else m_pLast = new TQListViewItem ( this , last ( ) , s ) ;
}
} ;
*/
class StatusInfo : public TQTextEdit
{
public :
StatusInfo ( TQWidget * pParent ) : TQTextEdit ( pParent , " StatusInfo " )
{
setWFlags ( TQt : : WShowModal ) ;
setWordWrap ( TQTextEdit : : NoWrap ) ;
setReadOnly ( true ) ;
//showMaximized();
}
bool isEmpty ( ) { return text ( ) . isEmpty ( ) ; }
void addText ( const TQString & s )
{
append ( s ) ;
}
void show ( )
{
scrollToBottom ( ) ;
TQTextEdit : : show ( ) ;
}
} ;
class TempRemover
{
public :
TempRemover ( const TQString & origName , FileAccess & fa ) ;
~ TempRemover ( ) ;
TQString name ( ) { return m_name ; }
bool success ( ) { return m_bSuccess ; }
private :
TQString m_name ;
bool m_bTemp ;
bool m_bSuccess ;
} ;
TempRemover : : TempRemover ( const TQString & origName , FileAccess & fa )
{
if ( fa . isLocal ( ) )
{
m_name = origName ;
m_bTemp = false ;
m_bSuccess = true ;
}
else
{
m_name = FileAccess : : tempFileName ( ) ;
m_bSuccess = fa . copyFile ( m_name ) ;
m_bTemp = m_bSuccess ;
}
}
TempRemover : : ~ TempRemover ( )
{
if ( m_bTemp & & ! m_name . isEmpty ( ) )
FileAccess : : removeTempFile ( m_name ) ;
}
void DirectoryMergeWindow : : fastFileComparison (
FileAccess & fi1 , FileAccess & fi2 ,
bool & bEqual , bool & bError , TQString & status )
{
ProgressProxy pp ;
status = " " ;
bEqual = false ;
bError = true ;
if ( ! m_bFollowFileLinks )
{
if ( fi1 . isSymLink ( ) ! = fi2 . isSymLink ( ) )
{
status = i18n ( " Mix of links and normal files. " ) ;
return ;
}
else if ( fi1 . isSymLink ( ) & & fi2 . isSymLink ( ) )
{
bError = false ;
bEqual = fi1 . readLink ( ) = = fi2 . readLink ( ) ;
status = i18n ( " Link: " ) ;
return ;
}
}
if ( fi1 . size ( ) ! = fi2 . size ( ) )
{
bEqual = false ;
status = i18n ( " Size. " ) ;
return ;
}
else if ( m_pOptions - > m_bDmTrustSize )
{
bEqual = true ;
return ;
}
if ( m_pOptions - > m_bDmTrustDate )
{
bEqual = ( fi1 . lastModified ( ) = = fi2 . lastModified ( ) & & fi1 . size ( ) = = fi2 . size ( ) ) ;
bError = false ;
status = i18n ( " Date & Size: " ) ;
return ;
}
if ( m_pOptions - > m_bDmTrustDateFallbackToBinary )
{
bEqual = ( fi1 . lastModified ( ) = = fi2 . lastModified ( ) & & fi1 . size ( ) = = fi2 . size ( ) ) ;
if ( bEqual )
{
bError = false ;
status = i18n ( " Date & Size: " ) ;
return ;
}
}
TQString fileName1 = fi1 . absFilePath ( ) ;
TQString fileName2 = fi2 . absFilePath ( ) ;
TempRemover tr1 ( fileName1 , fi1 ) ;
if ( ! tr1 . success ( ) )
{
status = i18n ( " Creating temp copy of %1 failed. " ) . arg ( fileName1 ) ;
return ;
}
TempRemover tr2 ( fileName2 , fi2 ) ;
if ( ! tr2 . success ( ) )
{
status = i18n ( " Creating temp copy of %1 failed. " ) . arg ( fileName2 ) ;
return ;
}
std : : vector < char > buf1 ( 100000 ) ;
std : : vector < char > buf2 ( buf1 . size ( ) ) ;
TQFile file1 ( tr1 . name ( ) ) ;
if ( ! file1 . open ( IO_ReadOnly ) )
{
status = i18n ( " Opening %1 failed. " ) . arg ( fileName1 ) ;
return ;
}
TQFile file2 ( tr2 . name ( ) ) ;
if ( ! file2 . open ( IO_ReadOnly ) )
{
status = i18n ( " Opening %1 failed. " ) . arg ( fileName2 ) ;
return ;
}
pp . setInformation ( i18n ( " Comparing file... " ) , 0 , false ) ;
# ifdef USE_QT4
typedef qint64 t_FileSize ;
# else // USE_QT4
typedef TQFile : : Offset t_FileSize ;
# endif // USE_QT4
t_FileSize fullSize = file1 . size ( ) ;
t_FileSize sizeLeft = fullSize ;
while ( sizeLeft > 0 & & ! pp . wasCancelled ( ) )
{
int len = min2 ( sizeLeft , ( t_FileSize ) buf1 . size ( ) ) ;
if ( len ! = file1 . readBlock ( & buf1 [ 0 ] , len ) )
{
status = i18n ( " Error reading from %1 " ) . arg ( fileName1 ) ;
return ;
}
if ( len ! = file2 . readBlock ( & buf2 [ 0 ] , len ) )
{
status = i18n ( " Error reading from %1 " ) . arg ( fileName2 ) ;
return ;
}
if ( memcmp ( & buf1 [ 0 ] , & buf2 [ 0 ] , len ) ! = 0 )
{
bError = false ;
return ;
}
sizeLeft - = len ;
pp . setCurrent ( double ( fullSize - sizeLeft ) / fullSize , false ) ;
}
// If the program really arrives here, then the files are really equal.
bError = false ;
bEqual = true ;
}
static int s_nameCol = 0 ;
static int s_ACol = 1 ;
static int s_BCol = 2 ;
static int s_CCol = 3 ;
static int s_OpCol = 4 ;
static int s_OpStatusCol = 5 ;
static int s_UnsolvedCol = 6 ; // Nr of unsolved conflicts (for 3 input files)
static int s_SolvedCol = 7 ; // Nr of auto-solvable conflicts (for 3 input files)
static int s_NonWhiteCol = 8 ; // Nr of nonwhite deltas (for 2 input files)
static int s_WhiteCol = 9 ; // Nr of white deltas (for 2 input files)
DirectoryMergeWindow : : DirectoryMergeWindow ( TQWidget * pParent , OptionDialog * pOptions , TDEIconLoader * pIconLoader )
: TQListView ( pParent )
{
connect ( TQT_TQOBJECT ( this ) , TQT_SIGNAL ( doubleClicked ( TQListViewItem * ) ) , TQT_TQOBJECT ( this ) , TQT_SLOT ( onDoubleClick ( TQListViewItem * ) ) ) ;
connect ( TQT_TQOBJECT ( this ) , TQT_SIGNAL ( returnPressed ( TQListViewItem * ) ) , TQT_TQOBJECT ( this ) , TQT_SLOT ( onDoubleClick ( TQListViewItem * ) ) ) ;
connect ( TQT_TQOBJECT ( this ) , TQT_SIGNAL ( mouseButtonPressed ( int , TQListViewItem * , const TQPoint & , int ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( onClick ( int , TQListViewItem * , const TQPoint & , int ) ) ) ;
connect ( TQT_TQOBJECT ( this ) , TQT_SIGNAL ( contextMenuRequested ( TQListViewItem * , const TQPoint & , int ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotShowContextMenu ( TQListViewItem * , const TQPoint & , int ) ) ) ;
connect ( TQT_TQOBJECT ( this ) , TQT_SIGNAL ( selectionChanged ( TQListViewItem * ) ) , TQT_TQOBJECT ( this ) , TQT_SLOT ( onSelectionChanged ( TQListViewItem * ) ) ) ;
m_pOptions = pOptions ;
m_pIconLoader = pIconLoader ;
m_pDirectoryMergeInfo = 0 ;
m_bAllowResizeEvents = true ;
m_bSimulatedMergeStarted = false ;
m_bRealMergeStarted = false ;
m_bError = false ;
m_bSyncMode = false ;
m_pStatusInfo = new StatusInfo ( 0 ) ;
m_pStatusInfo - > hide ( ) ;
m_bScanning = false ;
m_pSelection1Item = 0 ;
m_pSelection2Item = 0 ;
m_pSelection3Item = 0 ;
m_bCaseSensitive = true ;
addColumn ( i18n ( " Name " ) ) ;
addColumn ( " A " ) ;
addColumn ( " B " ) ;
addColumn ( " C " ) ;
addColumn ( i18n ( " Operation " ) ) ;
addColumn ( i18n ( " Status " ) ) ;
addColumn ( i18n ( " Unsolved " ) ) ;
addColumn ( i18n ( " Solved " ) ) ;
addColumn ( i18n ( " Nonwhite " ) ) ;
addColumn ( i18n ( " White " ) ) ;
setColumnAlignment ( s_UnsolvedCol , TQt : : AlignRight ) ;
setColumnAlignment ( s_SolvedCol , TQt : : AlignRight ) ;
setColumnAlignment ( s_NonWhiteCol , TQt : : AlignRight ) ;
setColumnAlignment ( s_WhiteCol , TQt : : AlignRight ) ;
}
DirectoryMergeWindow : : ~ DirectoryMergeWindow ( )
{
}
int DirectoryMergeWindow : : totalColumnWidth ( )
{
int w = 0 ;
for ( int i = 0 ; i < s_OpStatusCol ; + + i )
{
w + = columnWidth ( i ) ;
}
return w ;
}
void DirectoryMergeWindow : : reload ( )
{
if ( isDirectoryMergeInProgress ( ) )
{
int result = KMessageBox : : warningYesNo ( this ,
i18n ( " You are currently doing a directory merge. Are you sure, you want to abort the merge and rescan the directory? " ) ,
i18n ( " Warning " ) , i18n ( " Rescan " ) , i18n ( " Continue Merging " ) ) ;
if ( result ! = KMessageBox : : Yes )
return ;
}
init ( m_dirA , m_dirB , m_dirC , m_dirDest , m_bDirectoryMerge , true ) ;
}
// Copy pm2 onto pm1, but preserve the alpha value from pm1 where pm2 is transparent.
static TQPixmap pixCombiner ( const TQPixmap * pm1 , const TQPixmap * pm2 )
{
TQImage img1 = pm1 - > convertToImage ( ) . convertDepth ( 32 ) ;
TQImage img2 = pm2 - > convertToImage ( ) . convertDepth ( 32 ) ;
for ( int y = 0 ; y < img1 . height ( ) ; y + + )
{
TQ_UINT32 * line1 = reinterpret_cast < TQ_UINT32 * > ( img1 . scanLine ( y ) ) ;
TQ_UINT32 * line2 = reinterpret_cast < TQ_UINT32 * > ( img2 . scanLine ( y ) ) ;
for ( int x = 0 ; x < img1 . width ( ) ; x + + )
{
if ( tqAlpha ( line2 [ x ] ) > 0 )
line1 [ x ] = ( line2 [ x ] | 0xff000000 ) ;
}
}
TQPixmap pix ;
pix . convertFromImage ( img1 ) ;
return pix ;
}
// like pixCombiner but let the pm1 color shine through
static TQPixmap pixCombiner2 ( const TQPixmap * pm1 , const TQPixmap * pm2 )
{
TQImage img1 = pm1 - > convertToImage ( ) . convertDepth ( 32 ) ;
TQImage img2 = pm2 - > convertToImage ( ) . convertDepth ( 32 ) ;
for ( int y = 0 ; y < img1 . height ( ) ; y + + )
{
TQ_UINT32 * line1 = reinterpret_cast < TQ_UINT32 * > ( img1 . scanLine ( y ) ) ;
TQ_UINT32 * line2 = reinterpret_cast < TQ_UINT32 * > ( img2 . scanLine ( y ) ) ;
for ( int x = 0 ; x < img1 . width ( ) ; x + + )
{
if ( tqAlpha ( line2 [ x ] ) > 0 )
{
int r = ( tqRed ( line1 [ x ] ) + tqRed ( line2 [ x ] ) ) / 2 ;
int g = ( tqGreen ( line1 [ x ] ) + tqGreen ( line2 [ x ] ) ) / 2 ;
int b = ( tqBlue ( line1 [ x ] ) + tqBlue ( line2 [ x ] ) ) / 2 ;
line1 [ x ] = tqRgba ( r , g , b , 0xff ) ;
}
}
}
TQPixmap pix ;
pix . convertFromImage ( img1 ) ;
return pix ;
}
static void calcDirStatus ( bool bThreeDirs , DirMergeItem * i , int & nofFiles ,
int & nofDirs , int & nofEqualFiles , int & nofManualMerges )
{
if ( i - > m_pMFI - > m_bDirA | | i - > m_pMFI - > m_bDirB | | i - > m_pMFI - > m_bDirC )
{
+ + nofDirs ;
}
else
{
+ + nofFiles ;
if ( i - > m_pMFI - > m_bEqualAB & & ( ! bThreeDirs | | i - > m_pMFI - > m_bEqualAC ) )
{
+ + nofEqualFiles ;
}
else
{
if ( i - > m_pMFI - > m_eMergeOperation = = eMergeABCToDest | | i - > m_pMFI - > m_eMergeOperation = = eMergeABToDest )
+ + nofManualMerges ;
}
}
for ( TQListViewItem * p = i - > firstChild ( ) ; p ! = 0 ; p = p - > nextSibling ( ) )
calcDirStatus ( bThreeDirs , static_cast < DirMergeItem * > ( p ) , nofFiles , nofDirs , nofEqualFiles , nofManualMerges ) ;
}
static TQString sortString ( const TQString & s , bool bCaseSensitive )
{
if ( bCaseSensitive )
return s ;
else
return s . upper ( ) ;
}
struct t_ItemInfo
{
bool bExpanded ;
bool bOperationComplete ;
TQString status ;
e_MergeOperation eMergeOperation ;
} ;
bool DirectoryMergeWindow : : init
(
FileAccess & dirA ,
FileAccess & dirB ,
FileAccess & dirC ,
FileAccess & dirDest ,
bool bDirectoryMerge ,
bool bReload
)
{
if ( m_pOptions - > m_bDmFullAnalysis )
{
// A full analysis uses the same ressources that a normal text-diff/merge uses.
// So make sure that the user saves his data first.
bool bCanContinue = false ;
checkIfCanContinue ( & bCanContinue ) ;
if ( ! bCanContinue )
return false ;
startDiffMerge ( " " , " " , " " , " " , " " , " " , " " , 0 ) ; // hide main window
}
show ( ) ;
std : : map < TQString , t_ItemInfo > expandedDirsMap ;
if ( bReload )
{
// Remember expandes items
TQListViewItemIterator it ( this ) ;
while ( it . current ( ) )
{
DirMergeItem * pDMI = static_cast < DirMergeItem * > ( it . current ( ) ) ;
t_ItemInfo & ii = expandedDirsMap [ pDMI - > m_pMFI - > m_subPath ] ;
ii . bExpanded = pDMI - > isOpen ( ) ;
ii . bOperationComplete = pDMI - > m_pMFI - > m_bOperationComplete ;
ii . status = pDMI - > text ( s_OpStatusCol ) ;
ii . eMergeOperation = pDMI - > m_pMFI - > m_eMergeOperation ;
+ + it ;
}
}
ProgressProxy pp ;
m_bFollowDirLinks = m_pOptions - > m_bDmFollowDirLinks ;
m_bFollowFileLinks = m_pOptions - > m_bDmFollowFileLinks ;
m_bSimulatedMergeStarted = false ;
m_bRealMergeStarted = false ;
m_bError = false ;
m_bDirectoryMerge = bDirectoryMerge ;
m_pSelection1Item = 0 ;
m_pSelection2Item = 0 ;
m_pSelection3Item = 0 ;
m_bCaseSensitive = m_pOptions - > m_bDmCaseSensitiveFilenameComparison ;
clear ( ) ;
m_mergeItemList . clear ( ) ;
m_currentItemForOperation = m_mergeItemList . end ( ) ;
m_dirA = dirA ;
m_dirB = dirB ;
m_dirC = dirC ;
m_dirDest = dirDest ;
if ( ! bReload )
{
m_pDirShowIdenticalFiles - > setChecked ( true ) ;
m_pDirShowDifferentFiles - > setChecked ( true ) ;
m_pDirShowFilesOnlyInA - > setChecked ( true ) ;
m_pDirShowFilesOnlyInB - > setChecked ( true ) ;
m_pDirShowFilesOnlyInC - > setChecked ( true ) ;
}
// Check if all input directories exist and are valid. The dest dir is not tested now.
// The test will happen only when we are going to write to it.
if ( ! m_dirA . isDir ( ) | | ! m_dirB . isDir ( ) | |
( m_dirC . isValid ( ) & & ! m_dirC . isDir ( ) ) )
{
TQString text ( i18n ( " Opening of directories failed: " ) ) ;
text + = " \n \n " ;
if ( ! dirA . isDir ( ) )
{ text + = i18n ( " Dir A \" %1 \" does not exist or is not a directory. \n " ) . arg ( m_dirA . prettyAbsPath ( ) ) ; }
if ( ! dirB . isDir ( ) )
{ text + = i18n ( " Dir B \" %1 \" does not exist or is not a directory. \n " ) . arg ( m_dirB . prettyAbsPath ( ) ) ; }
if ( m_dirC . isValid ( ) & & ! m_dirC . isDir ( ) )
{ text + = i18n ( " Dir C \" %1 \" does not exist or is not a directory. \n " ) . arg ( m_dirC . prettyAbsPath ( ) ) ; }
KMessageBox : : sorry ( this , text , i18n ( " Directory Open Error " ) ) ;
return false ;
}
if ( m_dirC . isValid ( ) & &
( m_dirDest . prettyAbsPath ( ) = = m_dirA . prettyAbsPath ( ) | | m_dirDest . prettyAbsPath ( ) = = m_dirB . prettyAbsPath ( ) ) )
{
KMessageBox : : error ( this ,
i18n ( " The destination directory must not be the same as A or B when "
" three directories are merged. \n Check again before continuing. " ) ,
i18n ( " Parameter Warning " ) ) ;
return false ;
}
m_bScanning = true ;
statusBarMessage ( i18n ( " Scanning directories... " ) ) ;
m_bSyncMode = m_pOptions - > m_bDmSyncMode & & ! m_dirC . isValid ( ) & & ! m_dirDest . isValid ( ) ;
if ( m_dirDest . isValid ( ) )
m_dirDestInternal = m_dirDest ;
else
m_dirDestInternal = m_dirC . isValid ( ) ? m_dirC : m_dirB ;
TQString origCurrentDirectory = TQDir : : currentDirPath ( ) ;
m_fileMergeMap . clear ( ) ;
t_DirectoryList : : iterator i ;
// calc how many directories will be read:
double nofScans = ( m_dirA . isValid ( ) ? 1 : 0 ) + ( m_dirB . isValid ( ) ? 1 : 0 ) + ( m_dirC . isValid ( ) ? 1 : 0 ) ;
int currentScan = 0 ;
setColumnWidthMode ( s_UnsolvedCol , TQListView : : Manual ) ;
setColumnWidthMode ( s_SolvedCol , TQListView : : Manual ) ;
setColumnWidthMode ( s_WhiteCol , TQListView : : Manual ) ;
setColumnWidthMode ( s_NonWhiteCol , TQListView : : Manual ) ;
if ( ! m_pOptions - > m_bDmFullAnalysis )
{
setColumnWidth ( s_WhiteCol , 0 ) ;
setColumnWidth ( s_NonWhiteCol , 0 ) ;
setColumnWidth ( s_UnsolvedCol , 0 ) ;
setColumnWidth ( s_SolvedCol , 0 ) ;
}
else if ( m_dirC . isValid ( ) )
{
setColumnWidth ( s_WhiteCol , 50 ) ;
setColumnWidth ( s_NonWhiteCol , 50 ) ;
setColumnWidth ( s_UnsolvedCol , 50 ) ;
setColumnWidth ( s_SolvedCol , 50 ) ;
}
else
{
setColumnWidth ( s_WhiteCol , 50 ) ;
setColumnWidth ( s_NonWhiteCol , 50 ) ;
setColumnWidth ( s_UnsolvedCol , 50 ) ;
setColumnWidth ( s_SolvedCol , 0 ) ;
}
bool bListDirSuccessA = true ;
bool bListDirSuccessB = true ;
bool bListDirSuccessC = true ;
if ( m_dirA . isValid ( ) )
{
pp . setInformation ( i18n ( " Reading Directory A " ) ) ;
pp . setSubRangeTransformation ( currentScan / nofScans , ( currentScan + 1 ) / nofScans ) ;
+ + currentScan ;
t_DirectoryList dirListA ;
bListDirSuccessA = m_dirA . listDir ( & dirListA ,
m_pOptions - > m_bDmRecursiveDirs , m_pOptions - > m_bDmFindHidden ,
m_pOptions - > m_DmFilePattern , m_pOptions - > m_DmFileAntiPattern ,
m_pOptions - > m_DmDirAntiPattern , m_pOptions - > m_bDmFollowDirLinks ,
m_pOptions - > m_bDmUseCvsIgnore ) ;
for ( i = dirListA . begin ( ) ; i ! = dirListA . end ( ) ; + + i )
{
MergeFileInfos & mfi = m_fileMergeMap [ sortString ( i - > filePath ( ) , m_bCaseSensitive ) ] ;
//std::cout <<i->filePath()<<std::endl;
mfi . m_bExistsInA = true ;
mfi . m_fileInfoA = * i ;
}
}
if ( m_dirB . isValid ( ) )
{
pp . setInformation ( i18n ( " Reading Directory B " ) ) ;
pp . setSubRangeTransformation ( currentScan / nofScans , ( currentScan + 1 ) / nofScans ) ;
+ + currentScan ;
t_DirectoryList dirListB ;
bListDirSuccessB = m_dirB . listDir ( & dirListB ,
m_pOptions - > m_bDmRecursiveDirs , m_pOptions - > m_bDmFindHidden ,
m_pOptions - > m_DmFilePattern , m_pOptions - > m_DmFileAntiPattern ,
m_pOptions - > m_DmDirAntiPattern , m_pOptions - > m_bDmFollowDirLinks ,
m_pOptions - > m_bDmUseCvsIgnore ) ;
for ( i = dirListB . begin ( ) ; i ! = dirListB . end ( ) ; + + i )
{
MergeFileInfos & mfi = m_fileMergeMap [ sortString ( i - > filePath ( ) , m_bCaseSensitive ) ] ;
mfi . m_bExistsInB = true ;
mfi . m_fileInfoB = * i ;
}
}
e_MergeOperation eDefaultMergeOp ;
if ( m_dirC . isValid ( ) )
{
pp . setInformation ( i18n ( " Reading Directory C " ) ) ;
pp . setSubRangeTransformation ( currentScan / nofScans , ( currentScan + 1 ) / nofScans ) ;
+ + currentScan ;
t_DirectoryList dirListC ;
bListDirSuccessC = m_dirC . listDir ( & dirListC ,
m_pOptions - > m_bDmRecursiveDirs , m_pOptions - > m_bDmFindHidden ,
m_pOptions - > m_DmFilePattern , m_pOptions - > m_DmFileAntiPattern ,
m_pOptions - > m_DmDirAntiPattern , m_pOptions - > m_bDmFollowDirLinks ,
m_pOptions - > m_bDmUseCvsIgnore ) ;
for ( i = dirListC . begin ( ) ; i ! = dirListC . end ( ) ; + + i )
{
MergeFileInfos & mfi = m_fileMergeMap [ sortString ( i - > filePath ( ) , m_bCaseSensitive ) ] ;
mfi . m_bExistsInC = true ;
mfi . m_fileInfoC = * i ;
}
eDefaultMergeOp = eMergeABCToDest ;
}
else
eDefaultMergeOp = m_bSyncMode ? eMergeToAB : eMergeABToDest ;
bool bContinue = true ;
if ( ! bListDirSuccessA | | ! bListDirSuccessB | | ! bListDirSuccessC )
{
TQString s = i18n ( " Some subdirectories were not readable in " ) ;
if ( ! bListDirSuccessA ) s + = " \n A: " + m_dirA . prettyAbsPath ( ) ;
if ( ! bListDirSuccessB ) s + = " \n B: " + m_dirB . prettyAbsPath ( ) ;
if ( ! bListDirSuccessC ) s + = " \n C: " + m_dirC . prettyAbsPath ( ) ;
s + = " \n " ;
s + = i18n ( " Check the permissions of the subdirectories. " ) ;
bContinue = KMessageBox : : Continue = = KMessageBox : : warningContinueCancel ( this , s ) ;
}
if ( bContinue )
{
prepareListView ( pp ) ;
for ( TQListViewItem * p = firstChild ( ) ; p ! = 0 ; p = p - > nextSibling ( ) )
{
DirMergeItem * pDMI = static_cast < DirMergeItem * > ( p ) ;
calcSuggestedOperation ( * pDMI - > m_pMFI , eDefaultMergeOp ) ;
}
}
else
{
setSelected ( 0 , true ) ;
}
TQDir : : setCurrent ( origCurrentDirectory ) ;
// Try to improve the view a little bit.
TQWidget * pParent = parentWidget ( ) ;
TQSplitter * pSplitter = static_cast < TQSplitter * > ( pParent ) ;
if ( pSplitter ! = 0 )
{
TQValueList < int > sizes = pSplitter - > sizes ( ) ;
int total = sizes [ 0 ] + sizes [ 1 ] ;
sizes [ 0 ] = total * 6 / 10 ;
sizes [ 1 ] = total - sizes [ 0 ] ;
pSplitter - > setSizes ( sizes ) ;
}
m_bScanning = false ;
statusBarMessage ( i18n ( " Ready. " ) ) ;
if ( bContinue )
{
// Generate a status report
int nofFiles = 0 ;
int nofDirs = 0 ;
int nofEqualFiles = 0 ;
int nofManualMerges = 0 ;
for ( TQListViewItem * p = firstChild ( ) ; p ! = 0 ; p = p - > nextSibling ( ) )
calcDirStatus ( m_dirC . isValid ( ) , static_cast < DirMergeItem * > ( p ) ,
nofFiles , nofDirs , nofEqualFiles , nofManualMerges ) ;
TQString s ;
s = i18n ( " Directory Comparison Status " ) + " \n \n " +
i18n ( " Number of subdirectories: " ) + " " + TQString : : number ( nofDirs ) + " \n " +
i18n ( " Number of equal files: " ) + " " + TQString : : number ( nofEqualFiles ) + " \n " +
i18n ( " Number of different files: " ) + " " + TQString : : number ( nofFiles - nofEqualFiles ) ;
if ( m_dirC . isValid ( ) )
s + = " \n " + i18n ( " Number of manual merges: " ) + " " + TQString : : number ( nofManualMerges ) ;
KMessageBox : : information ( this , s ) ;
setSelected ( firstChild ( ) , true ) ;
}
updateFileVisibilities ( ) ;
if ( bReload )
{
// Remember expandes items
TQListViewItemIterator it ( this ) ;
while ( it . current ( ) )
{
DirMergeItem * pDMI = static_cast < DirMergeItem * > ( it . current ( ) ) ;
std : : map < TQString , t_ItemInfo > : : iterator i = expandedDirsMap . find ( pDMI - > m_pMFI - > m_subPath ) ;
if ( i ! = expandedDirsMap . end ( ) )
{
t_ItemInfo & ii = i - > second ;
pDMI - > setOpen ( ii . bExpanded ) ;
pDMI - > m_pMFI - > setMergeOperation ( ii . eMergeOperation , false ) ;
pDMI - > m_pMFI - > m_bOperationComplete = ii . bOperationComplete ;
pDMI - > setText ( s_OpStatusCol , ii . status ) ;
}
+ + it ;
}
}
return true ;
}
void DirectoryMergeWindow : : slotChooseAEverywhere ( ) { setAllMergeOperations ( eCopyAToDest ) ; }
void DirectoryMergeWindow : : slotChooseBEverywhere ( ) { setAllMergeOperations ( eCopyBToDest ) ; }
void DirectoryMergeWindow : : slotChooseCEverywhere ( ) { setAllMergeOperations ( eCopyCToDest ) ; }
void DirectoryMergeWindow : : slotAutoChooseEverywhere ( )
{
e_MergeOperation eDefaultMergeOp = m_dirC . isValid ( ) ? eMergeABCToDest :
m_bSyncMode ? eMergeToAB : eMergeABToDest ;
setAllMergeOperations ( eDefaultMergeOp ) ;
}
void DirectoryMergeWindow : : slotNoOpEverywhere ( ) { setAllMergeOperations ( eNoOperation ) ; }
static void setListViewItemOpen ( TQListViewItem * p , bool bOpen )
{
for ( TQListViewItem * pChild = p - > firstChild ( ) ; pChild ! = 0 ; pChild = pChild - > nextSibling ( ) )
setListViewItemOpen ( pChild , bOpen ) ;
p - > setOpen ( bOpen ) ;
}
void DirectoryMergeWindow : : slotFoldAllSubdirs ( )
{
for ( TQListViewItem * p = firstChild ( ) ; p ! = 0 ; p = p - > nextSibling ( ) )
setListViewItemOpen ( p , false ) ;
}
void DirectoryMergeWindow : : slotUnfoldAllSubdirs ( )
{
for ( TQListViewItem * p = firstChild ( ) ; p ! = 0 ; p = p - > nextSibling ( ) )
setListViewItemOpen ( p , true ) ;
}
static void setMergeOperation ( TQListViewItem * pLVI , e_MergeOperation eMergeOp )
{
if ( pLVI = = 0 ) return ;
DirMergeItem * pDMI = static_cast < DirMergeItem * > ( pLVI ) ;
MergeFileInfos & mfi = * pDMI - > m_pMFI ;
mfi . setMergeOperation ( eMergeOp ) ;
}
// Merge current item (merge mode)
void DirectoryMergeWindow : : slotCurrentDoNothing ( ) { setMergeOperation ( currentItem ( ) , eNoOperation ) ; }
void DirectoryMergeWindow : : slotCurrentChooseA ( ) { setMergeOperation ( currentItem ( ) , m_bSyncMode ? eCopyAToB : eCopyAToDest ) ; }
void DirectoryMergeWindow : : slotCurrentChooseB ( ) { setMergeOperation ( currentItem ( ) , m_bSyncMode ? eCopyBToA : eCopyBToDest ) ; }
void DirectoryMergeWindow : : slotCurrentChooseC ( ) { setMergeOperation ( currentItem ( ) , eCopyCToDest ) ; }
void DirectoryMergeWindow : : slotCurrentMerge ( )
{
bool bThreeDirs = m_dirC . isValid ( ) ;
setMergeOperation ( currentItem ( ) , bThreeDirs ? eMergeABCToDest : eMergeABToDest ) ;
}
void DirectoryMergeWindow : : slotCurrentDelete ( ) { setMergeOperation ( currentItem ( ) , eDeleteFromDest ) ; }
// Sync current item
void DirectoryMergeWindow : : slotCurrentCopyAToB ( ) { setMergeOperation ( currentItem ( ) , eCopyAToB ) ; }
void DirectoryMergeWindow : : slotCurrentCopyBToA ( ) { setMergeOperation ( currentItem ( ) , eCopyBToA ) ; }
void DirectoryMergeWindow : : slotCurrentDeleteA ( ) { setMergeOperation ( currentItem ( ) , eDeleteA ) ; }
void DirectoryMergeWindow : : slotCurrentDeleteB ( ) { setMergeOperation ( currentItem ( ) , eDeleteB ) ; }
void DirectoryMergeWindow : : slotCurrentDeleteAAndB ( ) { setMergeOperation ( currentItem ( ) , eDeleteAB ) ; }
void DirectoryMergeWindow : : slotCurrentMergeToA ( ) { setMergeOperation ( currentItem ( ) , eMergeToA ) ; }
void DirectoryMergeWindow : : slotCurrentMergeToB ( ) { setMergeOperation ( currentItem ( ) , eMergeToB ) ; }
void DirectoryMergeWindow : : slotCurrentMergeToAAndB ( ) { setMergeOperation ( currentItem ( ) , eMergeToAB ) ; }
void DirectoryMergeWindow : : keyPressEvent ( TQKeyEvent * e )
{
if ( ( e - > state ( ) & TQt : : ControlButton ) ! = 0 )
{
bool bThreeDirs = m_dirC . isValid ( ) ;
TQListViewItem * lvi = currentItem ( ) ;
DirMergeItem * pDMI = lvi = = 0 ? 0 : static_cast < DirMergeItem * > ( lvi ) ;
MergeFileInfos * pMFI = pDMI = = 0 ? 0 : pDMI - > m_pMFI ;
if ( pMFI = = 0 ) return ;
bool bMergeMode = bThreeDirs | | ! m_bSyncMode ;
bool bFTConflict = pMFI = = 0 ? false : conflictingFileTypes ( * pMFI ) ;
if ( bMergeMode )
{
switch ( e - > key ( ) )
{
case Key_1 : if ( pMFI - > m_bExistsInA ) { slotCurrentChooseA ( ) ; } return ;
case Key_2 : if ( pMFI - > m_bExistsInB ) { slotCurrentChooseB ( ) ; } return ;
case Key_3 : if ( pMFI - > m_bExistsInC ) { slotCurrentChooseC ( ) ; } return ;
case Key_Space : slotCurrentDoNothing ( ) ; return ;
case Key_4 : if ( ! bFTConflict ) { slotCurrentMerge ( ) ; } return ;
case Key_Delete : slotCurrentDelete ( ) ; return ;
default : break ;
}
}
else
{
switch ( e - > key ( ) )
{
case Key_1 : if ( pMFI - > m_bExistsInA ) { slotCurrentCopyAToB ( ) ; } return ;
case Key_2 : if ( pMFI - > m_bExistsInB ) { slotCurrentCopyBToA ( ) ; } return ;
case Key_Space : slotCurrentDoNothing ( ) ; return ;
case Key_4 : if ( ! bFTConflict ) { slotCurrentMergeToAAndB ( ) ; } return ;
case Key_Delete : if ( pMFI - > m_bExistsInA & & pMFI - > m_bExistsInB ) slotCurrentDeleteAAndB ( ) ;
else if ( pMFI - > m_bExistsInA ) slotCurrentDeleteA ( ) ;
else if ( pMFI - > m_bExistsInB ) slotCurrentDeleteB ( ) ;
return ;
default : break ;
}
}
}
TQListView : : keyPressEvent ( e ) ;
}
void DirectoryMergeWindow : : focusInEvent ( TQFocusEvent * )
{
updateAvailabilities ( ) ;
}
void DirectoryMergeWindow : : focusOutEvent ( TQFocusEvent * )
{
updateAvailabilities ( ) ;
}
void DirectoryMergeWindow : : setAllMergeOperations ( e_MergeOperation eDefaultOperation )
{
if ( KMessageBox : : Yes = = KMessageBox : : warningYesNo ( this ,
i18n ( " This affects all merge operations. " ) ,
i18n ( " Changing All Merge Operations " ) , i18n ( " C&ontinue " ) , i18n ( " &Cancel " ) ) )
{
for ( TQListViewItem * p = firstChild ( ) ; p ! = 0 ; p = p - > nextSibling ( ) )
{
DirMergeItem * pDMI = static_cast < DirMergeItem * > ( p ) ;
calcSuggestedOperation ( * pDMI - > m_pMFI , eDefaultOperation ) ;
}
}
}
void DirectoryMergeWindow : : compareFilesAndCalcAges ( MergeFileInfos & mfi )
{
std : : map < TQDateTime , int > dateMap ;
if ( mfi . m_bExistsInA )
{
mfi . m_bLinkA = mfi . m_fileInfoA . isSymLink ( ) ;
mfi . m_bDirA = mfi . m_fileInfoA . isDir ( ) ;
dateMap [ mfi . m_fileInfoA . lastModified ( ) ] = 0 ;
}
if ( mfi . m_bExistsInB )
{
mfi . m_bLinkB = mfi . m_fileInfoB . isSymLink ( ) ;
mfi . m_bDirB = mfi . m_fileInfoB . isDir ( ) ;
dateMap [ mfi . m_fileInfoB . lastModified ( ) ] = 1 ;
}
if ( mfi . m_bExistsInC )
{
mfi . m_bLinkC = mfi . m_fileInfoC . isSymLink ( ) ;
mfi . m_bDirC = mfi . m_fileInfoC . isDir ( ) ;
dateMap [ mfi . m_fileInfoC . lastModified ( ) ] = 2 ;
}
if ( m_pOptions - > m_bDmFullAnalysis )
{
if ( mfi . m_bExistsInA & & mfi . m_bDirA | | mfi . m_bExistsInB & & mfi . m_bDirB | | mfi . m_bExistsInC & & mfi . m_bDirC )
{
// If any input is a directory, don't start any comparison.
mfi . m_bEqualAB = mfi . m_bExistsInA & & mfi . m_bExistsInB ;
mfi . m_bEqualAC = mfi . m_bExistsInA & & mfi . m_bExistsInC ;
mfi . m_bEqualBC = mfi . m_bExistsInB & & mfi . m_bExistsInC ;
}
else
{
emit startDiffMerge (
mfi . m_bExistsInA ? mfi . m_fileInfoA . absFilePath ( ) : TQString ( " " ) ,
mfi . m_bExistsInB ? mfi . m_fileInfoB . absFilePath ( ) : TQString ( " " ) ,
mfi . m_bExistsInC ? mfi . m_fileInfoC . absFilePath ( ) : TQString ( " " ) ,
" " ,
" " , " " , " " , & mfi . m_totalDiffStatus
) ;
int nofNonwhiteConflicts = mfi . m_totalDiffStatus . nofUnsolvedConflicts +
mfi . m_totalDiffStatus . nofSolvedConflicts - mfi . m_totalDiffStatus . nofWhitespaceConflicts ;
if ( m_pOptions - > m_bDmWhiteSpaceEqual & & nofNonwhiteConflicts = = 0 )
{
mfi . m_bEqualAB = mfi . m_bExistsInA & & mfi . m_bExistsInB ;
mfi . m_bEqualAC = mfi . m_bExistsInA & & mfi . m_bExistsInC ;
mfi . m_bEqualBC = mfi . m_bExistsInB & & mfi . m_bExistsInC ;
}
else
{
mfi . m_bEqualAB = mfi . m_totalDiffStatus . bBinaryAEqB ;
mfi . m_bEqualBC = mfi . m_totalDiffStatus . bBinaryBEqC ;
mfi . m_bEqualAC = mfi . m_totalDiffStatus . bBinaryAEqC ;
}
}
}
else
{
bool bError ;
TQString eqStatus ;
if ( mfi . m_bExistsInA & & mfi . m_bExistsInB )
{
if ( mfi . m_bDirA ) mfi . m_bEqualAB = true ;
else fastFileComparison ( mfi . m_fileInfoA , mfi . m_fileInfoB , mfi . m_bEqualAB , bError , eqStatus ) ;
}
if ( mfi . m_bExistsInA & & mfi . m_bExistsInC )
{
if ( mfi . m_bDirA ) mfi . m_bEqualAC = true ;
else fastFileComparison ( mfi . m_fileInfoA , mfi . m_fileInfoC , mfi . m_bEqualAC , bError , eqStatus ) ;
}
if ( mfi . m_bExistsInB & & mfi . m_bExistsInC )
{
if ( mfi . m_bEqualAB & & mfi . m_bEqualAC )
mfi . m_bEqualBC = true ;
else
{
if ( mfi . m_bDirB ) mfi . m_bEqualBC = true ;
else fastFileComparison ( mfi . m_fileInfoB , mfi . m_fileInfoC , mfi . m_bEqualBC , bError , eqStatus ) ;
}
}
}
if ( mfi . m_bLinkA ! = mfi . m_bLinkB ) mfi . m_bEqualAB = false ;
if ( mfi . m_bLinkA ! = mfi . m_bLinkC ) mfi . m_bEqualAC = false ;
if ( mfi . m_bLinkB ! = mfi . m_bLinkC ) mfi . m_bEqualBC = false ;
if ( mfi . m_bDirA ! = mfi . m_bDirB ) mfi . m_bEqualAB = false ;
if ( mfi . m_bDirA ! = mfi . m_bDirC ) mfi . m_bEqualAC = false ;
if ( mfi . m_bDirB ! = mfi . m_bDirC ) mfi . m_bEqualBC = false ;
assert ( eNew = = 0 & & eMiddle = = 1 & & eOld = = 2 ) ;
// The map automatically sorts the keys.
int age = eNew ;
std : : map < TQDateTime , int > : : reverse_iterator i ;
for ( i = dateMap . rbegin ( ) ; i ! = dateMap . rend ( ) ; + + i )
{
int n = i - > second ;
if ( n = = 0 & & mfi . m_ageA = = eNotThere )
{
mfi . m_ageA = ( e_Age ) age ; + + age ;
if ( mfi . m_bEqualAB ) { mfi . m_ageB = mfi . m_ageA ; + + age ; }
if ( mfi . m_bEqualAC ) { mfi . m_ageC = mfi . m_ageA ; + + age ; }
}
else if ( n = = 1 & & mfi . m_ageB = = eNotThere )
{
mfi . m_ageB = ( e_Age ) age ; + + age ;
if ( mfi . m_bEqualAB ) { mfi . m_ageA = mfi . m_ageB ; + + age ; }
if ( mfi . m_bEqualBC ) { mfi . m_ageC = mfi . m_ageB ; + + age ; }
}
else if ( n = = 2 & & mfi . m_ageC = = eNotThere )
{
mfi . m_ageC = ( e_Age ) age ; + + age ;
if ( mfi . m_bEqualAC ) { mfi . m_ageA = mfi . m_ageC ; + + age ; }
if ( mfi . m_bEqualBC ) { mfi . m_ageB = mfi . m_ageC ; + + age ; }
}
}
// The checks below are necessary when the dates of the file are equal but the
// files are not. One wouldn't expect this to happen, yet it happens sometimes.
if ( mfi . m_bExistsInC & & mfi . m_ageC = = eNotThere )
{
mfi . m_ageC = ( e_Age ) age ; + + age ;
mfi . m_bConflictingAges = true ;
}
if ( mfi . m_bExistsInB & & mfi . m_ageB = = eNotThere )
{
mfi . m_ageB = ( e_Age ) age ; + + age ;
mfi . m_bConflictingAges = true ;
}
if ( mfi . m_bExistsInA & & mfi . m_ageA = = eNotThere )
{
mfi . m_ageA = ( e_Age ) age ; + + age ;
mfi . m_bConflictingAges = true ;
}
if ( mfi . m_ageA ! = eOld & & mfi . m_ageB ! = eOld & & mfi . m_ageC ! = eOld )
{
if ( mfi . m_ageA = = eMiddle ) mfi . m_ageA = eOld ;
if ( mfi . m_ageB = = eMiddle ) mfi . m_ageB = eOld ;
if ( mfi . m_ageC = = eMiddle ) mfi . m_ageC = eOld ;
}
}
static TQPixmap * s_pm_dir ;
static TQPixmap * s_pm_file ;
static TQPixmap * pmNotThere ;
static TQPixmap * pmNew ;
static TQPixmap * pmOld ;
static TQPixmap * pmMiddle ;
static TQPixmap * pmLink ;
static TQPixmap * pmDirLink ;
static TQPixmap * pmFileLink ;
static TQPixmap * pmNewLink ;
static TQPixmap * pmOldLink ;
static TQPixmap * pmMiddleLink ;
static TQPixmap * pmNewDir ;
static TQPixmap * pmMiddleDir ;
static TQPixmap * pmOldDir ;
static TQPixmap * pmNewDirLink ;
static TQPixmap * pmMiddleDirLink ;
static TQPixmap * pmOldDirLink ;
static TQPixmap colorToPixmap ( TQColor c )
{
TQPixmap pm ( 16 , 16 ) ;
TQPainter p ( & pm ) ;
p . setPen ( TQt : : black ) ;
p . setBrush ( c ) ;
p . drawRect ( 0 , 0 , pm . width ( ) , pm . height ( ) ) ;
return pm ;
}
static void initPixmaps ( TQColor newest , TQColor oldest , TQColor middle , TQColor notThere )
{
if ( pmNew = = 0 )
{
pmNotThere = new TQPixmap ;
pmNew = new TQPixmap ;
pmOld = new TQPixmap ;
pmMiddle = new TQPixmap ;
# include "xpm/link_arrow.xpm"
pmLink = new TQPixmap ( link_arrow ) ;
pmDirLink = new TQPixmap ;
pmFileLink = new TQPixmap ;
pmNewLink = new TQPixmap ;
pmOldLink = new TQPixmap ;
pmMiddleLink = new TQPixmap ;
pmNewDir = new TQPixmap ;
pmMiddleDir = new TQPixmap ;
pmOldDir = new TQPixmap ;
pmNewDirLink = new TQPixmap ;
pmMiddleDirLink = new TQPixmap ;
pmOldDirLink = new TQPixmap ;
}
* pmNotThere = colorToPixmap ( notThere ) ;
* pmNew = colorToPixmap ( newest ) ;
* pmOld = colorToPixmap ( oldest ) ;
* pmMiddle = colorToPixmap ( middle ) ;
* pmDirLink = pixCombiner ( s_pm_dir , pmLink ) ;
* pmFileLink = pixCombiner ( s_pm_file , pmLink ) ;
* pmNewLink = pixCombiner ( pmNew , pmLink ) ;
* pmOldLink = pixCombiner ( pmOld , pmLink ) ;
* pmMiddleLink = pixCombiner ( pmMiddle , pmLink ) ;
* pmNewDir = pixCombiner2 ( pmNew , s_pm_dir ) ;
* pmMiddleDir = pixCombiner2 ( pmMiddle , s_pm_dir ) ;
* pmOldDir = pixCombiner2 ( pmOld , s_pm_dir ) ;
* pmNewDirLink = pixCombiner ( pmNewDir , pmLink ) ;
* pmMiddleDirLink = pixCombiner ( pmMiddleDir , pmLink ) ;
* pmOldDirLink = pixCombiner ( pmOldDir , pmLink ) ;
}
static void setOnePixmap ( TQListViewItem * pLVI , int col , e_Age eAge , bool bLink , bool bDir )
{
static TQPixmap * ageToPm [ ] = { pmNew , pmMiddle , pmOld , pmNotThere , s_pm_file } ;
static TQPixmap * ageToPmLink [ ] = { pmNewLink , pmMiddleLink , pmOldLink , pmNotThere , pmFileLink } ;
static TQPixmap * ageToPmDir [ ] = { pmNewDir , pmMiddleDir , pmOldDir , pmNotThere , s_pm_dir } ;
static TQPixmap * ageToPmDirLink [ ] = { pmNewDirLink , pmMiddleDirLink , pmOldDirLink , pmNotThere , pmDirLink } ;
TQPixmap * * ppPm = bDir ? ( bLink ? ageToPmDirLink : ageToPmDir ) :
( bLink ? ageToPmLink : ageToPm ) ;
pLVI - > setPixmap ( col , * ppPm [ eAge ] ) ;
}
static void setPixmaps ( MergeFileInfos & mfi , bool bCheckC )
{
setOnePixmap ( mfi . m_pDMI , s_nameCol , eAgeEnd ,
mfi . m_bLinkA | | mfi . m_bLinkB | | mfi . m_bLinkC ,
mfi . m_bDirA | | mfi . m_bDirB | | mfi . m_bDirC
) ;
if ( mfi . m_bDirA | | mfi . m_bDirB | | mfi . m_bDirC )
{
mfi . m_ageA = eNotThere ;
mfi . m_ageB = eNotThere ;
mfi . m_ageC = eNotThere ;
int age = eNew ;
if ( mfi . m_bExistsInC )
{
mfi . m_ageC = ( e_Age ) age ;
if ( mfi . m_bEqualAC ) mfi . m_ageA = ( e_Age ) age ;
if ( mfi . m_bEqualBC ) mfi . m_ageB = ( e_Age ) age ;
+ + age ;
}
if ( mfi . m_bExistsInB & & mfi . m_ageB = = eNotThere )
{
mfi . m_ageB = ( e_Age ) age ;
if ( mfi . m_bEqualAB ) mfi . m_ageA = ( e_Age ) age ;
+ + age ;
}
if ( mfi . m_bExistsInA & & mfi . m_ageA = = eNotThere )
{
mfi . m_ageA = ( e_Age ) age ;
}
if ( mfi . m_ageA ! = eOld & & mfi . m_ageB ! = eOld & & mfi . m_ageC ! = eOld )
{
if ( mfi . m_ageA = = eMiddle ) mfi . m_ageA = eOld ;
if ( mfi . m_ageB = = eMiddle ) mfi . m_ageB = eOld ;
if ( mfi . m_ageC = = eMiddle ) mfi . m_ageC = eOld ;
}
}
setOnePixmap ( mfi . m_pDMI , s_ACol , mfi . m_ageA , mfi . m_bLinkA , mfi . m_bDirA ) ;
setOnePixmap ( mfi . m_pDMI , s_BCol , mfi . m_ageB , mfi . m_bLinkB , mfi . m_bDirB ) ;
if ( bCheckC )
setOnePixmap ( mfi . m_pDMI , s_CCol , mfi . m_ageC , mfi . m_bLinkC , mfi . m_bDirC ) ;
}
// Iterate through the complete tree. Start by specifying TQListView::firstChild().
static TQListViewItem * treeIterator ( TQListViewItem * p , bool bVisitChildren = true , bool bFindInvisible = false )
{
if ( p ! = 0 )
{
do
{
if ( bVisitChildren & & p - > firstChild ( ) ! = 0 ) p = p - > firstChild ( ) ;
else if ( p - > nextSibling ( ) ! = 0 ) p = p - > nextSibling ( ) ;
else
{
p = p - > parent ( ) ;
while ( p ! = 0 )
{
if ( p - > nextSibling ( ) ! = 0 ) { p = p - > nextSibling ( ) ; break ; }
else { p = p - > parent ( ) ; }
}
}
}
while ( p & & ! ( p - > isVisible ( ) | | bFindInvisible ) ) ;
}
return p ;
}
void DirectoryMergeWindow : : prepareListView ( ProgressProxy & pp )
{
static bool bFirstTime = true ;
if ( bFirstTime )
{
# include "xpm/file.xpm"
# include "xpm/folder.xpm"
s_pm_dir = new TQPixmap ( m_pIconLoader - > loadIcon ( " folder " , TDEIcon : : Small ) ) ;
if ( s_pm_dir - > size ( ) ! = TQSize ( 16 , 16 ) )
{
delete s_pm_dir ;
s_pm_dir = new TQPixmap ( folder_pm ) ;
}
s_pm_file = new TQPixmap ( file_pm ) ;
bFirstTime = false ;
}
clear ( ) ;
initPixmaps ( m_pOptions - > m_newestFileColor , m_pOptions - > m_oldestFileColor ,
m_pOptions - > m_midAgeFileColor , m_pOptions - > m_missingFileColor ) ;
setRootIsDecorated ( true ) ;
bool bCheckC = m_dirC . isValid ( ) ;
std : : map < TQString , MergeFileInfos > : : iterator j ;
int nrOfFiles = m_fileMergeMap . size ( ) ;
int currentIdx = 1 ;
TQTime t ;
t . start ( ) ;
for ( j = m_fileMergeMap . begin ( ) ; j ! = m_fileMergeMap . end ( ) ; + + j )
{
MergeFileInfos & mfi = j - > second ;
mfi . m_subPath = mfi . m_fileInfoA . exists ( ) ? mfi . m_fileInfoA . filePath ( ) :
mfi . m_fileInfoB . exists ( ) ? mfi . m_fileInfoB . filePath ( ) :
mfi . m_fileInfoC . exists ( ) ? mfi . m_fileInfoC . filePath ( ) :
TQString ( " " ) ;
// const TQString& fileName = j->first;
const TQString & fileName = mfi . m_subPath ;
pp . setInformation (
i18n ( " Processing " ) + TQString : : number ( currentIdx ) + " / " + TQString : : number ( nrOfFiles )
+ " \n " + fileName , double ( currentIdx ) / nrOfFiles , false ) ;
if ( pp . wasCancelled ( ) ) break ;
+ + currentIdx ;
// The comparisons and calculations for each file take place here.
compareFilesAndCalcAges ( mfi ) ;
bool bEqual = bCheckC ? mfi . m_bEqualAB & & mfi . m_bEqualAC : mfi . m_bEqualAB ;
//bool bDir = mfi.m_bDirA || mfi.m_bDirB || mfi.m_bDirC;
//if ( m_pOptions->m_bDmShowOnlyDeltas && !bDir && bEqual )
// continue;
// Get dirname from fileName: Search for "/" from end:
int pos = fileName . findRev ( ' / ' ) ;
TQString dirPart ;
TQString filePart ;
if ( pos = = - 1 )
{
// Top dir
filePart = fileName ;
}
else
{
dirPart = fileName . left ( pos ) ;
filePart = fileName . mid ( pos + 1 ) ;
}
if ( dirPart . isEmpty ( ) ) // Top level
{
new DirMergeItem ( this , filePart , & mfi ) ;
}
else
{
MergeFileInfos & dirMfi = m_fileMergeMap [ sortString ( dirPart , m_bCaseSensitive ) ] ; // parent
assert ( dirMfi . m_pDMI ! = 0 ) ;
new DirMergeItem ( dirMfi . m_pDMI , filePart , & mfi ) ;
mfi . m_pParent = & dirMfi ;
if ( ! bEqual ) // Set all parents to "not equal"
{
MergeFileInfos * p = mfi . m_pParent ;
while ( p ! = 0 )
{
bool bChange = false ;
if ( ! mfi . m_bEqualAB & & p - > m_bEqualAB ) { p - > m_bEqualAB = false ; bChange = true ; }
if ( ! mfi . m_bEqualAC & & p - > m_bEqualAC ) { p - > m_bEqualAC = false ; bChange = true ; }
if ( ! mfi . m_bEqualBC & & p - > m_bEqualBC ) { p - > m_bEqualBC = false ; bChange = true ; }
if ( bChange )
setPixmaps ( * p , bCheckC ) ;
else
break ;
p = p - > m_pParent ;
}
}
}
setPixmaps ( mfi , bCheckC ) ;
}
/*if ( m_pOptions->m_bDmShowOnlyDeltas )
{
// Remove all equals. (Search tree depth first)
TQListViewItem * p = firstChild ( ) ;
while ( p ! = 0 & & firstChild ( ) ! = 0 )
{
TQListViewItem * pParent = p - > parent ( ) ;
TQListViewItem * pNextSibling = p - > nextSibling ( ) ;
DirMergeItem * pDMI = static_cast < DirMergeItem * > ( p ) ;
bool bDirEqual = bCheckC ? pDMI - > m_pMFI - > m_bEqualAB & & pDMI - > m_pMFI - > m_bEqualAC
: pDMI - > m_pMFI - > m_bEqualAB ;
if ( pDMI ! = 0 & & pDMI - > m_pMFI - > m_bDirA & & bDirEqual )
{
delete p ;
p = 0 ;
}
if ( p ! = 0 & & p - > firstChild ( ) ! = 0 ) p = p - > firstChild ( ) ;
else if ( pNextSibling ! = 0 ) p = pNextSibling ;
else
{
p = pParent ;
while ( p ! = 0 )
{
if ( p - > nextSibling ( ) ! = 0 ) { p = p - > nextSibling ( ) ; break ; }
else { p = p - > parent ( ) ; }
}
}
}
} */
}
static bool conflictingFileTypes ( MergeFileInfos & mfi )
{
// Now check if file/dir-types fit.
if ( mfi . m_bLinkA | | mfi . m_bLinkB | | mfi . m_bLinkC )
{
if ( mfi . m_bExistsInA & & ! mfi . m_bLinkA | |
mfi . m_bExistsInB & & ! mfi . m_bLinkB | |
mfi . m_bExistsInC & & ! mfi . m_bLinkC )
{
return true ;
}
}
if ( mfi . m_bDirA | | mfi . m_bDirB | | mfi . m_bDirC )
{
if ( mfi . m_bExistsInA & & ! mfi . m_bDirA | |
mfi . m_bExistsInB & & ! mfi . m_bDirB | |
mfi . m_bExistsInC & & ! mfi . m_bDirC )
{
return true ;
}
}
return false ;
}
void DirectoryMergeWindow : : calcSuggestedOperation ( MergeFileInfos & mfi , e_MergeOperation eDefaultMergeOp )
{
bool bCheckC = m_dirC . isValid ( ) ;
bool bCopyNewer = m_pOptions - > m_bDmCopyNewer ;
bool bOtherDest = ! ( m_dirDestInternal . absFilePath ( ) = = m_dirA . absFilePath ( ) | |
m_dirDestInternal . absFilePath ( ) = = m_dirB . absFilePath ( ) | |
bCheckC & & m_dirDestInternal . absFilePath ( ) = = m_dirC . absFilePath ( ) ) ;
if ( eDefaultMergeOp = = eMergeABCToDest & & ! bCheckC ) { eDefaultMergeOp = eMergeABToDest ; }
if ( eDefaultMergeOp = = eMergeToAB & & bCheckC ) { assert ( false ) ; }
if ( eDefaultMergeOp = = eMergeToA | | eDefaultMergeOp = = eMergeToB | |
eDefaultMergeOp = = eMergeABCToDest | | eDefaultMergeOp = = eMergeABToDest | | eDefaultMergeOp = = eMergeToAB )
{
if ( ! bCheckC )
{
if ( mfi . m_bEqualAB )
{
mfi . setMergeOperation ( bOtherDest ? eCopyBToDest : eNoOperation ) ;
}
else if ( mfi . m_bExistsInA & & mfi . m_bExistsInB )
{
if ( ! bCopyNewer | | mfi . m_bDirA )
mfi . setMergeOperation ( eDefaultMergeOp ) ;
else if ( bCopyNewer & & mfi . m_bConflictingAges )
{
mfi . setMergeOperation ( eConflictingAges ) ;
}
else
{
if ( mfi . m_ageA = = eNew )
mfi . setMergeOperation ( eDefaultMergeOp = = eMergeToAB ? eCopyAToB : eCopyAToDest ) ;
else
mfi . setMergeOperation ( eDefaultMergeOp = = eMergeToAB ? eCopyBToA : eCopyBToDest ) ;
}
}
else if ( ! mfi . m_bExistsInA & & mfi . m_bExistsInB )
{
if ( eDefaultMergeOp = = eMergeABToDest ) mfi . setMergeOperation ( eCopyBToDest ) ;
else if ( eDefaultMergeOp = = eMergeToB ) mfi . setMergeOperation ( eNoOperation ) ;
else mfi . setMergeOperation ( eCopyBToA ) ;
}
else if ( mfi . m_bExistsInA & & ! mfi . m_bExistsInB )
{
if ( eDefaultMergeOp = = eMergeABToDest ) mfi . setMergeOperation ( eCopyAToDest ) ;
else if ( eDefaultMergeOp = = eMergeToA ) mfi . setMergeOperation ( eNoOperation ) ;
else mfi . setMergeOperation ( eCopyAToB ) ;
}
else //if ( !mfi.m_bExistsInA && !mfi.m_bExistsInB )
{
mfi . setMergeOperation ( eNoOperation ) ; assert ( false ) ;
}
}
else
{
if ( mfi . m_bEqualAB & & mfi . m_bEqualAC )
{
mfi . setMergeOperation ( bOtherDest ? eCopyCToDest : eNoOperation ) ;
}
else if ( mfi . m_bExistsInA & & mfi . m_bExistsInB & & mfi . m_bExistsInC )
{
if ( mfi . m_bEqualAB )
mfi . setMergeOperation ( eCopyCToDest ) ;
else if ( mfi . m_bEqualAC )
mfi . setMergeOperation ( eCopyBToDest ) ;
else if ( mfi . m_bEqualBC )
mfi . setMergeOperation ( eCopyCToDest ) ;
else
mfi . setMergeOperation ( eMergeABCToDest ) ;
}
else if ( mfi . m_bExistsInA & & mfi . m_bExistsInB & & ! mfi . m_bExistsInC )
{
if ( mfi . m_bEqualAB )
mfi . setMergeOperation ( eDeleteFromDest ) ;
else
mfi . setMergeOperation ( eCopyBToDest ) ;
}
else if ( mfi . m_bExistsInA & & ! mfi . m_bExistsInB & & mfi . m_bExistsInC )
{
if ( mfi . m_bEqualAC )
mfi . setMergeOperation ( eDeleteFromDest ) ;
else
mfi . setMergeOperation ( eCopyCToDest ) ;
}
else if ( ! mfi . m_bExistsInA & & mfi . m_bExistsInB & & mfi . m_bExistsInC )
{
if ( mfi . m_bEqualBC )
mfi . setMergeOperation ( eCopyCToDest ) ;
else
mfi . setMergeOperation ( eMergeABCToDest ) ;
}
else if ( ! mfi . m_bExistsInA & & ! mfi . m_bExistsInB & & mfi . m_bExistsInC )
{
mfi . setMergeOperation ( eCopyCToDest ) ;
}
else if ( ! mfi . m_bExistsInA & & mfi . m_bExistsInB & & ! mfi . m_bExistsInC )
{
mfi . setMergeOperation ( eCopyBToDest ) ;
}
else if ( mfi . m_bExistsInA & & ! mfi . m_bExistsInB & & ! mfi . m_bExistsInC )
{
mfi . setMergeOperation ( eDeleteFromDest ) ;
}
else //if ( !mfi.m_bExistsInA && !mfi.m_bExistsInB && !mfi.m_bExistsInC )
{
mfi . setMergeOperation ( eNoOperation ) ; assert ( false ) ;
}
}
// Now check if file/dir-types fit.
if ( conflictingFileTypes ( mfi ) )
{
mfi . setMergeOperation ( eConflictingFileTypes ) ;
}
}
else
{
e_MergeOperation eMO = eDefaultMergeOp ;
switch ( eDefaultMergeOp )
{
case eConflictingFileTypes :
case eConflictingAges :
case eDeleteA :
case eDeleteB :
case eDeleteAB :
case eDeleteFromDest :
case eNoOperation : break ;
case eCopyAToB : if ( ! mfi . m_bExistsInA ) { eMO = eDeleteB ; } break ;
case eCopyBToA : if ( ! mfi . m_bExistsInB ) { eMO = eDeleteA ; } break ;
case eCopyAToDest : if ( ! mfi . m_bExistsInA ) { eMO = eDeleteFromDest ; } break ;
case eCopyBToDest : if ( ! mfi . m_bExistsInB ) { eMO = eDeleteFromDest ; } break ;
case eCopyCToDest : if ( ! mfi . m_bExistsInC ) { eMO = eDeleteFromDest ; } break ;
case eMergeToA :
case eMergeToB :
case eMergeToAB :
case eMergeABCToDest :
case eMergeABToDest :
default :
assert ( false ) ;
}
mfi . setMergeOperation ( eMO ) ;
}
}
void DirectoryMergeWindow : : onDoubleClick ( TQListViewItem * lvi )
{
if ( lvi = = 0 ) return ;
if ( m_bDirectoryMerge )
mergeCurrentFile ( ) ;
else
compareCurrentFile ( ) ;
}
void DirectoryMergeWindow : : onSelectionChanged ( TQListViewItem * lvi )
{
if ( lvi = = 0 ) return ;
DirMergeItem * pDMI = static_cast < DirMergeItem * > ( lvi ) ;
MergeFileInfos & mfi = * pDMI - > m_pMFI ;
assert ( mfi . m_pDMI = = pDMI ) ;
m_pDirectoryMergeInfo - > setInfo ( m_dirA , m_dirB , m_dirC , m_dirDestInternal , mfi ) ;
}
void DirectoryMergeWindow : : onClick ( int button , TQListViewItem * lvi , const TQPoint & p , int c )
{
if ( lvi = = 0 ) return ;
DirMergeItem * pDMI = static_cast < DirMergeItem * > ( lvi ) ;
MergeFileInfos & mfi = * pDMI - > m_pMFI ;
assert ( mfi . m_pDMI = = pDMI ) ;
if ( c = = s_OpCol )
{
bool bThreeDirs = m_dirC . isValid ( ) ;
TDEPopupMenu m ( this ) ;
if ( bThreeDirs )
{
m_pDirCurrentDoNothing - > plug ( & m ) ;
int count = 0 ;
if ( mfi . m_bExistsInA ) { m_pDirCurrentChooseA - > plug ( & m ) ; + + count ; }
if ( mfi . m_bExistsInB ) { m_pDirCurrentChooseB - > plug ( & m ) ; + + count ; }
if ( mfi . m_bExistsInC ) { m_pDirCurrentChooseC - > plug ( & m ) ; + + count ; }
if ( ! conflictingFileTypes ( mfi ) & & count > 1 ) m_pDirCurrentMerge - > plug ( & m ) ;
m_pDirCurrentDelete - > plug ( & m ) ;
}
else if ( m_bSyncMode )
{
m_pDirCurrentSyncDoNothing - > plug ( & m ) ;
if ( mfi . m_bExistsInA ) m_pDirCurrentSyncCopyAToB - > plug ( & m ) ;
if ( mfi . m_bExistsInB ) m_pDirCurrentSyncCopyBToA - > plug ( & m ) ;
if ( mfi . m_bExistsInA ) m_pDirCurrentSyncDeleteA - > plug ( & m ) ;
if ( mfi . m_bExistsInB ) m_pDirCurrentSyncDeleteB - > plug ( & m ) ;
if ( mfi . m_bExistsInA & & mfi . m_bExistsInB )
{
m_pDirCurrentSyncDeleteAAndB - > plug ( & m ) ;
if ( ! conflictingFileTypes ( mfi ) )
{
m_pDirCurrentSyncMergeToA - > plug ( & m ) ;
m_pDirCurrentSyncMergeToB - > plug ( & m ) ;
m_pDirCurrentSyncMergeToAAndB - > plug ( & m ) ;
}
}
}
else
{
m_pDirCurrentDoNothing - > plug ( & m ) ;
if ( mfi . m_bExistsInA ) { m_pDirCurrentChooseA - > plug ( & m ) ; }
if ( mfi . m_bExistsInB ) { m_pDirCurrentChooseB - > plug ( & m ) ; }
if ( ! conflictingFileTypes ( mfi ) & & mfi . m_bExistsInA & & mfi . m_bExistsInB ) m_pDirCurrentMerge - > plug ( & m ) ;
m_pDirCurrentDelete - > plug ( & m ) ;
}
m . exec ( p ) ;
}
else if ( c = = s_ACol | | c = = s_BCol | | c = = s_CCol )
{
TQString itemPath ;
if ( c = = s_ACol & & mfi . m_bExistsInA ) { itemPath = fullNameA ( mfi ) ; }
else if ( c = = s_BCol & & mfi . m_bExistsInB ) { itemPath = fullNameB ( mfi ) ; }
else if ( c = = s_CCol & & mfi . m_bExistsInC ) { itemPath = fullNameC ( mfi ) ; }
if ( ! itemPath . isEmpty ( ) )
{
selectItemAndColumn ( pDMI , c , button = = Qt : : RightButton ) ;
}
}
}
void DirectoryMergeWindow : : slotShowContextMenu ( TQListViewItem * lvi , const TQPoint & p , int c )
{
if ( lvi = = 0 ) return ;
DirMergeItem * pDMI = static_cast < DirMergeItem * > ( lvi ) ;
MergeFileInfos & mfi = * pDMI - > m_pMFI ;
assert ( mfi . m_pDMI = = pDMI ) ;
if ( c = = s_ACol | | c = = s_BCol | | c = = s_CCol )
{
TQString itemPath ;
if ( c = = s_ACol & & mfi . m_bExistsInA ) { itemPath = fullNameA ( mfi ) ; }
else if ( c = = s_BCol & & mfi . m_bExistsInB ) { itemPath = fullNameB ( mfi ) ; }
else if ( c = = s_CCol & & mfi . m_bExistsInC ) { itemPath = fullNameC ( mfi ) ; }
if ( ! itemPath . isEmpty ( ) )
{
selectItemAndColumn ( pDMI , c , true ) ;
TDEPopupMenu m ( this ) ;
m_pDirCompareExplicit - > plug ( & m ) ;
m_pDirMergeExplicit - > plug ( & m ) ;
# ifndef _WIN32
m . exec ( p ) ;
# else
void showShellContextMenu ( const TQString & , TQPoint , TQWidget * , TQPopupMenu * ) ;
showShellContextMenu ( itemPath , p , this , & m ) ;
# endif
}
}
}
static TQString getFileName ( DirMergeItem * pDMI , int column )
{
if ( pDMI ! = 0 )
{
MergeFileInfos & mfi = * pDMI - > m_pMFI ;
return column = = s_ACol ? mfi . m_fileInfoA . absFilePath ( ) :
column = = s_BCol ? mfi . m_fileInfoB . absFilePath ( ) :
column = = s_CCol ? mfi . m_fileInfoC . absFilePath ( ) :
TQString ( " " ) ;
}
return " " ;
}
static bool isDir ( DirMergeItem * pDMI , int column )
{
if ( pDMI ! = 0 )
{
MergeFileInfos & mfi = * pDMI - > m_pMFI ;
return column = = s_ACol ? mfi . m_bDirA :
column = = s_BCol ? mfi . m_bDirB :
mfi . m_bDirC ;
}
return false ;
}
void DirectoryMergeWindow : : selectItemAndColumn ( DirMergeItem * pDMI , int c , bool bContextMenu )
{
if ( bContextMenu & & (
pDMI = = m_pSelection1Item & & c = = m_selection1Column | |
pDMI = = m_pSelection2Item & & c = = m_selection2Column | |
pDMI = = m_pSelection3Item & & c = = m_selection3Column ) )
return ;
DirMergeItem * pOld1 = m_pSelection1Item ;
DirMergeItem * pOld2 = m_pSelection2Item ;
DirMergeItem * pOld3 = m_pSelection3Item ;
bool bReset = false ;
if ( m_pSelection1Item )
{
if ( isDir ( m_pSelection1Item , m_selection1Column ) ! = isDir ( pDMI , c ) )
bReset = true ;
}
if ( bReset | | m_pSelection3Item ! = 0 | |
pDMI = = m_pSelection1Item & & c = = m_selection1Column | |
pDMI = = m_pSelection2Item & & c = = m_selection2Column | |
pDMI = = m_pSelection3Item & & c = = m_selection3Column )
{
m_pSelection1Item = 0 ;
m_pSelection2Item = 0 ;
m_pSelection3Item = 0 ;
}
else if ( m_pSelection1Item = = 0 )
{
m_pSelection1Item = pDMI ;
m_selection1Column = c ;
m_pSelection2Item = 0 ;
m_pSelection3Item = 0 ;
}
else if ( m_pSelection2Item = = 0 )
{
m_pSelection2Item = pDMI ;
m_selection2Column = c ;
m_pSelection3Item = 0 ;
}
else if ( m_pSelection3Item = = 0 )
{
m_pSelection3Item = pDMI ;
m_selection3Column = c ;
}
if ( pOld1 ) repaintItem ( pOld1 ) ;
if ( pOld2 ) repaintItem ( pOld2 ) ;
if ( pOld3 ) repaintItem ( pOld3 ) ;
if ( m_pSelection1Item ) repaintItem ( m_pSelection1Item ) ;
if ( m_pSelection2Item ) repaintItem ( m_pSelection2Item ) ;
if ( m_pSelection3Item ) repaintItem ( m_pSelection3Item ) ;
emit updateAvailabilities ( ) ;
}
// Since TQt 2.3.0 doesn't allow the specification of a compare operator, this trick emulates it.
# define DIRSORT(x) x
DirMergeItem : : DirMergeItem ( TQListView * pParent , const TQString & fileName , MergeFileInfos * pMFI )
: TQListViewItem ( pParent , DIRSORT ( fileName ) , " " , " " , " " , i18n ( " To do. " ) , " " )
{
init ( pMFI ) ;
}
DirMergeItem : : DirMergeItem ( DirMergeItem * pParent , const TQString & fileName , MergeFileInfos * pMFI )
: TQListViewItem ( pParent , DIRSORT ( fileName ) , " " , " " , " " , i18n ( " To do. " ) , " " )
{
init ( pMFI ) ;
}
void DirMergeItem : : init ( MergeFileInfos * pMFI )
{
pMFI - > m_pDMI = this ;
m_pMFI = pMFI ;
TotalDiffStatus & tds = pMFI - > m_totalDiffStatus ;
if ( m_pMFI - > m_bDirA | | m_pMFI - > m_bDirB | | m_pMFI - > m_bDirC )
{
}
else
{
setText ( s_UnsolvedCol , TQString : : number ( tds . nofUnsolvedConflicts ) ) ;
setText ( s_SolvedCol , TQString : : number ( tds . nofSolvedConflicts ) ) ;
setText ( s_NonWhiteCol , TQString : : number ( tds . nofUnsolvedConflicts + tds . nofSolvedConflicts - tds . nofWhitespaceConflicts ) ) ;
setText ( s_WhiteCol , TQString : : number ( tds . nofWhitespaceConflicts ) ) ;
}
}
int DirMergeItem : : compare ( TQListViewItem * i , int col , bool ascending ) const
{
DirMergeItem * pDMI = static_cast < DirMergeItem * > ( i ) ;
bool bDir1 = m_pMFI - > m_bDirA | | m_pMFI - > m_bDirB | | m_pMFI - > m_bDirC ;
bool bDir2 = pDMI - > m_pMFI - > m_bDirA | | pDMI - > m_pMFI - > m_bDirB | | pDMI - > m_pMFI - > m_bDirC ;
if ( m_pMFI = = 0 | | pDMI - > m_pMFI = = 0 | | bDir1 = = bDir2 )
{
if ( col = = s_UnsolvedCol | | col = = s_SolvedCol | | col = = s_NonWhiteCol | | col = = s_WhiteCol )
return key ( col , ascending ) . toInt ( ) > i - > key ( col , ascending ) . toInt ( ) ? - 1 : 1 ;
else
return TQListViewItem : : compare ( i , col , ascending ) ;
}
else
return bDir1 ? - 1 : 1 ;
}
void DirMergeItem : : paintCell ( TQPainter * p , const TQColorGroup & cg , int column , int width , int align )
{
if ( column = = s_ACol | | column = = s_BCol | | column = = s_CCol )
{
const TQPixmap * icon = pixmap ( column ) ;
if ( icon )
{
int yOffset = ( height ( ) - icon - > height ( ) ) / 2 ;
p - > fillRect ( 0 , 0 , width , height ( ) , cg . base ( ) ) ;
p - > drawPixmap ( 2 , yOffset , * icon ) ;
if ( listView ( ) )
{
DirectoryMergeWindow * pDMW = static_cast < DirectoryMergeWindow * > ( listView ( ) ) ;
int i = this = = pDMW - > m_pSelection1Item & & column = = pDMW - > m_selection1Column ? 1 :
this = = pDMW - > m_pSelection2Item & & column = = pDMW - > m_selection2Column ? 2 :
this = = pDMW - > m_pSelection3Item & & column = = pDMW - > m_selection3Column ? 3 :
0 ;
if ( i ! = 0 )
{
OptionDialog * pOD = pDMW - > m_pOptions ;
TQColor c ( i = = 1 ? pOD - > m_colorA : i = = 2 ? pOD - > m_colorB : pOD - > m_colorC ) ;
p - > setPen ( c ) ; // highlight() );
p - > drawRect ( 2 , yOffset , icon - > width ( ) , icon - > height ( ) ) ;
p - > setPen ( TQPen ( c , 0 , TQt : : DotLine ) ) ;
p - > drawRect ( 1 , yOffset - 1 , icon - > width ( ) + 2 , icon - > height ( ) + 2 ) ;
p - > setPen ( cg . background ( ) ) ;
TQString s ( TQChar ( ' A ' + i - 1 ) ) ;
p - > drawText ( 2 + ( icon - > width ( ) - p - > fontMetrics ( ) . width ( s ) ) / 2 ,
yOffset + ( icon - > height ( ) + p - > fontMetrics ( ) . ascent ( ) ) / 2 - 1 ,
s ) ;
}
else
{
p - > setPen ( cg . background ( ) ) ;
p - > drawRect ( 1 , yOffset - 1 , icon - > width ( ) + 2 , icon - > height ( ) + 2 ) ;
}
}
return ;
}
}
TQListViewItem : : paintCell ( p , cg , column , width , align ) ;
}
DirMergeItem : : ~ DirMergeItem ( )
{
m_pMFI - > m_pDMI = 0 ;
}
void MergeFileInfos : : setMergeOperation ( e_MergeOperation eMOp , bool bRecursive )
{
if ( eMOp ! = m_eMergeOperation )
{
m_bOperationComplete = false ;
m_pDMI - > setText ( s_OpStatusCol , " " ) ;
}
m_eMergeOperation = eMOp ;
TQString s ;
bool bDir = m_bDirA | | m_bDirB | | m_bDirC ;
if ( m_pDMI ! = 0 )
{
switch ( m_eMergeOperation )
{
case eNoOperation : s = " " ; m_pDMI - > setText ( s_OpCol , " " ) ; break ;
case eCopyAToB : s = i18n ( " Copy A to B " ) ; break ;
case eCopyBToA : s = i18n ( " Copy B to A " ) ; break ;
case eDeleteA : s = i18n ( " Delete A " ) ; break ;
case eDeleteB : s = i18n ( " Delete B " ) ; break ;
case eDeleteAB : s = i18n ( " Delete A & B " ) ; break ;
case eMergeToA : s = i18n ( " Merge to A " ) ; break ;
case eMergeToB : s = i18n ( " Merge to B " ) ; break ;
case eMergeToAB : s = i18n ( " Merge to A & B " ) ; break ;
case eCopyAToDest : s = " A " ; break ;
case eCopyBToDest : s = " B " ; break ;
case eCopyCToDest : s = " C " ; break ;
case eDeleteFromDest : s = i18n ( " Delete (if exists) " ) ; break ;
case eMergeABCToDest : s = bDir ? i18n ( " Merge " ) : i18n ( " Merge (manual) " ) ; break ;
case eMergeABToDest : s = bDir ? i18n ( " Merge " ) : i18n ( " Merge (manual) " ) ; break ;
case eConflictingFileTypes : s = i18n ( " Error: Conflicting File Types " ) ; break ;
case eConflictingAges : s = i18n ( " Error: Dates are equal but files are not. " ) ; break ;
default : assert ( false ) ; break ;
}
m_pDMI - > setText ( s_OpCol , s ) ;
if ( bRecursive )
{
e_MergeOperation eChildrenMergeOp = m_eMergeOperation ;
if ( eChildrenMergeOp = = eConflictingFileTypes ) eChildrenMergeOp = eMergeABCToDest ;
TQListViewItem * p = m_pDMI - > firstChild ( ) ;
while ( p ! = 0 )
{
DirMergeItem * pDMI = static_cast < DirMergeItem * > ( p ) ;
DirectoryMergeWindow * pDMW = static_cast < DirectoryMergeWindow * > ( p - > listView ( ) ) ;
pDMW - > calcSuggestedOperation ( * pDMI - > m_pMFI , eChildrenMergeOp ) ;
p = p - > nextSibling ( ) ;
}
}
}
}
void DirectoryMergeWindow : : compareCurrentFile ( )
{
if ( ! canContinue ( ) ) return ;
if ( m_bRealMergeStarted )
{
KMessageBox : : sorry ( this , i18n ( " This operation is currently not possible. " ) , i18n ( " Operation Not Possible " ) ) ;
return ;
}
DirMergeItem * pDMI = static_cast < DirMergeItem * > ( selectedItem ( ) ) ;
if ( pDMI ! = 0 )
{
MergeFileInfos & mfi = * pDMI - > m_pMFI ;
if ( ! ( mfi . m_bDirA | | mfi . m_bDirB | | mfi . m_bDirC ) )
{
emit startDiffMerge (
mfi . m_bExistsInA ? mfi . m_fileInfoA . absFilePath ( ) : TQString ( " " ) ,
mfi . m_bExistsInB ? mfi . m_fileInfoB . absFilePath ( ) : TQString ( " " ) ,
mfi . m_bExistsInC ? mfi . m_fileInfoC . absFilePath ( ) : TQString ( " " ) ,
" " ,
" " , " " , " " , 0
) ;
}
}
emit updateAvailabilities ( ) ;
}
void DirectoryMergeWindow : : slotCompareExplicitlySelectedFiles ( )
{
if ( ! isDir ( m_pSelection1Item , m_selection1Column ) & & ! canContinue ( ) ) return ;
if ( m_bRealMergeStarted )
{
KMessageBox : : sorry ( this , i18n ( " This operation is currently not possible. " ) , i18n ( " Operation Not Possible " ) ) ;
return ;
}
emit startDiffMerge (
getFileName ( m_pSelection1Item , m_selection1Column ) ,
getFileName ( m_pSelection2Item , m_selection2Column ) ,
getFileName ( m_pSelection3Item , m_selection3Column ) ,
" " ,
" " , " " , " " , 0
) ;
m_pSelection1Item = 0 ;
m_pSelection2Item = 0 ;
m_pSelection3Item = 0 ;
emit updateAvailabilities ( ) ;
triggerUpdate ( ) ;
}
void DirectoryMergeWindow : : slotMergeExplicitlySelectedFiles ( )
{
if ( ! isDir ( m_pSelection1Item , m_selection1Column ) & & ! canContinue ( ) ) return ;
if ( m_bRealMergeStarted )
{
KMessageBox : : sorry ( this , i18n ( " This operation is currently not possible. " ) , i18n ( " Operation Not Possible " ) ) ;
return ;
}
TQString fn1 = getFileName ( m_pSelection1Item , m_selection1Column ) ;
TQString fn2 = getFileName ( m_pSelection2Item , m_selection2Column ) ;
TQString fn3 = getFileName ( m_pSelection3Item , m_selection3Column ) ;
emit startDiffMerge ( fn1 , fn2 , fn3 ,
fn3 . isEmpty ( ) ? fn2 : fn3 ,
" " , " " , " " , 0
) ;
m_pSelection1Item = 0 ;
m_pSelection2Item = 0 ;
m_pSelection3Item = 0 ;
emit updateAvailabilities ( ) ;
triggerUpdate ( ) ;
}
bool DirectoryMergeWindow : : isFileSelected ( )
{
DirMergeItem * pDMI = static_cast < DirMergeItem * > ( selectedItem ( ) ) ;
if ( pDMI ! = 0 )
{
MergeFileInfos & mfi = * pDMI - > m_pMFI ;
return ! ( mfi . m_bDirA | | mfi . m_bDirB | | mfi . m_bDirC | | conflictingFileTypes ( mfi ) ) ;
}
return false ;
}
void DirectoryMergeWindow : : mergeResultSaved ( const TQString & fileName )
{
DirMergeItem * pCurrentItemForOperation = ( m_mergeItemList . empty ( ) | | m_currentItemForOperation = = m_mergeItemList . end ( ) )
? 0
: * m_currentItemForOperation ;
if ( pCurrentItemForOperation ! = 0 & & pCurrentItemForOperation - > m_pMFI = = 0 )
{
KMessageBox : : error ( this , i18n ( " This should never happen: \n \n mergeResultSaved: m_pMFI=0 \n \n If you know how to reproduce this, please contact the program author. " ) , i18n ( " Program Error " ) ) ;
return ;
}
if ( pCurrentItemForOperation ! = 0 & & fileName = = fullNameDest ( * pCurrentItemForOperation - > m_pMFI ) )
{
if ( pCurrentItemForOperation - > m_pMFI - > m_eMergeOperation = = eMergeToAB )
{
MergeFileInfos & mfi = * pCurrentItemForOperation - > m_pMFI ;
bool bSuccess = copyFLD ( fullNameB ( mfi ) , fullNameA ( mfi ) ) ;
if ( ! bSuccess )
{
KMessageBox : : error ( this , i18n ( " An error occurred while copying. \n " ) , i18n ( " Error " ) ) ;
m_pStatusInfo - > setCaption ( i18n ( " Merge Error " ) ) ;
m_pStatusInfo - > show ( ) ;
//if ( m_pStatusInfo->firstChild()!=0 )
// m_pStatusInfo->ensureItemVisible( m_pStatusInfo->last() );
m_bError = true ;
pCurrentItemForOperation - > setText ( s_OpStatusCol , i18n ( " Error. " ) ) ;
mfi . m_eMergeOperation = eCopyBToA ;
return ;
}
}
pCurrentItemForOperation - > setText ( s_OpStatusCol , i18n ( " Done. " ) ) ;
pCurrentItemForOperation - > m_pMFI - > m_bOperationComplete = true ;
if ( m_mergeItemList . size ( ) = = 1 )
{
m_mergeItemList . clear ( ) ;
m_bRealMergeStarted = false ;
}
}
emit updateAvailabilities ( ) ;
}
bool DirectoryMergeWindow : : canContinue ( )
{
bool bCanContinue = false ;
checkIfCanContinue ( & bCanContinue ) ;
if ( bCanContinue & & ! m_bError )
{
DirMergeItem * pCurrentItemForOperation =
( m_mergeItemList . empty ( ) | | m_currentItemForOperation = = m_mergeItemList . end ( ) ) ? 0 : * m_currentItemForOperation ;
if ( pCurrentItemForOperation ! = 0 & & ! pCurrentItemForOperation - > m_pMFI - > m_bOperationComplete )
{
pCurrentItemForOperation - > setText ( s_OpStatusCol , i18n ( " Not saved. " ) ) ;
pCurrentItemForOperation - > m_pMFI - > m_bOperationComplete = true ;
if ( m_mergeItemList . size ( ) = = 1 )
{
m_mergeItemList . clear ( ) ;
m_bRealMergeStarted = false ;
}
}
}
return bCanContinue ;
}
bool DirectoryMergeWindow : : executeMergeOperation ( MergeFileInfos & mfi , bool & bSingleFileMerge )
{
bool bCreateBackups = m_pOptions - > m_bDmCreateBakFiles ;
// First decide destname
TQString destName ;
switch ( mfi . m_eMergeOperation )
{
case eNoOperation : break ;
case eDeleteAB : break ;
case eMergeToAB : // let the user save in B. In mergeResultSaved() the file will be copied to A.
case eMergeToB :
case eDeleteB :
case eCopyAToB : destName = fullNameB ( mfi ) ; break ;
case eMergeToA :
case eDeleteA :
case eCopyBToA : destName = fullNameA ( mfi ) ; break ;
case eMergeABToDest :
case eMergeABCToDest :
case eCopyAToDest :
case eCopyBToDest :
case eCopyCToDest :
case eDeleteFromDest : destName = fullNameDest ( mfi ) ; break ;
default :
KMessageBox : : error ( this , i18n ( " Unknown merge operation. (This must never happen!) " ) , i18n ( " Error " ) ) ;
assert ( false ) ;
}
bool bSuccess = false ;
bSingleFileMerge = false ;
switch ( mfi . m_eMergeOperation )
{
case eNoOperation : bSuccess = true ; break ;
case eCopyAToDest :
case eCopyAToB : bSuccess = copyFLD ( fullNameA ( mfi ) , destName ) ; break ;
case eCopyBToDest :
case eCopyBToA : bSuccess = copyFLD ( fullNameB ( mfi ) , destName ) ; break ;
case eCopyCToDest : bSuccess = copyFLD ( fullNameC ( mfi ) , destName ) ; break ;
case eDeleteFromDest :
case eDeleteA :
case eDeleteB : bSuccess = deleteFLD ( destName , bCreateBackups ) ; break ;
case eDeleteAB : bSuccess = deleteFLD ( fullNameA ( mfi ) , bCreateBackups ) & &
deleteFLD ( fullNameB ( mfi ) , bCreateBackups ) ; break ;
case eMergeABToDest :
case eMergeToA :
case eMergeToAB :
case eMergeToB : bSuccess = mergeFLD ( fullNameA ( mfi ) , fullNameB ( mfi ) , " " ,
destName , bSingleFileMerge ) ;
break ;
case eMergeABCToDest : bSuccess = mergeFLD (
mfi . m_bExistsInA ? fullNameA ( mfi ) : TQString ( " " ) ,
mfi . m_bExistsInB ? fullNameB ( mfi ) : TQString ( " " ) ,
mfi . m_bExistsInC ? fullNameC ( mfi ) : TQString ( " " ) ,
destName , bSingleFileMerge ) ;
break ;
default :
KMessageBox : : error ( this , i18n ( " Unknown merge operation. " ) , i18n ( " Error " ) ) ;
assert ( false ) ;
}
return bSuccess ;
}
// Check if the merge can start, and prepare the m_mergeItemList which then contains all
// items that must be merged.
void DirectoryMergeWindow : : prepareMergeStart ( TQListViewItem * pBegin , TQListViewItem * pEnd , bool bVerbose )
{
if ( bVerbose )
{
int status = KMessageBox : : warningYesNoCancel ( this ,
i18n ( " The merge is about to begin. \n \n "
" Choose \" Do it \" if you have read the instructions and know what you are doing. \n "
" Choosing \" Simulate it \" will tell you what would happen. \n \n "
" Be aware that this program still has beta status "
" and there is NO WARRANTY whatsoever! Make backups of your vital data! " ) ,
i18n ( " Starting Merge " ) , i18n ( " Do It " ) , i18n ( " Simulate It " ) ) ;
if ( status = = KMessageBox : : Yes ) m_bRealMergeStarted = true ;
else if ( status = = KMessageBox : : No ) m_bSimulatedMergeStarted = true ;
else return ;
}
else
{
m_bRealMergeStarted = true ;
}
m_mergeItemList . clear ( ) ;
if ( pBegin = = 0 )
return ;
for ( TQListViewItem * p = pBegin ; p ! = pEnd ; p = treeIterator ( p ) )
{
DirMergeItem * pDMI = static_cast < DirMergeItem * > ( p ) ;
if ( pDMI & & ! pDMI - > m_pMFI - > m_bOperationComplete )
{
m_mergeItemList . push_back ( pDMI ) ;
if ( pDMI ! = 0 & & pDMI - > m_pMFI - > m_eMergeOperation = = eConflictingFileTypes )
{
ensureItemVisible ( pDMI ) ;
setSelected ( pDMI , true ) ;
KMessageBox : : error ( this , i18n ( " The highlighted item has a different type in the different directories. Select what to do. " ) , i18n ( " Error " ) ) ;
m_mergeItemList . clear ( ) ;
m_bRealMergeStarted = false ;
return ;
}
if ( pDMI ! = 0 & & pDMI - > m_pMFI - > m_eMergeOperation = = eConflictingAges )
{
ensureItemVisible ( pDMI ) ;
setSelected ( pDMI , true ) ;
KMessageBox : : error ( this , i18n ( " The modification dates of the file are equal but the files are not. Select what to do. " ) , i18n ( " Error " ) ) ;
m_mergeItemList . clear ( ) ;
m_bRealMergeStarted = false ;
return ;
}
}
}
m_currentItemForOperation = m_mergeItemList . begin ( ) ;
return ;
}
void DirectoryMergeWindow : : slotRunOperationForCurrentItem ( )
{
if ( ! canContinue ( ) ) return ;
bool bVerbose = false ;
if ( m_mergeItemList . empty ( ) )
{
TQListViewItem * pBegin = currentItem ( ) ;
TQListViewItem * pEnd = treeIterator ( pBegin , false , false ) ; // find next visible sibling (no children)
prepareMergeStart ( pBegin , pEnd , bVerbose ) ;
mergeContinue ( true , bVerbose ) ;
}
else
mergeContinue ( false , bVerbose ) ;
}
void DirectoryMergeWindow : : slotRunOperationForAllItems ( )
{
if ( ! canContinue ( ) ) return ;
bool bVerbose = true ;
if ( m_mergeItemList . empty ( ) )
{
TQListViewItem * pBegin = firstChild ( ) ;
prepareMergeStart ( pBegin , 0 , bVerbose ) ;
mergeContinue ( true , bVerbose ) ;
}
else
mergeContinue ( false , bVerbose ) ;
}
void DirectoryMergeWindow : : mergeCurrentFile ( )
{
if ( ! canContinue ( ) ) return ;
if ( m_bRealMergeStarted )
{
KMessageBox : : sorry ( this , i18n ( " This operation is currently not possible because directory merge is currently running. " ) , i18n ( " Operation Not Possible " ) ) ;
return ;
}
if ( isFileSelected ( ) )
{
DirMergeItem * pDMI = static_cast < DirMergeItem * > ( selectedItem ( ) ) ;
if ( pDMI ! = 0 )
{
MergeFileInfos & mfi = * pDMI - > m_pMFI ;
m_mergeItemList . clear ( ) ;
m_mergeItemList . push_back ( pDMI ) ;
m_currentItemForOperation = m_mergeItemList . begin ( ) ;
bool bDummy = false ;
mergeFLD (
mfi . m_bExistsInA ? mfi . m_fileInfoA . absFilePath ( ) : TQString ( " " ) ,
mfi . m_bExistsInB ? mfi . m_fileInfoB . absFilePath ( ) : TQString ( " " ) ,
mfi . m_bExistsInC ? mfi . m_fileInfoC . absFilePath ( ) : TQString ( " " ) ,
fullNameDest ( mfi ) ,
bDummy
) ;
}
}
emit updateAvailabilities ( ) ;
}
// When bStart is true then m_currentItemForOperation must still be processed.
// When bVerbose is true then a messagebox will tell when the merge is complete.
void DirectoryMergeWindow : : mergeContinue ( bool bStart , bool bVerbose )
{
ProgressProxy pp ;
if ( m_mergeItemList . empty ( ) )
return ;
int nrOfItems = 0 ;
int nrOfCompletedItems = 0 ;
int nrOfCompletedSimItems = 0 ;
// Count the number of completed items (for the progress bar).
for ( MergeItemList : : iterator i = m_mergeItemList . begin ( ) ; i ! = m_mergeItemList . end ( ) ; + + i )
{
DirMergeItem * pDMI = * i ;
+ + nrOfItems ;
if ( pDMI - > m_pMFI - > m_bOperationComplete )
+ + nrOfCompletedItems ;
if ( pDMI - > m_pMFI - > m_bSimOpComplete )
+ + nrOfCompletedSimItems ;
}
m_pStatusInfo - > hide ( ) ;
m_pStatusInfo - > clear ( ) ;
DirMergeItem * pCurrentItemForOperation = m_currentItemForOperation = = m_mergeItemList . end ( ) ? 0 : * m_currentItemForOperation ;
bool bContinueWithCurrentItem = bStart ; // true for first item, else false
bool bSkipItem = false ;
if ( ! bStart & & m_bError & & pCurrentItemForOperation ! = 0 )
{
int status = KMessageBox : : warningYesNoCancel ( this ,
i18n ( " There was an error in the last step. \n "
" Do you want to continue with the item that caused the error or do you want to skip this item? " ) ,
i18n ( " Continue merge after an error " ) , i18n ( " Continue With Last Item " ) , i18n ( " Skip Item " ) ) ;
if ( status = = KMessageBox : : Yes ) bContinueWithCurrentItem = true ;
else if ( status = = KMessageBox : : No ) bSkipItem = true ;
else return ;
m_bError = false ;
}
bool bSuccess = true ;
bool bSingleFileMerge = false ;
bool bSim = m_bSimulatedMergeStarted ;
while ( bSuccess )
{
if ( pCurrentItemForOperation = = 0 )
{
m_mergeItemList . clear ( ) ;
m_bRealMergeStarted = false ;
break ;
}
if ( pCurrentItemForOperation ! = 0 & & ! bContinueWithCurrentItem )
{
if ( bSim )
{
if ( pCurrentItemForOperation - > firstChild ( ) = = 0 )
{
pCurrentItemForOperation - > m_pMFI - > m_bSimOpComplete = true ;
}
}
else
{
if ( pCurrentItemForOperation - > firstChild ( ) = = 0 )
{
if ( ! pCurrentItemForOperation - > m_pMFI - > m_bOperationComplete )
{
pCurrentItemForOperation - > setText ( s_OpStatusCol , bSkipItem ? i18n ( " Skipped. " ) : i18n ( " Done. " ) ) ;
pCurrentItemForOperation - > m_pMFI - > m_bOperationComplete = true ;
bSkipItem = false ;
}
}
else
{
pCurrentItemForOperation - > setText ( s_OpStatusCol , i18n ( " In progress... " ) ) ;
}
}
}
if ( ! bContinueWithCurrentItem )
{
// Depth first
TQListViewItem * pPrevItem = pCurrentItemForOperation ;
+ + m_currentItemForOperation ;
pCurrentItemForOperation = m_currentItemForOperation = = m_mergeItemList . end ( ) ? 0 : * m_currentItemForOperation ;
if ( ( pCurrentItemForOperation = = 0 | | pCurrentItemForOperation - > parent ( ) ! = pPrevItem - > parent ( ) ) & & pPrevItem - > parent ( ) ! = 0 )
{
// Check if the parent may be set to "Done"
TQListViewItem * pParent = pPrevItem - > parent ( ) ;
bool bDone = true ;
while ( bDone & & pParent ! = 0 )
{
for ( TQListViewItem * p = pParent - > firstChild ( ) ; p ! = 0 ; p = p - > nextSibling ( ) )
{
DirMergeItem * pDMI = static_cast < DirMergeItem * > ( p ) ;
if ( ! bSim & & ! pDMI - > m_pMFI - > m_bOperationComplete | | bSim & & pDMI - > m_pMFI - > m_bSimOpComplete )
{
bDone = false ;
break ;
}
}
if ( bDone )
{
if ( bSim )
static_cast < DirMergeItem * > ( pParent ) - > m_pMFI - > m_bSimOpComplete = bDone ;
else
{
pParent - > setText ( s_OpStatusCol , i18n ( " Done. " ) ) ;
static_cast < DirMergeItem * > ( pParent ) - > m_pMFI - > m_bOperationComplete = bDone ;
}
}
pParent = pParent - > parent ( ) ;
}
}
}
if ( pCurrentItemForOperation = = 0 ) // end?
{
if ( m_bRealMergeStarted )
{
if ( bVerbose )
{
KMessageBox : : information ( this , i18n ( " Merge operation complete. " ) , i18n ( " Merge Complete " ) ) ;
}
m_bRealMergeStarted = false ;
m_pStatusInfo - > setCaption ( i18n ( " Merge Complete " ) ) ;
}
if ( m_bSimulatedMergeStarted )
{
m_bSimulatedMergeStarted = false ;
for ( TQListViewItem * p = firstChild ( ) ; p ! = 0 ; p = treeIterator ( p ) )
{
static_cast < DirMergeItem * > ( p ) - > m_pMFI - > m_bSimOpComplete = false ;
}
m_pStatusInfo - > setCaption ( i18n ( " Simulated merge complete: Check if you agree with the proposed operations. " ) ) ;
m_pStatusInfo - > show ( ) ;
}
//g_pProgressDialog->hide();
m_mergeItemList . clear ( ) ;
m_bRealMergeStarted = false ;
return ;
}
MergeFileInfos & mfi = * pCurrentItemForOperation - > m_pMFI ;
pp . setInformation ( mfi . m_subPath ,
bSim ? double ( nrOfCompletedSimItems ) / nrOfItems : double ( nrOfCompletedItems ) / nrOfItems ,
false // bRedrawUpdate
) ;
//g_pProgressDialog->show();
bSuccess = executeMergeOperation ( mfi , bSingleFileMerge ) ; // Here the real operation happens.
if ( bSuccess )
{
if ( bSim ) + + nrOfCompletedSimItems ;
else + + nrOfCompletedItems ;
bContinueWithCurrentItem = false ;
}
if ( pp . wasCancelled ( ) )
break ;
} // end while
//g_pProgressDialog->hide();
setCurrentItem ( pCurrentItemForOperation ) ;
ensureItemVisible ( pCurrentItemForOperation ) ;
if ( ! bSuccess & & ! bSingleFileMerge )
{
KMessageBox : : error ( this , i18n ( " An error occurred. Press OK to see detailed information. \n " ) , i18n ( " Error " ) ) ;
m_pStatusInfo - > setCaption ( i18n ( " Merge Error " ) ) ;
m_pStatusInfo - > show ( ) ;
//if ( m_pStatusInfo->firstChild()!=0 )
// m_pStatusInfo->ensureItemVisible( m_pStatusInfo->last() );
m_bError = true ;
pCurrentItemForOperation - > setText ( s_OpStatusCol , i18n ( " Error. " ) ) ;
}
else
{
m_bError = false ;
}
emit updateAvailabilities ( ) ;
if ( m_currentItemForOperation = = m_mergeItemList . end ( ) )
{
m_mergeItemList . clear ( ) ;
m_bRealMergeStarted = false ;
}
}
void DirectoryMergeWindow : : allowResizeEvents ( bool bAllowResizeEvents )
{
m_bAllowResizeEvents = bAllowResizeEvents ;
}
void DirectoryMergeWindow : : resizeEvent ( TQResizeEvent * e )
{
if ( m_bAllowResizeEvents )
TQListView : : resizeEvent ( e ) ;
}
bool DirectoryMergeWindow : : deleteFLD ( const TQString & name , bool bCreateBackup )
{
FileAccess fi ( name , true ) ;
if ( ! fi . exists ( ) )
return true ;
if ( bCreateBackup )
{
bool bSuccess = renameFLD ( name , name + " .orig " ) ;
if ( ! bSuccess )
{
m_pStatusInfo - > addText ( i18n ( " Error: While deleting %1: Creating backup failed. " ) . arg ( name ) ) ;
return false ;
}
}
else
{
if ( fi . isDir ( ) & & ! fi . isSymLink ( ) )
m_pStatusInfo - > addText ( i18n ( " delete directory recursively( %1 ) " ) . arg ( name ) ) ;
else
m_pStatusInfo - > addText ( i18n ( " delete( %1 ) " ) . arg ( name ) ) ;
if ( m_bSimulatedMergeStarted )
{
return true ;
}
if ( fi . isDir ( ) & & ! fi . isSymLink ( ) ) // recursive directory delete only for real dirs, not symlinks
{
t_DirectoryList dirList ;
bool bSuccess = fi . listDir ( & dirList , false , true , " * " , " " , " " , false , false ) ; // not recursive, find hidden files
if ( ! bSuccess )
{
// No Permission to read directory or other error.
m_pStatusInfo - > addText ( i18n ( " Error: delete dir operation failed while trying to read the directory. " ) ) ;
return false ;
}
t_DirectoryList : : iterator it ; // create list iterator
for ( it = dirList . begin ( ) ; it ! = dirList . end ( ) ; + + it ) // for each file...
{
FileAccess & fi2 = * it ;
if ( fi2 . fileName ( ) = = " . " | | fi2 . fileName ( ) = = " .. " )
continue ;
bSuccess = deleteFLD ( fi2 . absFilePath ( ) , false ) ;
if ( ! bSuccess ) break ;
}
if ( bSuccess )
{
bSuccess = FileAccess : : removeDir ( name ) ;
if ( ! bSuccess )
{
m_pStatusInfo - > addText ( i18n ( " Error: rmdir( %1 ) operation failed. " ) . arg ( name ) ) ;
return false ;
}
}
}
else
{
bool bSuccess = FileAccess : : removeFile ( name ) ;
if ( ! bSuccess )
{
m_pStatusInfo - > addText ( i18n ( " Error: delete operation failed. " ) ) ;
return false ;
}
}
}
return true ;
}
bool DirectoryMergeWindow : : mergeFLD ( const TQString & nameA , const TQString & nameB , const TQString & nameC , const TQString & nameDest , bool & bSingleFileMerge )
{
FileAccess fi ( nameA ) ;
if ( fi . isDir ( ) )
{
return makeDir ( nameDest ) ;
}
// Make sure that the dir exists, into which we will save the file later.
int pos = nameDest . findRev ( ' / ' ) ;
if ( pos > 0 )
{
TQString parentName = nameDest . left ( pos ) ;
bool bSuccess = makeDir ( parentName , true /*quiet*/ ) ;
if ( ! bSuccess )
return false ;
}
m_pStatusInfo - > addText ( i18n ( " manual merge( %1, %2, %3 -> %4) " ) . arg ( nameA ) . arg ( nameB ) . arg ( nameC ) . arg ( nameDest ) ) ;
if ( m_bSimulatedMergeStarted )
{
m_pStatusInfo - > addText ( i18n ( " Note: After a manual merge the user should continue by pressing F7. " ) ) ;
return true ;
}
bSingleFileMerge = true ;
( * m_currentItemForOperation ) - > setText ( s_OpStatusCol , i18n ( " In progress... " ) ) ;
ensureItemVisible ( * m_currentItemForOperation ) ;
emit startDiffMerge ( nameA , nameB , nameC , nameDest , " " , " " , " " , 0 ) ;
return false ;
}
bool DirectoryMergeWindow : : copyFLD ( const TQString & srcName , const TQString & destName )
{
if ( srcName = = destName )
return true ;
if ( FileAccess ( destName , true ) . exists ( ) )
{
bool bSuccess = deleteFLD ( destName , m_pOptions - > m_bDmCreateBakFiles ) ;
if ( ! bSuccess )
{
m_pStatusInfo - > addText ( i18n ( " Error: copy( %1 -> %2 ) failed. "
" Deleting existing destination failed. " ) . arg ( srcName ) . arg ( destName ) ) ;
return false ;
}
}
FileAccess fi ( srcName ) ;
if ( fi . isSymLink ( ) & & ( fi . isDir ( ) & & ! m_bFollowDirLinks | | ! fi . isDir ( ) & & ! m_bFollowFileLinks ) )
{
m_pStatusInfo - > addText ( i18n ( " copyLink( %1 -> %2 ) " ) . arg ( srcName ) . arg ( destName ) ) ;
# ifdef _WIN32
// What are links?
# else
if ( m_bSimulatedMergeStarted )
{
return true ;
}
FileAccess destFi ( destName ) ;
if ( ! destFi . isLocal ( ) | | ! fi . isLocal ( ) )
{
m_pStatusInfo - > addText ( i18n ( " Error: copyLink failed: Remote links are not yet supported. " ) ) ;
return false ;
}
TQString linkTarget = fi . readLink ( ) ;
bool bSuccess = FileAccess : : symLink ( linkTarget , destName ) ;
if ( ! bSuccess )
m_pStatusInfo - > addText ( i18n ( " Error: copyLink failed. " ) ) ;
return bSuccess ;
# endif
}
if ( fi . isDir ( ) )
{
bool bSuccess = makeDir ( destName ) ;
return bSuccess ;
}
int pos = destName . findRev ( ' / ' ) ;
if ( pos > 0 )
{
TQString parentName = destName . left ( pos ) ;
bool bSuccess = makeDir ( parentName , true /*quiet*/ ) ;
if ( ! bSuccess )
return false ;
}
m_pStatusInfo - > addText ( i18n ( " copy( %1 -> %2 ) " ) . arg ( srcName ) . arg ( destName ) ) ;
if ( m_bSimulatedMergeStarted )
{
return true ;
}
FileAccess faSrc ( srcName ) ;
bool bSuccess = faSrc . copyFile ( destName ) ;
if ( ! bSuccess ) m_pStatusInfo - > addText ( faSrc . getStatusText ( ) ) ;
return bSuccess ;
}
// Rename is not an operation that can be selected by the user.
// It will only be used to create backups.
// Hence it will delete an existing destination without making a backup (of the old backup.)
bool DirectoryMergeWindow : : renameFLD ( const TQString & srcName , const TQString & destName )
{
if ( srcName = = destName )
return true ;
if ( FileAccess ( destName , true ) . exists ( ) )
{
bool bSuccess = deleteFLD ( destName , false /*no backup*/ ) ;
if ( ! bSuccess )
{
m_pStatusInfo - > addText ( i18n ( " Error during rename( %1 -> %2 ): "
" Cannot delete existing destination. " ) . arg ( srcName ) . arg ( destName ) ) ;
return false ;
}
}
m_pStatusInfo - > addText ( i18n ( " rename( %1 -> %2 ) " ) . arg ( srcName ) . arg ( destName ) ) ;
if ( m_bSimulatedMergeStarted )
{
return true ;
}
bool bSuccess = FileAccess ( srcName ) . rename ( destName ) ;
if ( ! bSuccess )
{
m_pStatusInfo - > addText ( i18n ( " Error: Rename failed. " ) ) ;
return false ;
}
return true ;
}
bool DirectoryMergeWindow : : makeDir ( const TQString & name , bool bQuiet )
{
FileAccess fi ( name , true ) ;
if ( fi . exists ( ) & & fi . isDir ( ) )
return true ;
if ( fi . exists ( ) & & ! fi . isDir ( ) )
{
bool bSuccess = deleteFLD ( name , true ) ;
if ( ! bSuccess )
{
m_pStatusInfo - > addText ( i18n ( " Error during makeDir of %1. "
" Cannot delete existing file. " ) . arg ( name ) ) ;
return false ;
}
}
int pos = name . findRev ( ' / ' ) ;
if ( pos > 0 )
{
TQString parentName = name . left ( pos ) ;
bool bSuccess = makeDir ( parentName , true ) ;
if ( ! bSuccess )
return false ;
}
if ( ! bQuiet )
m_pStatusInfo - > addText ( i18n ( " makeDir( %1 ) " ) . arg ( name ) ) ;
if ( m_bSimulatedMergeStarted )
{
return true ;
}
bool bSuccess = FileAccess : : makeDir ( name ) ;
if ( bSuccess = = false )
{
m_pStatusInfo - > addText ( i18n ( " Error while creating directory. " ) ) ;
return false ;
}
return true ;
}
DirectoryMergeInfo : : DirectoryMergeInfo ( TQWidget * pParent )
: TQFrame ( pParent )
{
TQVBoxLayout * topLayout = new TQVBoxLayout ( this ) ;
TQGridLayout * grid = new TQGridLayout ( topLayout ) ;
grid - > setColStretch ( 1 , 10 ) ;
int line = 0 ;
m_pA = new TQLabel ( " A " , this ) ; grid - > addWidget ( m_pA , line , 0 ) ;
m_pInfoA = new TQLabel ( this ) ; grid - > addWidget ( m_pInfoA , line , 1 ) ; + + line ;
m_pB = new TQLabel ( " B " , this ) ; grid - > addWidget ( m_pB , line , 0 ) ;
m_pInfoB = new TQLabel ( this ) ; grid - > addWidget ( m_pInfoB , line , 1 ) ; + + line ;
m_pC = new TQLabel ( " C " , this ) ; grid - > addWidget ( m_pC , line , 0 ) ;
m_pInfoC = new TQLabel ( this ) ; grid - > addWidget ( m_pInfoC , line , 1 ) ; + + line ;
m_pDest = new TQLabel ( i18n ( " Dest " ) , this ) ; grid - > addWidget ( m_pDest , line , 0 ) ;
m_pInfoDest = new TQLabel ( this ) ; grid - > addWidget ( m_pInfoDest , line , 1 ) ; + + line ;
m_pInfoList = new TQListView ( this ) ; topLayout - > addWidget ( m_pInfoList ) ;
m_pInfoList - > addColumn ( i18n ( " Dir " ) ) ;
m_pInfoList - > addColumn ( i18n ( " Type " ) ) ;
m_pInfoList - > addColumn ( i18n ( " Size " ) ) ;
m_pInfoList - > addColumn ( i18n ( " Attr " ) ) ;
m_pInfoList - > addColumn ( i18n ( " Last Modification " ) ) ;
m_pInfoList - > addColumn ( i18n ( " Link-Destination " ) ) ;
setMinimumSize ( 100 , 100 ) ;
m_pInfoList - > installEventFilter ( this ) ;
}
bool DirectoryMergeInfo : : eventFilter ( TQObject * o , TQEvent * e )
{
if ( e - > type ( ) = = TQEvent : : FocusIn & & TQT_BASE_OBJECT ( o ) = = TQT_BASE_OBJECT ( m_pInfoList ) )
emit gotFocus ( ) ;
return false ;
}
static void addListViewItem ( TQListView * pListView , const TQString & dir ,
const TQString & basePath , FileAccess & fi )
{
if ( basePath . isEmpty ( ) )
{
return ;
}
else
{
if ( fi . exists ( ) )
{
TQString dateString = fi . lastModified ( ) . toString ( " yyyy-MM-dd hh:mm:ss " ) ;
new TQListViewItem (
pListView ,
dir ,
TQString ( fi . isDir ( ) ? i18n ( " Dir " ) : i18n ( " File " ) ) + ( fi . isSymLink ( ) ? " -Link " : " " ) ,
TQString : : number ( fi . size ( ) ) ,
TQString ( fi . isReadable ( ) ? " r " : " " ) + ( fi . isWritable ( ) ? " w " : " " )
# ifdef _WIN32
/*Future: Use GetFileAttributes()*/ ,
# else
+ ( fi . isExecutable ( ) ? " x " : " " ) ,
# endif
dateString ,
TQString ( fi . isSymLink ( ) ? ( " -> " + fi . readLink ( ) ) : TQString ( " " ) )
) ;
}
else
{
new TQListViewItem (
pListView ,
dir ,
i18n ( " not available " ) ,
" " ,
" " ,
" " ,
" "
) ;
}
}
}
void DirectoryMergeInfo : : setInfo (
const FileAccess & dirA ,
const FileAccess & dirB ,
const FileAccess & dirC ,
const FileAccess & dirDest ,
MergeFileInfos & mfi )
{
bool bHideDest = false ;
if ( dirA . absFilePath ( ) = = dirDest . absFilePath ( ) )
{
m_pA - > setText ( i18n ( " A (Dest): " ) ) ; bHideDest = true ;
}
else
m_pA - > setText ( ! dirC . isValid ( ) ? TQString ( " A: " ) : i18n ( " A (Base): " ) ) ;
m_pInfoA - > setText ( dirA . prettyAbsPath ( ) ) ;
if ( dirB . absFilePath ( ) = = dirDest . absFilePath ( ) )
{
m_pB - > setText ( i18n ( " B (Dest): " ) ) ; bHideDest = true ;
}
else
m_pB - > setText ( " B: " ) ;
m_pInfoB - > setText ( dirB . prettyAbsPath ( ) ) ;
if ( dirC . absFilePath ( ) = = dirDest . absFilePath ( ) )
{
m_pC - > setText ( i18n ( " C (Dest): " ) ) ; bHideDest = true ;
}
else
m_pC - > setText ( " C: " ) ;
m_pInfoC - > setText ( dirC . prettyAbsPath ( ) ) ;
m_pDest - > setText ( i18n ( " Dest: " ) ) ; m_pInfoDest - > setText ( dirDest . prettyAbsPath ( ) ) ;
if ( ! dirC . isValid ( ) ) { m_pC - > hide ( ) ; m_pInfoC - > hide ( ) ; }
else { m_pC - > show ( ) ; m_pInfoC - > show ( ) ; }
if ( ! dirDest . isValid ( ) | | bHideDest ) { m_pDest - > hide ( ) ; m_pInfoDest - > hide ( ) ; }
else { m_pDest - > show ( ) ; m_pInfoDest - > show ( ) ; }
m_pInfoList - > clear ( ) ;
addListViewItem ( m_pInfoList , " A " , dirA . prettyAbsPath ( ) , mfi . m_fileInfoA ) ;
addListViewItem ( m_pInfoList , " B " , dirB . prettyAbsPath ( ) , mfi . m_fileInfoB ) ;
addListViewItem ( m_pInfoList , " C " , dirC . prettyAbsPath ( ) , mfi . m_fileInfoC ) ;
if ( ! bHideDest )
{
FileAccess fiDest ( dirDest . prettyAbsPath ( ) + " / " + mfi . m_subPath , true ) ;
addListViewItem ( m_pInfoList , i18n ( " Dest " ) , dirDest . prettyAbsPath ( ) , fiDest ) ;
}
}
TQTextStream & operator < < ( TQTextStream & ts , MergeFileInfos & mfi )
{
ts < < " { \n " ;
ValueMap vm ;
vm . writeEntry ( " SubPath " , mfi . m_subPath ) ;
vm . writeEntry ( " ExistsInA " , mfi . m_bExistsInA ) ;
vm . writeEntry ( " ExistsInB " , mfi . m_bExistsInB ) ;
vm . writeEntry ( " ExistsInC " , mfi . m_bExistsInC ) ;
vm . writeEntry ( " EqualAB " , mfi . m_bEqualAB ) ;
vm . writeEntry ( " EqualAC " , mfi . m_bEqualAC ) ;
vm . writeEntry ( " EqualBC " , mfi . m_bEqualBC ) ;
//DirMergeItem* m_pDMI;
//MergeFileInfos* m_pParent;
vm . writeEntry ( " MergeOperation " , ( int ) mfi . m_eMergeOperation ) ;
vm . writeEntry ( " DirA " , mfi . m_bDirA ) ;
vm . writeEntry ( " DirB " , mfi . m_bDirB ) ;
vm . writeEntry ( " DirC " , mfi . m_bDirC ) ;
vm . writeEntry ( " LinkA " , mfi . m_bLinkA ) ;
vm . writeEntry ( " LinkB " , mfi . m_bLinkB ) ;
vm . writeEntry ( " LinkC " , mfi . m_bLinkC ) ;
vm . writeEntry ( " OperationComplete " , mfi . m_bOperationComplete ) ;
//bool m_bSimOpComplete );
vm . writeEntry ( " AgeA " , ( int ) mfi . m_ageA ) ;
vm . writeEntry ( " AgeB " , ( int ) mfi . m_ageB ) ;
vm . writeEntry ( " AgeC " , ( int ) mfi . m_ageC ) ;
vm . writeEntry ( " ConflictingAges " , mfi . m_bConflictingAges ) ; // Equal age but files are not!
//FileAccess m_fileInfoA;
//FileAccess m_fileInfoB;
//FileAccess m_fileInfoC;
//TotalDiffStatus m_totalDiffStatus;
vm . save ( ts ) ;
ts < < " } \n " ;
return ts ;
}
void DirectoryMergeWindow : : slotSaveMergeState ( )
{
//slotStatusMsg(i18n("Saving Directory Merge State ..."));
//TQString s = KFileDialog::getSaveURL( TQDir::currentDirPath(), 0, this, i18n("Save As...") ).url();
TQString s = KFileDialog : : getSaveFileName ( TQDir : : currentDirPath ( ) , 0 , this , i18n ( " Save Directory Merge State As... " ) ) ;
if ( ! s . isEmpty ( ) )
{
m_dirMergeStateFilename = s ;
TQFile file ( m_dirMergeStateFilename ) ;
bool bSuccess = file . open ( IO_WriteOnly ) ;
if ( bSuccess )
{
TQTextStream ts ( & file ) ;
TQListViewItemIterator it ( this ) ;
while ( it . current ( ) ) {
DirMergeItem * item = static_cast < DirMergeItem * > ( it . current ( ) ) ;
MergeFileInfos * pMFI = item - > m_pMFI ;
ts < < * pMFI ;
+ + it ;
}
}
}
//slotStatusMsg(i18n("Ready."));
}
void DirectoryMergeWindow : : slotLoadMergeState ( )
{
}
void DirectoryMergeWindow : : updateFileVisibilities ( )
{
bool bShowIdentical = m_pDirShowIdenticalFiles - > isChecked ( ) ;
bool bShowDifferent = m_pDirShowDifferentFiles - > isChecked ( ) ;
bool bShowOnlyInA = m_pDirShowFilesOnlyInA - > isChecked ( ) ;
bool bShowOnlyInB = m_pDirShowFilesOnlyInB - > isChecked ( ) ;
bool bShowOnlyInC = m_pDirShowFilesOnlyInC - > isChecked ( ) ;
bool bThreeDirs = m_dirC . isValid ( ) ;
m_pSelection1Item = 0 ;
m_pSelection2Item = 0 ;
m_pSelection3Item = 0 ;
TQListViewItem * p = firstChild ( ) ;
while ( p )
{
DirMergeItem * pDMI = static_cast < DirMergeItem * > ( p ) ;
MergeFileInfos * pMFI = pDMI - > m_pMFI ;
bool bDir = pMFI - > m_bDirA | | pMFI - > m_bDirB | | pMFI - > m_bDirC ;
bool bExistsEverywhere = pMFI - > m_bExistsInA & & pMFI - > m_bExistsInB & & ( pMFI - > m_bExistsInC | | ! bThreeDirs ) ;
int existCount = int ( pMFI - > m_bExistsInA ) + int ( pMFI - > m_bExistsInB ) + int ( pMFI - > m_bExistsInC ) ;
bool bVisible =
( bShowIdentical & & bExistsEverywhere & & pMFI - > m_bEqualAB & & ( pMFI - > m_bEqualAC | | ! bThreeDirs ) )
| | ( ( bShowDifferent | | bDir ) & & existCount > = 2 & & ( ! pMFI - > m_bEqualAB | | ! ( pMFI - > m_bEqualAC | | ! bThreeDirs ) ) )
| | ( bShowOnlyInA & & pMFI - > m_bExistsInA & & ! pMFI - > m_bExistsInB & & ! pMFI - > m_bExistsInC )
| | ( bShowOnlyInB & & ! pMFI - > m_bExistsInA & & pMFI - > m_bExistsInB & & ! pMFI - > m_bExistsInC )
| | ( bShowOnlyInC & & ! pMFI - > m_bExistsInA & & ! pMFI - > m_bExistsInB & & pMFI - > m_bExistsInC ) ;
TQString fileName = pMFI - > m_subPath . section ( ' / ' , - 1 ) ;
bVisible = bVisible & & (
bDir & & ! wildcardMultiMatch ( m_pOptions - > m_DmDirAntiPattern , fileName , m_bCaseSensitive )
| | wildcardMultiMatch ( m_pOptions - > m_DmFilePattern , fileName , m_bCaseSensitive )
& & ! wildcardMultiMatch ( m_pOptions - > m_DmFileAntiPattern , fileName , m_bCaseSensitive ) ) ;
p - > setVisible ( bVisible ) ;
p = treeIterator ( p , true , true ) ;
}
}
void DirectoryMergeWindow : : slotShowIdenticalFiles ( ) { m_pOptions - > m_bDmShowIdenticalFiles = m_pDirShowIdenticalFiles - > isChecked ( ) ;
updateFileVisibilities ( ) ; }
void DirectoryMergeWindow : : slotShowDifferentFiles ( ) { updateFileVisibilities ( ) ; }
void DirectoryMergeWindow : : slotShowFilesOnlyInA ( ) { updateFileVisibilities ( ) ; }
void DirectoryMergeWindow : : slotShowFilesOnlyInB ( ) { updateFileVisibilities ( ) ; }
void DirectoryMergeWindow : : slotShowFilesOnlyInC ( ) { updateFileVisibilities ( ) ; }
void DirectoryMergeWindow : : slotSynchronizeDirectories ( ) { }
void DirectoryMergeWindow : : slotChooseNewerFiles ( ) { }
void DirectoryMergeWindow : : initDirectoryMergeActions ( TQObject * pKDiff3App , TDEActionCollection * ac )
{
# include "xpm/startmerge.xpm"
# include "xpm/showequalfiles.xpm"
# include "xpm/showfilesonlyina.xpm"
# include "xpm/showfilesonlyinb.xpm"
# include "xpm/showfilesonlyinc.xpm"
DirectoryMergeWindow * p = this ;
m_pDirStartOperation = new TDEAction ( i18n ( " Start/Continue Directory Merge " ) , TQt : : Key_F7 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotRunOperationForAllItems ( ) ) , ac , " dir_start_operation " ) ;
m_pDirRunOperationForCurrentItem = new TDEAction ( i18n ( " Run Operation for Current Item " ) , TQt : : Key_F6 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotRunOperationForCurrentItem ( ) ) , ac , " dir_run_operation_for_current_item " ) ;
m_pDirCompareCurrent = new TDEAction ( i18n ( " Compare Selected File " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( compareCurrentFile ( ) ) , ac , " dir_compare_current " ) ;
m_pDirMergeCurrent = new TDEAction ( i18n ( " Merge Current File " ) , TQIconSet ( TQPixmap ( startmerge ) ) , 0 , TQT_TQOBJECT ( pKDiff3App ) , TQT_SLOT ( slotMergeCurrentFile ( ) ) , ac , " merge_current " ) ;
m_pDirFoldAll = new TDEAction ( i18n ( " Fold All Subdirs " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotFoldAllSubdirs ( ) ) , ac , " dir_fold_all " ) ;
m_pDirUnfoldAll = new TDEAction ( i18n ( " Unfold All Subdirs " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotUnfoldAllSubdirs ( ) ) , ac , " dir_unfold_all " ) ;
m_pDirRescan = new TDEAction ( i18n ( " Rescan " ) , TQt : : SHIFT + TQt : : Key_F5 , TQT_TQOBJECT ( p ) , TQT_SLOT ( reload ( ) ) , ac , " dir_rescan " ) ;
m_pDirSaveMergeState = 0 ; //new TDEAction(i18n("Save Directory Merge State ..."), 0, TQT_TQOBJECT(p), TQT_SLOT(slotSaveMergeState()), ac, "dir_save_merge_state");
m_pDirLoadMergeState = 0 ; //new TDEAction(i18n("Load Directory Merge State ..."), 0, TQT_TQOBJECT(p), TQT_SLOT(slotLoadMergeState()), ac, "dir_load_merge_state");
m_pDirChooseAEverywhere = new TDEAction ( i18n ( " Choose A for All Items " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotChooseAEverywhere ( ) ) , ac , " dir_choose_a_everywhere " ) ;
m_pDirChooseBEverywhere = new TDEAction ( i18n ( " Choose B for All Items " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotChooseBEverywhere ( ) ) , ac , " dir_choose_b_everywhere " ) ;
m_pDirChooseCEverywhere = new TDEAction ( i18n ( " Choose C for All Items " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotChooseCEverywhere ( ) ) , ac , " dir_choose_c_everywhere " ) ;
m_pDirAutoChoiceEverywhere = new TDEAction ( i18n ( " Auto-Choose Operation for All Items " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotAutoChooseEverywhere ( ) ) , ac , " dir_autochoose_everywhere " ) ;
m_pDirDoNothingEverywhere = new TDEAction ( i18n ( " No Operation for All Items " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotNoOpEverywhere ( ) ) , ac , " dir_nothing_everywhere " ) ;
// m_pDirSynchronizeDirectories = new TDEToggleAction(i18n("Synchronize Directories"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotSynchronizeDirectories()), ac, "dir_synchronize_directories");
// m_pDirChooseNewerFiles = new TDEToggleAction(i18n("Copy Newer Files Instead of Merging"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotChooseNewerFiles()), ac, "dir_choose_newer_files");
m_pDirShowIdenticalFiles = new TDEToggleAction ( i18n ( " Show Identical Files " ) , TQIconSet ( TQPixmap ( showequalfiles ) ) , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slotShowIdenticalFiles ( ) ) , ac , " dir_show_identical_files " ) ;
m_pDirShowDifferentFiles = new TDEToggleAction ( i18n ( " Show Different Files " ) , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slotShowDifferentFiles ( ) ) , ac , " dir_show_different_files " ) ;
m_pDirShowFilesOnlyInA = new TDEToggleAction ( i18n ( " Show Files only in A " ) , TQIconSet ( TQPixmap ( showfilesonlyina ) ) , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slotShowFilesOnlyInA ( ) ) , ac , " dir_show_files_only_in_a " ) ;
m_pDirShowFilesOnlyInB = new TDEToggleAction ( i18n ( " Show Files only in B " ) , TQIconSet ( TQPixmap ( showfilesonlyinb ) ) , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slotShowFilesOnlyInB ( ) ) , ac , " dir_show_files_only_in_b " ) ;
m_pDirShowFilesOnlyInC = new TDEToggleAction ( i18n ( " Show Files only in C " ) , TQIconSet ( TQPixmap ( showfilesonlyinc ) ) , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slotShowFilesOnlyInC ( ) ) , ac , " dir_show_files_only_in_c " ) ;
m_pDirShowIdenticalFiles - > setChecked ( m_pOptions - > m_bDmShowIdenticalFiles ) ;
m_pDirCompareExplicit = new TDEAction ( i18n ( " Compare Explicitly Selected Files " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotCompareExplicitlySelectedFiles ( ) ) , ac , " dir_compare_explicitly_selected_files " ) ;
m_pDirMergeExplicit = new TDEAction ( i18n ( " Merge Explicitly Selected Files " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotMergeExplicitlySelectedFiles ( ) ) , ac , " dir_merge_explicitly_selected_files " ) ;
m_pDirCurrentDoNothing = new TDEAction ( i18n ( " Do Nothing " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotCurrentDoNothing ( ) ) , ac , " dir_current_do_nothing " ) ;
m_pDirCurrentChooseA = new TDEAction ( i18n ( " A " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotCurrentChooseA ( ) ) , ac , " dir_current_choose_a " ) ;
m_pDirCurrentChooseB = new TDEAction ( i18n ( " B " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotCurrentChooseB ( ) ) , ac , " dir_current_choose_b " ) ;
m_pDirCurrentChooseC = new TDEAction ( i18n ( " C " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotCurrentChooseC ( ) ) , ac , " dir_current_choose_c " ) ;
m_pDirCurrentMerge = new TDEAction ( i18n ( " Merge " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotCurrentMerge ( ) ) , ac , " dir_current_merge " ) ;
m_pDirCurrentDelete = new TDEAction ( i18n ( " Delete (if exists) " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotCurrentDelete ( ) ) , ac , " dir_current_delete " ) ;
m_pDirCurrentSyncDoNothing = new TDEAction ( i18n ( " Do Nothing " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotCurrentDoNothing ( ) ) , ac , " dir_current_sync_do_nothing " ) ;
m_pDirCurrentSyncCopyAToB = new TDEAction ( i18n ( " Copy A to B " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotCurrentCopyAToB ( ) ) , ac , " dir_current_sync_copy_a_to_b " ) ;
m_pDirCurrentSyncCopyBToA = new TDEAction ( i18n ( " Copy B to A " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotCurrentCopyBToA ( ) ) , ac , " dir_current_sync_copy_b_to_a " ) ;
m_pDirCurrentSyncDeleteA = new TDEAction ( i18n ( " Delete A " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotCurrentDeleteA ( ) ) , ac , " dir_current_sync_delete_a " ) ;
m_pDirCurrentSyncDeleteB = new TDEAction ( i18n ( " Delete B " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotCurrentDeleteB ( ) ) , ac , " dir_current_sync_delete_b " ) ;
m_pDirCurrentSyncDeleteAAndB = new TDEAction ( i18n ( " Delete A && B " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotCurrentDeleteAAndB ( ) ) , ac , " dir_current_sync_delete_a_and_b " ) ;
m_pDirCurrentSyncMergeToA = new TDEAction ( i18n ( " Merge to A " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotCurrentMergeToA ( ) ) , ac , " dir_current_sync_merge_to_a " ) ;
m_pDirCurrentSyncMergeToB = new TDEAction ( i18n ( " Merge to B " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotCurrentMergeToB ( ) ) , ac , " dir_current_sync_merge_to_b " ) ;
m_pDirCurrentSyncMergeToAAndB = new TDEAction ( i18n ( " Merge to A && B " ) , 0 , TQT_TQOBJECT ( p ) , TQT_SLOT ( slotCurrentMergeToAAndB ( ) ) , ac , " dir_current_sync_merge_to_a_and_b " ) ;
}
void DirectoryMergeWindow : : updateAvailabilities ( bool bDirCompare , bool bDiffWindowVisible ,
TDEToggleAction * chooseA , TDEToggleAction * chooseB , TDEToggleAction * chooseC )
{
m_pDirStartOperation - > setEnabled ( bDirCompare ) ;
m_pDirRunOperationForCurrentItem - > setEnabled ( bDirCompare ) ;
m_pDirFoldAll - > setEnabled ( bDirCompare ) ;
m_pDirUnfoldAll - > setEnabled ( bDirCompare ) ;
m_pDirCompareCurrent - > setEnabled ( bDirCompare & & isVisible ( ) & & isFileSelected ( ) ) ;
m_pDirMergeCurrent - > setEnabled ( bDirCompare & & isVisible ( ) & & isFileSelected ( )
| | bDiffWindowVisible ) ;
m_pDirRescan - > setEnabled ( bDirCompare ) ;
m_pDirAutoChoiceEverywhere - > setEnabled ( bDirCompare & & isVisible ( ) ) ;
m_pDirDoNothingEverywhere - > setEnabled ( bDirCompare & & isVisible ( ) ) ;
m_pDirChooseAEverywhere - > setEnabled ( bDirCompare & & isVisible ( ) ) ;
m_pDirChooseBEverywhere - > setEnabled ( bDirCompare & & isVisible ( ) ) ;
m_pDirChooseCEverywhere - > setEnabled ( bDirCompare & & isVisible ( ) ) ;
bool bThreeDirs = m_dirC . isValid ( ) ;
TQListViewItem * lvi = currentItem ( ) ;
DirMergeItem * pDMI = lvi = = 0 ? 0 : static_cast < DirMergeItem * > ( lvi ) ;
MergeFileInfos * pMFI = pDMI = = 0 ? 0 : pDMI - > m_pMFI ;
bool bItemActive = bDirCompare & & isVisible ( ) & & pMFI ! = 0 ; // && hasFocus();
bool bMergeMode = bThreeDirs | | ! m_bSyncMode ;
bool bFTConflict = pMFI = = 0 ? false : conflictingFileTypes ( * pMFI ) ;
bool bDirWindowHasFocus = isVisible ( ) & & hasFocus ( ) ;
m_pDirShowIdenticalFiles - > setEnabled ( bDirCompare & & isVisible ( ) ) ;
m_pDirShowDifferentFiles - > setEnabled ( bDirCompare & & isVisible ( ) ) ;
m_pDirShowFilesOnlyInA - > setEnabled ( bDirCompare & & isVisible ( ) ) ;
m_pDirShowFilesOnlyInB - > setEnabled ( bDirCompare & & isVisible ( ) ) ;
m_pDirShowFilesOnlyInC - > setEnabled ( bDirCompare & & isVisible ( ) & & bThreeDirs ) ;
m_pDirCompareExplicit - > setEnabled ( bDirCompare & & isVisible ( ) & & m_pSelection2Item ! = 0 ) ;
m_pDirMergeExplicit - > setEnabled ( bDirCompare & & isVisible ( ) & & m_pSelection2Item ! = 0 ) ;
m_pDirCurrentDoNothing - > setEnabled ( bItemActive & & bMergeMode ) ;
m_pDirCurrentChooseA - > setEnabled ( bItemActive & & bMergeMode & & pMFI - > m_bExistsInA ) ;
m_pDirCurrentChooseB - > setEnabled ( bItemActive & & bMergeMode & & pMFI - > m_bExistsInB ) ;
m_pDirCurrentChooseC - > setEnabled ( bItemActive & & bMergeMode & & pMFI - > m_bExistsInC ) ;
m_pDirCurrentMerge - > setEnabled ( bItemActive & & bMergeMode & & ! bFTConflict ) ;
m_pDirCurrentDelete - > setEnabled ( bItemActive & & bMergeMode ) ;
if ( bDirWindowHasFocus )
{
chooseA - > setEnabled ( bItemActive & & pMFI - > m_bExistsInA ) ;
chooseB - > setEnabled ( bItemActive & & pMFI - > m_bExistsInB ) ;
chooseC - > setEnabled ( bItemActive & & pMFI - > m_bExistsInC ) ;
chooseA - > setChecked ( false ) ;
chooseB - > setChecked ( false ) ;
chooseC - > setChecked ( false ) ;
}
m_pDirCurrentSyncDoNothing - > setEnabled ( bItemActive & & ! bMergeMode ) ;
m_pDirCurrentSyncCopyAToB - > setEnabled ( bItemActive & & ! bMergeMode & & pMFI - > m_bExistsInA ) ;
m_pDirCurrentSyncCopyBToA - > setEnabled ( bItemActive & & ! bMergeMode & & pMFI - > m_bExistsInB ) ;
m_pDirCurrentSyncDeleteA - > setEnabled ( bItemActive & & ! bMergeMode & & pMFI - > m_bExistsInA ) ;
m_pDirCurrentSyncDeleteB - > setEnabled ( bItemActive & & ! bMergeMode & & pMFI - > m_bExistsInB ) ;
m_pDirCurrentSyncDeleteAAndB - > setEnabled ( bItemActive & & ! bMergeMode & & pMFI - > m_bExistsInB & & pMFI - > m_bExistsInB ) ;
m_pDirCurrentSyncMergeToA - > setEnabled ( bItemActive & & ! bMergeMode & & ! bFTConflict ) ;
m_pDirCurrentSyncMergeToB - > setEnabled ( bItemActive & & ! bMergeMode & & ! bFTConflict ) ;
m_pDirCurrentSyncMergeToAAndB - > setEnabled ( bItemActive & & ! bMergeMode & & ! bFTConflict ) ;
}
# include "directorymergewindow.moc"