diff options
Diffstat (limited to 'src/directorymergewindow.h')
-rw-r--r-- | src/directorymergewindow.h | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/src/directorymergewindow.h b/src/directorymergewindow.h new file mode 100644 index 0000000..77b09fd --- /dev/null +++ b/src/directorymergewindow.h @@ -0,0 +1,362 @@ +/*************************************************************************** + 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 <qfileinfo.h> +#include <qlistview.h> +#include <qtimer.h> +#include <qdir.h> +#include <list> +#include <map> +#include "common.h" +#include "fileaccess.h" +#include "diff.h" //TotalDiffStatus + +class OptionDialog; +class KIconLoader; +class StatusInfo; +class DirectoryMergeInfo; +class OneDirectoryInfo; +class QLabel; +class KAction; +class KToggleAction; +class KActionCollection; +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& ); + QString 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 QListViewItem +{ +public: + DirMergeItem( QListView* pParent, const QString&, MergeFileInfos*); + DirMergeItem( DirMergeItem* pParent, const QString&, MergeFileInfos*); + ~DirMergeItem(); + MergeFileInfos* m_pMFI; + virtual int compare(QListViewItem *i, int col, bool ascending) const; + virtual void paintCell(QPainter * p, const QColorGroup & cg, int column, int width, int align ); + void init(MergeFileInfos* pMFI); +}; + +class DirectoryMergeWindow : public QListView +{ + Q_OBJECT +public: + DirectoryMergeWindow( QWidget* pParent, OptionDialog* pOptions, KIconLoader* 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( QObject* pKDiff3App, KActionCollection* ac ); + void updateAvailabilities( bool bDirCompare, bool bDiffWindowVisible, + KToggleAction* chooseA, KToggleAction* chooseB, KToggleAction* chooseC ); + void updateFileVisibilities(); + + virtual void keyPressEvent( QKeyEvent* e ); + virtual void focusInEvent( QFocusEvent* e ); + virtual void focusOutEvent( QFocusEvent* e ); + + QString getDirNameA(){ return m_dirA.prettyAbsPath(); } + QString getDirNameB(){ return m_dirB.prettyAbsPath(); } + QString getDirNameC(){ return m_dirC.prettyAbsPath(); } + QString getDirNameDest(){ return m_dirDest.prettyAbsPath(); } + +public slots: + void reload(); + void mergeCurrentFile(); + void compareCurrentFile(); + void slotRunOperationForAllItems(); + void slotRunOperationForCurrentItem(); + void mergeResultSaved(const QString& 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(QResizeEvent* 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( QListViewItem* pBegin, QListViewItem* pEnd, bool bVerbose ); + bool executeMergeOperation( MergeFileInfos& mfi, bool& bSingleFileMerge ); + + void scanDirectory( const QString& dirName, t_DirectoryList& dirList ); + void scanLocalDirectory( const QString& dirName, t_DirectoryList& dirList ); + void fastFileComparison( FileAccess& fi1, FileAccess& fi2, + bool& bEqual, bool& bError, QString& status ); + void compareFilesAndCalcAges( MergeFileInfos& mfi ); + + QString fullNameA( const MergeFileInfos& mfi ) + { return mfi.m_bExistsInA ? mfi.m_fileInfoA.absFilePath() : m_dirA.absFilePath() + "/" + mfi.m_subPath; } + QString fullNameB( const MergeFileInfos& mfi ) + { return mfi.m_bExistsInB ? mfi.m_fileInfoB.absFilePath() : m_dirB.absFilePath() + "/" + mfi.m_subPath; } + QString fullNameC( const MergeFileInfos& mfi ) + { return mfi.m_bExistsInC ? mfi.m_fileInfoC.absFilePath() : m_dirC.absFilePath() + "/" + mfi.m_subPath; } + QString 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 QString& srcName, const QString& destName ); + bool deleteFLD( const QString& name, bool bCreateBackup ); + bool makeDir( const QString& name, bool bQuiet=false ); + bool renameFLD( const QString& srcName, const QString& destName ); + bool mergeFLD( const QString& nameA,const QString& nameB,const QString& nameC, + const QString& nameDest, bool& bSingleFileMerge ); + + FileAccess m_dirA; + FileAccess m_dirB; + FileAccess m_dirC; + FileAccess m_dirDest; + FileAccess m_dirDestInternal; + + QString m_dirMergeStateFilename; + + std::map<QString, 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; + KIconLoader* 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; + + KAction* m_pDirStartOperation; + KAction* m_pDirRunOperationForCurrentItem; + KAction* m_pDirCompareCurrent; + KAction* m_pDirMergeCurrent; + KAction* m_pDirRescan; + KAction* m_pDirChooseAEverywhere; + KAction* m_pDirChooseBEverywhere; + KAction* m_pDirChooseCEverywhere; + KAction* m_pDirAutoChoiceEverywhere; + KAction* m_pDirDoNothingEverywhere; + KAction* m_pDirFoldAll; + KAction* m_pDirUnfoldAll; + + KToggleAction* m_pDirShowIdenticalFiles; + KToggleAction* m_pDirShowDifferentFiles; + KToggleAction* m_pDirShowFilesOnlyInA; + KToggleAction* m_pDirShowFilesOnlyInB; + KToggleAction* m_pDirShowFilesOnlyInC; + + KToggleAction* m_pDirSynchronizeDirectories; + KToggleAction* m_pDirChooseNewerFiles; + + KAction* m_pDirCompareExplicit; + KAction* m_pDirMergeExplicit; + + KAction* m_pDirCurrentDoNothing; + KAction* m_pDirCurrentChooseA; + KAction* m_pDirCurrentChooseB; + KAction* m_pDirCurrentChooseC; + KAction* m_pDirCurrentMerge; + KAction* m_pDirCurrentDelete; + + KAction* m_pDirCurrentSyncDoNothing; + KAction* m_pDirCurrentSyncCopyAToB; + KAction* m_pDirCurrentSyncCopyBToA; + KAction* m_pDirCurrentSyncDeleteA; + KAction* m_pDirCurrentSyncDeleteB; + KAction* m_pDirCurrentSyncDeleteAAndB; + KAction* m_pDirCurrentSyncMergeToA; + KAction* m_pDirCurrentSyncMergeToB; + KAction* m_pDirCurrentSyncMergeToAAndB; + + KAction* m_pDirSaveMergeState; + KAction* m_pDirLoadMergeState; +signals: + void startDiffMerge(QString fn1,QString fn2, QString fn3, QString ofn, QString,QString,QString,TotalDiffStatus*); + void checkIfCanContinue( bool* pbContinue ); + void updateAvailabilities(); + void statusBarMessage( const QString& msg ); +protected slots: + void onDoubleClick( QListViewItem* lvi ); + void onClick( int button, QListViewItem* lvi, const QPoint&, int c ); + void slotShowContextMenu(QListViewItem* lvi,const QPoint &,int c); + void onSelectionChanged(QListViewItem* lvi); +}; + +class DirectoryMergeInfo : public QFrame +{ + Q_OBJECT +public: + DirectoryMergeInfo( QWidget* pParent ); + void setInfo( + const FileAccess& APath, + const FileAccess& BPath, + const FileAccess& CPath, + const FileAccess& DestPath, + MergeFileInfos& mfi ); + QListView* getInfoList() {return m_pInfoList;} + virtual bool eventFilter( QObject* o, QEvent* e ); +signals: + void gotFocus(); +private: + QLabel* m_pInfoA; + QLabel* m_pInfoB; + QLabel* m_pInfoC; + QLabel* m_pInfoDest; + + QLabel* m_pA; + QLabel* m_pB; + QLabel* m_pC; + QLabel* m_pDest; + + QListView* m_pInfoList; +}; + + +#endif |