joachim99@8: /*************************************************************************** joachim99@8: directorymergewindow.h joachim99@8: ------------------- joachim99@8: begin : Sat Oct 19 2002 joachim99@77: copyright : (C) 2002-2007 by Joachim Eibl joachim99@69: email : joachim.eibl at gmx.de joachim99@8: ***************************************************************************/ joachim99@8: joachim99@8: /*************************************************************************** joachim99@8: * * joachim99@8: * This program is free software; you can redistribute it and/or modify * joachim99@8: * it under the terms of the GNU General Public License as published by * joachim99@8: * the Free Software Foundation; either version 2 of the License, or * joachim99@8: * (at your option) any later version. * joachim99@8: * * joachim99@8: ***************************************************************************/ joachim99@8: joachim99@8: #ifndef DIRECTORY_MERGE_WINDOW_H joachim99@8: #define DIRECTORY_MERGE_WINDOW_H joachim99@8: joachim99@75: #include joachim99@80: #include joachim99@8: #include joachim99@8: #include joachim99@8: #include "common.h" joachim99@8: #include "fileaccess.h" joachim99@66: #include "diff.h" //TotalDiffStatus joachim99@8: joachim99@8: class OptionDialog; joachim99@8: class KIconLoader; joachim99@8: class StatusInfo; joachim99@8: class DirectoryMergeInfo; joachim99@8: class OneDirectoryInfo; joachim99@8: class QLabel; joachim99@51: class KAction; joachim99@51: class KToggleAction; joachim99@51: class KActionCollection; joachim99@66: class TotalDiffStatus; joachim99@8: joachim99@8: enum e_MergeOperation joachim99@8: { joachim99@8: eTitleId, joachim99@8: eNoOperation, joachim99@8: // Operations in sync mode (with only two directories): joachim99@8: eCopyAToB, eCopyBToA, eDeleteA, eDeleteB, eDeleteAB, eMergeToA, eMergeToB, eMergeToAB, joachim99@8: joachim99@8: // Operations in merge mode (with two or three directories) joachim99@8: eCopyAToDest, eCopyBToDest, eCopyCToDest, eDeleteFromDest, eMergeABCToDest, joachim99@8: eMergeABToDest, joachim99@8: eConflictingFileTypes, // Error joachim99@92: eChangedAndDeleted, // Error joachim99@8: eConflictingAges // Equal age but files are not! joachim99@8: }; joachim99@8: joachim99@8: class DirMergeItem; joachim99@8: joachim99@8: enum e_Age { eNew, eMiddle, eOld, eNotThere, eAgeEnd }; joachim99@8: joachim99@8: class MergeFileInfos joachim99@8: { joachim99@8: public: joachim99@8: MergeFileInfos(){ m_bEqualAB=false; m_bEqualAC=false; m_bEqualBC=false; joachim99@8: m_pDMI=0; m_pParent=0; joachim99@8: m_bExistsInA=false;m_bExistsInB=false;m_bExistsInC=false; joachim99@8: m_bDirA=false; m_bDirB=false; m_bDirC=false; joachim99@8: m_bLinkA=false; m_bLinkB=false; m_bLinkC=false; joachim99@8: m_bOperationComplete=false; m_bSimOpComplete = false; joachim99@8: m_eMergeOperation=eNoOperation; joachim99@8: m_ageA = eNotThere; m_ageB=eNotThere; m_ageC=eNotThere; joachim99@8: m_bConflictingAges=false; } joachim99@8: bool operator>( const MergeFileInfos& ); joachim99@8: QString m_subPath; joachim99@8: joachim99@8: bool m_bExistsInA; joachim99@8: bool m_bExistsInB; joachim99@8: bool m_bExistsInC; joachim99@8: bool m_bEqualAB; joachim99@8: bool m_bEqualAC; joachim99@8: bool m_bEqualBC; joachim99@8: DirMergeItem* m_pDMI; joachim99@8: MergeFileInfos* m_pParent; joachim99@8: e_MergeOperation m_eMergeOperation; joachim99@77: void setMergeOperation( e_MergeOperation eMOp, bool bRecursive=true ); joachim99@8: bool m_bDirA; joachim99@8: bool m_bDirB; joachim99@8: bool m_bDirC; joachim99@8: bool m_bLinkA; joachim99@8: bool m_bLinkB; joachim99@8: bool m_bLinkC; joachim99@8: bool m_bOperationComplete; joachim99@8: bool m_bSimOpComplete; joachim99@8: e_Age m_ageA; joachim99@8: e_Age m_ageB; joachim99@8: e_Age m_ageC; joachim99@8: bool m_bConflictingAges; // Equal age but files are not! joachim99@8: joachim99@8: FileAccess m_fileInfoA; joachim99@8: FileAccess m_fileInfoB; joachim99@8: FileAccess m_fileInfoC; joachim99@66: joachim99@66: TotalDiffStatus m_totalDiffStatus; joachim99@8: }; joachim99@8: joachim99@75: class DirMergeItem : public QTreeWidgetItem joachim99@8: { joachim99@8: public: joachim99@75: DirMergeItem( QTreeWidget* pParent, const QString&, MergeFileInfos*); joachim99@8: DirMergeItem( DirMergeItem* pParent, const QString&, MergeFileInfos*); joachim99@8: ~DirMergeItem(); joachim99@8: MergeFileInfos* m_pMFI; joachim99@75: virtual bool operator<( const QTreeWidgetItem& other ) const; joachim99@75: //virtual void paintCell(QPainter * p, const QColorGroup & cg, int column, int width, int align ); joachim99@66: void init(MergeFileInfos* pMFI); joachim99@8: }; joachim99@8: joachim99@75: class DirectoryMergeWindow : public QTreeWidget joachim99@8: { joachim99@8: Q_OBJECT joachim99@8: public: joachim99@8: DirectoryMergeWindow( QWidget* pParent, OptionDialog* pOptions, KIconLoader* pIconLoader ); joachim99@8: ~DirectoryMergeWindow(); joachim99@8: void setDirectoryMergeInfo(DirectoryMergeInfo* p){ m_pDirectoryMergeInfo=p; } joachim99@8: bool init( joachim99@8: FileAccess& dirA, joachim99@8: FileAccess& dirB, joachim99@8: FileAccess& dirC, joachim99@8: FileAccess& dirDest, joachim99@77: bool bDirectoryMerge, joachim99@77: bool bReload = false joachim99@8: ); joachim99@8: bool isFileSelected(); joachim99@8: bool isDirectoryMergeInProgress() { return m_bRealMergeStarted; } joachim99@8: int totalColumnWidth(); joachim99@8: bool isSyncMode() { return m_bSyncMode; } joachim99@66: bool isScanning() { return m_bScanning; } joachim99@51: void initDirectoryMergeActions( QObject* pKDiff3App, KActionCollection* ac ); joachim99@53: void updateAvailabilities( bool bDirCompare, bool bDiffWindowVisible, joachim99@53: KToggleAction* chooseA, KToggleAction* chooseB, KToggleAction* chooseC ); joachim99@69: void updateFileVisibilities(); joachim99@51: joachim99@75: virtual void mousePressEvent( QMouseEvent* e ); joachim99@51: virtual void keyPressEvent( QKeyEvent* e ); joachim99@53: virtual void focusInEvent( QFocusEvent* e ); joachim99@53: virtual void focusOutEvent( QFocusEvent* e ); joachim99@75: virtual void contextMenuEvent( QContextMenuEvent* e ); joachim99@75: QString getDirNameA(){ return m_dirA.prettyAbsPath(); } joachim99@75: QString getDirNameB(){ return m_dirB.prettyAbsPath(); } joachim99@75: QString getDirNameC(){ return m_dirC.prettyAbsPath(); } joachim99@75: QString getDirNameDest(){ return m_dirDest.prettyAbsPath(); } joachim99@8: joachim99@8: public slots: joachim99@8: void reload(); joachim99@8: void mergeCurrentFile(); joachim99@8: void compareCurrentFile(); joachim99@51: void slotRunOperationForAllItems(); joachim99@51: void slotRunOperationForCurrentItem(); joachim99@8: void mergeResultSaved(const QString& fileName); joachim99@8: void slotChooseAEverywhere(); joachim99@8: void slotChooseBEverywhere(); joachim99@8: void slotChooseCEverywhere(); joachim99@8: void slotAutoChooseEverywhere(); joachim99@8: void slotNoOpEverywhere(); joachim99@8: void slotFoldAllSubdirs(); joachim99@8: void slotUnfoldAllSubdirs(); joachim99@69: void slotShowIdenticalFiles(); joachim99@69: void slotShowDifferentFiles(); joachim99@69: void slotShowFilesOnlyInA(); joachim99@69: void slotShowFilesOnlyInB(); joachim99@69: void slotShowFilesOnlyInC(); joachim99@69: joachim99@69: void slotSynchronizeDirectories(); joachim99@69: void slotChooseNewerFiles(); joachim99@69: joachim99@69: void slotCompareExplicitlySelectedFiles(); joachim99@69: void slotMergeExplicitlySelectedFiles(); joachim99@69: joachim99@51: // Merge current item (merge mode) joachim99@51: void slotCurrentDoNothing(); joachim99@51: void slotCurrentChooseA(); joachim99@51: void slotCurrentChooseB(); joachim99@51: void slotCurrentChooseC(); joachim99@51: void slotCurrentMerge(); joachim99@51: void slotCurrentDelete(); joachim99@51: // Sync current item joachim99@51: void slotCurrentCopyAToB(); joachim99@51: void slotCurrentCopyBToA(); joachim99@51: void slotCurrentDeleteA(); joachim99@51: void slotCurrentDeleteB(); joachim99@51: void slotCurrentDeleteAAndB(); joachim99@51: void slotCurrentMergeToA(); joachim99@51: void slotCurrentMergeToB(); joachim99@51: void slotCurrentMergeToAAndB(); joachim99@8: joachim99@69: void slotSaveMergeState(); joachim99@69: void slotLoadMergeState(); joachim99@69: joachim99@8: protected: joachim99@75: class DirMergeItemDelegate; joachim99@51: void mergeContinue( bool bStart, bool bVerbose ); joachim99@8: joachim99@66: void prepareListView(ProgressProxy& pp); joachim99@8: void calcSuggestedOperation( MergeFileInfos& mfi, e_MergeOperation eDefaultOperation ); joachim99@8: void setAllMergeOperations( e_MergeOperation eDefaultOperation ); joachim99@8: friend class MergeFileInfos; joachim99@8: joachim99@8: bool canContinue(); joachim99@75: void prepareMergeStart( QTreeWidgetItem* pBegin, QTreeWidgetItem* pEnd, bool bVerbose ); joachim99@51: bool executeMergeOperation( MergeFileInfos& mfi, bool& bSingleFileMerge ); joachim99@8: joachim99@8: void scanDirectory( const QString& dirName, t_DirectoryList& dirList ); joachim99@8: void scanLocalDirectory( const QString& dirName, t_DirectoryList& dirList ); joachim99@8: void fastFileComparison( FileAccess& fi1, FileAccess& fi2, joachim99@8: bool& bEqual, bool& bError, QString& status ); joachim99@8: void compareFilesAndCalcAges( MergeFileInfos& mfi ); joachim99@8: joachim99@8: QString fullNameA( const MergeFileInfos& mfi ) joachim99@80: { return mfi.m_bExistsInA ? mfi.m_fileInfoA.absoluteFilePath() : m_dirA.absoluteFilePath() + "/" + mfi.m_subPath; } joachim99@8: QString fullNameB( const MergeFileInfos& mfi ) joachim99@80: { return mfi.m_bExistsInB ? mfi.m_fileInfoB.absoluteFilePath() : m_dirB.absoluteFilePath() + "/" + mfi.m_subPath; } joachim99@8: QString fullNameC( const MergeFileInfos& mfi ) joachim99@80: { return mfi.m_bExistsInC ? mfi.m_fileInfoC.absoluteFilePath() : m_dirC.absoluteFilePath() + "/" + mfi.m_subPath; } joachim99@8: QString fullNameDest( const MergeFileInfos& mfi ) joachim99@77: { if ( m_dirDestInternal.prettyAbsPath() == m_dirC.prettyAbsPath() ) return fullNameC(mfi); joachim99@77: else if ( m_dirDestInternal.prettyAbsPath() == m_dirB.prettyAbsPath() ) return fullNameB(mfi); joachim99@80: else return m_dirDestInternal.absoluteFilePath() + "/" + mfi.m_subPath; joachim99@77: } joachim99@8: joachim99@8: bool copyFLD( const QString& srcName, const QString& destName ); joachim99@8: bool deleteFLD( const QString& name, bool bCreateBackup ); joachim99@8: bool makeDir( const QString& name, bool bQuiet=false ); joachim99@8: bool renameFLD( const QString& srcName, const QString& destName ); joachim99@8: bool mergeFLD( const QString& nameA,const QString& nameB,const QString& nameC, joachim99@8: const QString& nameDest, bool& bSingleFileMerge ); joachim99@8: joachim99@8: FileAccess m_dirA; joachim99@8: FileAccess m_dirB; joachim99@8: FileAccess m_dirC; joachim99@8: FileAccess m_dirDest; joachim99@8: FileAccess m_dirDestInternal; joachim99@8: joachim99@69: QString m_dirMergeStateFilename; joachim99@69: joachim99@8: std::map m_fileMergeMap; joachim99@8: joachim99@8: bool m_bFollowDirLinks; joachim99@8: bool m_bFollowFileLinks; joachim99@8: bool m_bSimulatedMergeStarted; joachim99@8: bool m_bRealMergeStarted; joachim99@8: bool m_bError; joachim99@8: bool m_bSyncMode; joachim99@8: bool m_bDirectoryMerge; // if true, then merge is the default operation, otherwise it's diff. joachim99@69: bool m_bCaseSensitive; joachim99@66: joachim99@66: bool m_bScanning; // true while in init() joachim99@8: joachim99@8: OptionDialog* m_pOptions; joachim99@8: KIconLoader* m_pIconLoader; joachim99@8: DirectoryMergeInfo* m_pDirectoryMergeInfo; joachim99@8: StatusInfo* m_pStatusInfo; joachim99@51: joachim99@51: typedef std::list MergeItemList; joachim99@51: MergeItemList m_mergeItemList; joachim99@51: MergeItemList::iterator m_currentItemForOperation; joachim99@51: joachim99@69: DirMergeItem* m_pSelection1Item; joachim99@69: int m_selection1Column; joachim99@69: DirMergeItem* m_pSelection2Item; joachim99@69: int m_selection2Column; joachim99@69: DirMergeItem* m_pSelection3Item; joachim99@69: int m_selection3Column; joachim99@69: void selectItemAndColumn(DirMergeItem* pDMI, int c, bool bContextMenu); joachim99@69: friend class DirMergeItem; joachim99@51: joachim99@69: KAction* m_pDirStartOperation; joachim99@69: KAction* m_pDirRunOperationForCurrentItem; joachim99@69: KAction* m_pDirCompareCurrent; joachim99@69: KAction* m_pDirMergeCurrent; joachim99@69: KAction* m_pDirRescan; joachim99@69: KAction* m_pDirChooseAEverywhere; joachim99@69: KAction* m_pDirChooseBEverywhere; joachim99@69: KAction* m_pDirChooseCEverywhere; joachim99@69: KAction* m_pDirAutoChoiceEverywhere; joachim99@69: KAction* m_pDirDoNothingEverywhere; joachim99@69: KAction* m_pDirFoldAll; joachim99@69: KAction* m_pDirUnfoldAll; joachim99@51: joachim99@69: KToggleAction* m_pDirShowIdenticalFiles; joachim99@69: KToggleAction* m_pDirShowDifferentFiles; joachim99@69: KToggleAction* m_pDirShowFilesOnlyInA; joachim99@69: KToggleAction* m_pDirShowFilesOnlyInB; joachim99@69: KToggleAction* m_pDirShowFilesOnlyInC; joachim99@69: joachim99@69: KToggleAction* m_pDirSynchronizeDirectories; joachim99@69: KToggleAction* m_pDirChooseNewerFiles; joachim99@69: joachim99@69: KAction* m_pDirCompareExplicit; joachim99@69: KAction* m_pDirMergeExplicit; joachim99@69: joachim99@69: KAction* m_pDirCurrentDoNothing; joachim99@69: KAction* m_pDirCurrentChooseA; joachim99@69: KAction* m_pDirCurrentChooseB; joachim99@69: KAction* m_pDirCurrentChooseC; joachim99@69: KAction* m_pDirCurrentMerge; joachim99@69: KAction* m_pDirCurrentDelete; joachim99@69: joachim99@69: KAction* m_pDirCurrentSyncDoNothing; joachim99@69: KAction* m_pDirCurrentSyncCopyAToB; joachim99@69: KAction* m_pDirCurrentSyncCopyBToA; joachim99@69: KAction* m_pDirCurrentSyncDeleteA; joachim99@69: KAction* m_pDirCurrentSyncDeleteB; joachim99@69: KAction* m_pDirCurrentSyncDeleteAAndB; joachim99@69: KAction* m_pDirCurrentSyncMergeToA; joachim99@69: KAction* m_pDirCurrentSyncMergeToB; joachim99@69: KAction* m_pDirCurrentSyncMergeToAAndB; joachim99@69: joachim99@69: KAction* m_pDirSaveMergeState; joachim99@69: KAction* m_pDirLoadMergeState; joachim99@8: signals: joachim99@66: void startDiffMerge(QString fn1,QString fn2, QString fn3, QString ofn, QString,QString,QString,TotalDiffStatus*); joachim99@8: void checkIfCanContinue( bool* pbContinue ); joachim99@8: void updateAvailabilities(); joachim99@66: void statusBarMessage( const QString& msg ); joachim99@8: protected slots: joachim99@75: void onDoubleClick( QTreeWidgetItem* lvi ); joachim99@75: void onCurrentChanged(QTreeWidgetItem*); joachim99@75: void onExpanded(); joachim99@8: }; joachim99@8: joachim99@75: class DirectoryMergeInfo : public QFrame joachim99@8: { joachim99@53: Q_OBJECT joachim99@8: public: joachim99@8: DirectoryMergeInfo( QWidget* pParent ); joachim99@8: void setInfo( joachim99@8: const FileAccess& APath, joachim99@8: const FileAccess& BPath, joachim99@8: const FileAccess& CPath, joachim99@8: const FileAccess& DestPath, joachim99@8: MergeFileInfos& mfi ); joachim99@75: QTreeWidget* getInfoList() {return m_pInfoList;} joachim99@66: virtual bool eventFilter( QObject* o, QEvent* e ); joachim99@66: signals: joachim99@66: void gotFocus(); joachim99@8: private: joachim99@8: QLabel* m_pInfoA; joachim99@8: QLabel* m_pInfoB; joachim99@8: QLabel* m_pInfoC; joachim99@8: QLabel* m_pInfoDest; joachim99@8: joachim99@8: QLabel* m_pA; joachim99@8: QLabel* m_pB; joachim99@8: QLabel* m_pC; joachim99@8: QLabel* m_pDest; joachim99@8: joachim99@75: QTreeWidget* m_pInfoList; joachim99@8: }; joachim99@8: joachim99@8: joachim99@8: #endif