|
|
|
/***************************************************************************
|
|
|
|
directorymergewindow.h
|
|
|
|
-------------------
|
|
|
|
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. *
|
|
|
|
* *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#ifndef DIRECTORY_MERGE_WINDOW_H
|
|
|
|
#define DIRECTORY_MERGE_WINDOW_H
|
|
|
|
|
|
|
|
#include <tqfileinfo.h>
|
|
|
|
#include <tqlistview.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <list>
|
|
|
|
#include <map>
|
|
|
|
#include "common.h"
|
|
|
|
#include "fileaccess.h"
|
|
|
|
#include "diff.h" //TotalDiffStatus
|
|
|
|
|
|
|
|
class OptionDialog;
|
|
|
|
class TDEIconLoader;
|
|
|
|
class StatusInfo;
|
|
|
|
class DirectoryMergeInfo;
|
|
|
|
class OneDirectoryInfo;
|
|
|
|
class TQLabel;
|
|
|
|
class TDEAction;
|
|
|
|
class TDEToggleAction;
|
|
|
|
class TDEActionCollection;
|
|
|
|
class TotalDiffStatus;
|
|
|
|
|
|
|
|
enum e_MergeOperation
|
|
|
|
{
|
|
|
|
eTitleId,
|
|
|
|
eNoOperation,
|
|
|
|
// Operations in sync mode (with only two directories):
|
|
|
|
eCopyAToB, eCopyBToA, eDeleteA, eDeleteB, eDeleteAB, eMergeToA, eMergeToB, eMergeToAB,
|
|
|
|
|
|
|
|
// Operations in merge mode (with two or three directories)
|
|
|
|
eCopyAToDest, eCopyBToDest, eCopyCToDest, eDeleteFromDest, eMergeABCToDest,
|
|
|
|
eMergeABToDest,
|
|
|
|
eConflictingFileTypes, // Error
|
|
|
|
eConflictingAges // Equal age but files are not!
|
|
|
|
};
|
|
|
|
|
|
|
|
class DirMergeItem;
|
|
|
|
|
|
|
|
enum e_Age { eNew, eMiddle, eOld, eNotThere, eAgeEnd };
|
|
|
|
|
|
|
|
class MergeFileInfos
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
MergeFileInfos(){ m_bEqualAB=false; m_bEqualAC=false; m_bEqualBC=false;
|
|
|
|
m_pDMI=0; m_pParent=0;
|
|
|
|
m_bExistsInA=false;m_bExistsInB=false;m_bExistsInC=false;
|
|
|
|
m_bDirA=false; m_bDirB=false; m_bDirC=false;
|
|
|
|
m_bLinkA=false; m_bLinkB=false; m_bLinkC=false;
|
|
|
|
m_bOperationComplete=false; m_bSimOpComplete = false;
|
|
|
|
m_eMergeOperation=eNoOperation;
|
|
|
|
m_ageA = eNotThere; m_ageB=eNotThere; m_ageC=eNotThere;
|
|
|
|
m_bConflictingAges=false; }
|
|
|
|
bool operator>( const MergeFileInfos& );
|
|
|
|
TQString m_subPath;
|
|
|
|
|
|
|
|
bool m_bExistsInA;
|
|
|
|
bool m_bExistsInB;
|
|
|
|
bool m_bExistsInC;
|
|
|
|
bool m_bEqualAB;
|
|
|
|
bool m_bEqualAC;
|
|
|
|
bool m_bEqualBC;
|
|
|
|
DirMergeItem* m_pDMI;
|
|
|
|
MergeFileInfos* m_pParent;
|
|
|
|
e_MergeOperation m_eMergeOperation;
|
|
|
|
void setMergeOperation( e_MergeOperation eMOp, bool bRecursive=true );
|
|
|
|
bool m_bDirA;
|
|
|
|
bool m_bDirB;
|
|
|
|
bool m_bDirC;
|
|
|
|
bool m_bLinkA;
|
|
|
|
bool m_bLinkB;
|
|
|
|
bool m_bLinkC;
|
|
|
|
bool m_bOperationComplete;
|
|
|
|
bool m_bSimOpComplete;
|
|
|
|
e_Age m_ageA;
|
|
|
|
e_Age m_ageB;
|
|
|
|
e_Age m_ageC;
|
|
|
|
bool m_bConflictingAges; // Equal age but files are not!
|
|
|
|
|
|
|
|
FileAccess m_fileInfoA;
|
|
|
|
FileAccess m_fileInfoB;
|
|
|
|
FileAccess m_fileInfoC;
|
|
|
|
|
|
|
|
TotalDiffStatus m_totalDiffStatus;
|
|
|
|
};
|
|
|
|
|
|
|
|
class DirMergeItem : public TQListViewItem
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
DirMergeItem( TQListView* pParent, const TQString&, MergeFileInfos*);
|
|
|
|
DirMergeItem( DirMergeItem* pParent, const TQString&, MergeFileInfos*);
|
|
|
|
~DirMergeItem();
|
|
|
|
MergeFileInfos* m_pMFI;
|
|
|
|
virtual int compare(TQListViewItem *i, int col, bool ascending) const;
|
|
|
|
virtual void paintCell(TQPainter * p, const TQColorGroup & cg, int column, int width, int align );
|
|
|
|
void init(MergeFileInfos* pMFI);
|
|
|
|
};
|
|
|
|
|
|
|
|
class DirectoryMergeWindow : public TQListView
|
|
|
|
{
|
|
|
|
TQ_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
DirectoryMergeWindow( TQWidget* pParent, OptionDialog* pOptions, TDEIconLoader* pIconLoader );
|
|
|
|
~DirectoryMergeWindow();
|
|
|
|
void setDirectoryMergeInfo(DirectoryMergeInfo* p){ m_pDirectoryMergeInfo=p; }
|
|
|
|
bool init(
|
|
|
|
FileAccess& dirA,
|
|
|
|
FileAccess& dirB,
|
|
|
|
FileAccess& dirC,
|
|
|
|
FileAccess& dirDest,
|
|
|
|
bool bDirectoryMerge,
|
|
|
|
bool bReload = false
|
|
|
|
);
|
|
|
|
bool isFileSelected();
|
|
|
|
void allowResizeEvents(bool bAllowResizeEvents);
|
|
|
|
bool isDirectoryMergeInProgress() { return m_bRealMergeStarted; }
|
|
|
|
int totalColumnWidth();
|
|
|
|
bool isSyncMode() { return m_bSyncMode; }
|
|
|
|
bool isScanning() { return m_bScanning; }
|
|
|
|
void initDirectoryMergeActions( TQObject* pKDiff3App, TDEActionCollection* ac );
|
|
|
|
void updateAvailabilities( bool bDirCompare, bool bDiffWindowVisible,
|
|
|
|
TDEToggleAction* chooseA, TDEToggleAction* chooseB, TDEToggleAction* chooseC );
|
|
|
|
void updateFileVisibilities();
|
|
|
|
|
|
|
|
virtual void keyPressEvent( TQKeyEvent* e );
|
|
|
|
virtual void focusInEvent( TQFocusEvent* e );
|
|
|
|
virtual void focusOutEvent( TQFocusEvent* e );
|
|
|
|
|
|
|
|
TQString getDirNameA(){ return m_dirA.prettyAbsPath(); }
|
|
|
|
TQString getDirNameB(){ return m_dirB.prettyAbsPath(); }
|
|
|
|
TQString getDirNameC(){ return m_dirC.prettyAbsPath(); }
|
|
|
|
TQString getDirNameDest(){ return m_dirDest.prettyAbsPath(); }
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
void reload();
|
|
|
|
void mergeCurrentFile();
|
|
|
|
void compareCurrentFile();
|
|
|
|
void slotRunOperationForAllItems();
|
|
|
|
void slotRunOperationForCurrentItem();
|
|
|
|
void mergeResultSaved(const TQString& fileName);
|
|
|
|
void slotChooseAEverywhere();
|
|
|
|
void slotChooseBEverywhere();
|
|
|
|
void slotChooseCEverywhere();
|
|
|
|
void slotAutoChooseEverywhere();
|
|
|
|
void slotNoOpEverywhere();
|
|
|
|
void slotFoldAllSubdirs();
|
|
|
|
void slotUnfoldAllSubdirs();
|
|
|
|
void slotShowIdenticalFiles();
|
|
|
|
void slotShowDifferentFiles();
|
|
|
|
void slotShowFilesOnlyInA();
|
|
|
|
void slotShowFilesOnlyInB();
|
|
|
|
void slotShowFilesOnlyInC();
|
|
|
|
|
|
|
|
void slotSynchronizeDirectories();
|
|
|
|
void slotChooseNewerFiles();
|
|
|
|
|
|
|
|
void slotCompareExplicitlySelectedFiles();
|
|
|
|
void slotMergeExplicitlySelectedFiles();
|
|
|
|
|
|
|
|
// Merge current item (merge mode)
|
|
|
|
void slotCurrentDoNothing();
|
|
|
|
void slotCurrentChooseA();
|
|
|
|
void slotCurrentChooseB();
|
|
|
|
void slotCurrentChooseC();
|
|
|
|
void slotCurrentMerge();
|
|
|
|
void slotCurrentDelete();
|
|
|
|
// Sync current item
|
|
|
|
void slotCurrentCopyAToB();
|
|
|
|
void slotCurrentCopyBToA();
|
|
|
|
void slotCurrentDeleteA();
|
|
|
|
void slotCurrentDeleteB();
|
|
|
|
void slotCurrentDeleteAAndB();
|
|
|
|
void slotCurrentMergeToA();
|
|
|
|
void slotCurrentMergeToB();
|
|
|
|
void slotCurrentMergeToAAndB();
|
|
|
|
|
|
|
|
void slotSaveMergeState();
|
|
|
|
void slotLoadMergeState();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void mergeContinue( bool bStart, bool bVerbose );
|
|
|
|
void resizeEvent(TQResizeEvent* e);
|
|
|
|
bool m_bAllowResizeEvents;
|
|
|
|
|
|
|
|
void prepareListView(ProgressProxy& pp);
|
|
|
|
void calcSuggestedOperation( MergeFileInfos& mfi, e_MergeOperation eDefaultOperation );
|
|
|
|
void setAllMergeOperations( e_MergeOperation eDefaultOperation );
|
|
|
|
friend class MergeFileInfos;
|
|
|
|
|
|
|
|
bool canContinue();
|
|
|
|
void prepareMergeStart( TQListViewItem* pBegin, TQListViewItem* pEnd, bool bVerbose );
|
|
|
|
bool executeMergeOperation( MergeFileInfos& mfi, bool& bSingleFileMerge );
|
|
|
|
|
|
|
|
void scanDirectory( const TQString& dirName, t_DirectoryList& dirList );
|
|
|
|
void scanLocalDirectory( const TQString& dirName, t_DirectoryList& dirList );
|
|
|
|
void fastFileComparison( FileAccess& fi1, FileAccess& fi2,
|
|
|
|
bool& bEqual, bool& bError, TQString& status );
|
|
|
|
void compareFilesAndCalcAges( MergeFileInfos& mfi );
|
|
|
|
|
|
|
|
TQString fullNameA( const MergeFileInfos& mfi )
|
|
|
|
{ return mfi.m_bExistsInA ? mfi.m_fileInfoA.absFilePath() : m_dirA.absFilePath() + "/" + mfi.m_subPath; }
|
|
|
|
TQString fullNameB( const MergeFileInfos& mfi )
|
|
|
|
{ return mfi.m_bExistsInB ? mfi.m_fileInfoB.absFilePath() : m_dirB.absFilePath() + "/" + mfi.m_subPath; }
|
|
|
|
TQString fullNameC( const MergeFileInfos& mfi )
|
|
|
|
{ return mfi.m_bExistsInC ? mfi.m_fileInfoC.absFilePath() : m_dirC.absFilePath() + "/" + mfi.m_subPath; }
|
|
|
|
TQString fullNameDest( const MergeFileInfos& mfi )
|
|
|
|
{ if ( m_dirDestInternal.prettyAbsPath() == m_dirC.prettyAbsPath() ) return fullNameC(mfi);
|
|
|
|
else if ( m_dirDestInternal.prettyAbsPath() == m_dirB.prettyAbsPath() ) return fullNameB(mfi);
|
|
|
|
else return m_dirDestInternal.absFilePath() + "/" + mfi.m_subPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool copyFLD( const TQString& srcName, const TQString& destName );
|
|
|
|
bool deleteFLD( const TQString& name, bool bCreateBackup );
|
|
|
|
bool makeDir( const TQString& name, bool bQuiet=false );
|
|
|
|
bool renameFLD( const TQString& srcName, const TQString& destName );
|
|
|
|
bool mergeFLD( const TQString& nameA,const TQString& nameB,const TQString& nameC,
|
|
|
|
const TQString& nameDest, bool& bSingleFileMerge );
|
|
|
|
|
|
|
|
FileAccess m_dirA;
|
|
|
|
FileAccess m_dirB;
|
|
|
|
FileAccess m_dirC;
|
|
|
|
FileAccess m_dirDest;
|
|
|
|
FileAccess m_dirDestInternal;
|
|
|
|
|
|
|
|
TQString m_dirMergeStateFilename;
|
|
|
|
|
|
|
|
std::map<TQString, MergeFileInfos> m_fileMergeMap;
|
|
|
|
|
|
|
|
bool m_bFollowDirLinks;
|
|
|
|
bool m_bFollowFileLinks;
|
|
|
|
bool m_bSimulatedMergeStarted;
|
|
|
|
bool m_bRealMergeStarted;
|
|
|
|
bool m_bError;
|
|
|
|
bool m_bSyncMode;
|
|
|
|
bool m_bDirectoryMerge; // if true, then merge is the default operation, otherwise it's diff.
|
|
|
|
bool m_bCaseSensitive;
|
|
|
|
|
|
|
|
bool m_bScanning; // true while in init()
|
|
|
|
|
|
|
|
OptionDialog* m_pOptions;
|
|
|
|
TDEIconLoader* m_pIconLoader;
|
|
|
|
DirectoryMergeInfo* m_pDirectoryMergeInfo;
|
|
|
|
StatusInfo* m_pStatusInfo;
|
|
|
|
|
|
|
|
typedef std::list<DirMergeItem*> MergeItemList;
|
|
|
|
MergeItemList m_mergeItemList;
|
|
|
|
MergeItemList::iterator m_currentItemForOperation;
|
|
|
|
|
|
|
|
DirMergeItem* m_pSelection1Item;
|
|
|
|
int m_selection1Column;
|
|
|
|
DirMergeItem* m_pSelection2Item;
|
|
|
|
int m_selection2Column;
|
|
|
|
DirMergeItem* m_pSelection3Item;
|
|
|
|
int m_selection3Column;
|
|
|
|
void selectItemAndColumn(DirMergeItem* pDMI, int c, bool bContextMenu);
|
|
|
|
friend class DirMergeItem;
|
|
|
|
|
|
|
|
TDEAction* m_pDirStartOperation;
|
|
|
|
TDEAction* m_pDirRunOperationForCurrentItem;
|
|
|
|
TDEAction* m_pDirCompareCurrent;
|
|
|
|
TDEAction* m_pDirMergeCurrent;
|
|
|
|
TDEAction* m_pDirRescan;
|
|
|
|
TDEAction* m_pDirChooseAEverywhere;
|
|
|
|
TDEAction* m_pDirChooseBEverywhere;
|
|
|
|
TDEAction* m_pDirChooseCEverywhere;
|
|
|
|
TDEAction* m_pDirAutoChoiceEverywhere;
|
|
|
|
TDEAction* m_pDirDoNothingEverywhere;
|
|
|
|
TDEAction* m_pDirFoldAll;
|
|
|
|
TDEAction* m_pDirUnfoldAll;
|
|
|
|
|
|
|
|
TDEToggleAction* m_pDirShowIdenticalFiles;
|
|
|
|
TDEToggleAction* m_pDirShowDifferentFiles;
|
|
|
|
TDEToggleAction* m_pDirShowFilesOnlyInA;
|
|
|
|
TDEToggleAction* m_pDirShowFilesOnlyInB;
|
|
|
|
TDEToggleAction* m_pDirShowFilesOnlyInC;
|
|
|
|
|
|
|
|
TDEToggleAction* m_pDirSynchronizeDirectories;
|
|
|
|
TDEToggleAction* m_pDirChooseNewerFiles;
|
|
|
|
|
|
|
|
TDEAction* m_pDirCompareExplicit;
|
|
|
|
TDEAction* m_pDirMergeExplicit;
|
|
|
|
|
|
|
|
TDEAction* m_pDirCurrentDoNothing;
|
|
|
|
TDEAction* m_pDirCurrentChooseA;
|
|
|
|
TDEAction* m_pDirCurrentChooseB;
|
|
|
|
TDEAction* m_pDirCurrentChooseC;
|
|
|
|
TDEAction* m_pDirCurrentMerge;
|
|
|
|
TDEAction* m_pDirCurrentDelete;
|
|
|
|
|
|
|
|
TDEAction* m_pDirCurrentSyncDoNothing;
|
|
|
|
TDEAction* m_pDirCurrentSyncCopyAToB;
|
|
|
|
TDEAction* m_pDirCurrentSyncCopyBToA;
|
|
|
|
TDEAction* m_pDirCurrentSyncDeleteA;
|
|
|
|
TDEAction* m_pDirCurrentSyncDeleteB;
|
|
|
|
TDEAction* m_pDirCurrentSyncDeleteAAndB;
|
|
|
|
TDEAction* m_pDirCurrentSyncMergeToA;
|
|
|
|
TDEAction* m_pDirCurrentSyncMergeToB;
|
|
|
|
TDEAction* m_pDirCurrentSyncMergeToAAndB;
|
|
|
|
|
|
|
|
TDEAction* m_pDirSaveMergeState;
|
|
|
|
TDEAction* m_pDirLoadMergeState;
|
|
|
|
signals:
|
|
|
|
void startDiffMerge(TQString fn1,TQString fn2, TQString fn3, TQString ofn, TQString,TQString,TQString,TotalDiffStatus*);
|
|
|
|
void checkIfCanContinue( bool* pbContinue );
|
|
|
|
void updateAvailabilities();
|
|
|
|
void statusBarMessage( const TQString& msg );
|
|
|
|
protected slots:
|
|
|
|
void onDoubleClick( TQListViewItem* lvi );
|
|
|
|
void onClick( int button, TQListViewItem* lvi, const TQPoint&, int c );
|
|
|
|
void slotShowContextMenu(TQListViewItem* lvi,const TQPoint &,int c);
|
|
|
|
void onSelectionChanged(TQListViewItem* lvi);
|
|
|
|
};
|
|
|
|
|
|
|
|
class DirectoryMergeInfo : public TQFrame
|
|
|
|
{
|
|
|
|
TQ_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
DirectoryMergeInfo( TQWidget* pParent );
|
|
|
|
void setInfo(
|
|
|
|
const FileAccess& APath,
|
|
|
|
const FileAccess& BPath,
|
|
|
|
const FileAccess& CPath,
|
|
|
|
const FileAccess& DestPath,
|
|
|
|
MergeFileInfos& mfi );
|
|
|
|
TQListView* getInfoList() {return m_pInfoList;}
|
|
|
|
virtual bool eventFilter( TQObject* o, TQEvent* e );
|
|
|
|
signals:
|
|
|
|
void gotFocus();
|
|
|
|
private:
|
|
|
|
TQLabel* m_pInfoA;
|
|
|
|
TQLabel* m_pInfoB;
|
|
|
|
TQLabel* m_pInfoC;
|
|
|
|
TQLabel* m_pInfoDest;
|
|
|
|
|
|
|
|
TQLabel* m_pA;
|
|
|
|
TQLabel* m_pB;
|
|
|
|
TQLabel* m_pC;
|
|
|
|
TQLabel* m_pDest;
|
|
|
|
|
|
|
|
TQListView* m_pInfoList;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|