joachim99@8: /*************************************************************************** joachim99@8: directorymergewindow.h joachim99@8: ------------------- joachim99@8: begin : Sat Oct 19 2002 joachim99@58: copyright : (C) 2002-2004 by Joachim Eibl joachim99@8: email : joachim.eibl@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@8: #include joachim99@8: #include joachim99@8: #include joachim99@8: #include joachim99@8: #include joachim99@8: #include joachim99@8: #include "common.h" joachim99@8: #include "fileaccess.h" joachim99@8: joachim99@8: class OptionDialog; joachim99@8: class KIconLoader; joachim99@8: class StatusMessageBox; 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@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@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@8: void setMergeOperation( e_MergeOperation eMOp ); 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@8: }; joachim99@8: joachim99@8: class DirMergeItem : public QListViewItem joachim99@8: { joachim99@8: public: joachim99@8: DirMergeItem( QListView* pParent, const QString&, MergeFileInfos*); joachim99@8: DirMergeItem( DirMergeItem* pParent, const QString&, MergeFileInfos*); joachim99@8: ~DirMergeItem(); joachim99@8: MergeFileInfos* m_pMFI; joachim99@8: #if QT_VERSION!=230 joachim99@8: virtual int compare(QListViewItem *i, int col, bool ascending) const joachim99@8: { joachim99@8: DirMergeItem* pDMI = static_cast(i); joachim99@8: bool bDir1 = m_pMFI->m_bDirA || m_pMFI->m_bDirB || m_pMFI->m_bDirC; joachim99@8: bool bDir2 = pDMI->m_pMFI->m_bDirA || pDMI->m_pMFI->m_bDirB || pDMI->m_pMFI->m_bDirC; joachim99@8: if ( m_pMFI==0 || pDMI->m_pMFI==0 || bDir1 == bDir2 ) joachim99@8: return QListViewItem::compare( i, col, ascending ); joachim99@8: else joachim99@8: return bDir1 ? -1 : 1; joachim99@8: } joachim99@8: #endif joachim99@8: }; joachim99@8: joachim99@8: class DirectoryMergeWindow : public QListView 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@8: bool bDirectoryMerge joachim99@8: ); joachim99@8: bool isFileSelected(); joachim99@8: void allowResizeEvents(bool bAllowResizeEvents); joachim99@8: bool isDirectoryMergeInProgress() { return m_bRealMergeStarted; } joachim99@8: int totalColumnWidth(); joachim99@8: bool isSyncMode() { return m_bSyncMode; } 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@51: joachim99@51: virtual void keyPressEvent( QKeyEvent* e ); joachim99@53: virtual void focusInEvent( QFocusEvent* e ); joachim99@53: virtual void focusOutEvent( QFocusEvent* e ); 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@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@8: protected: joachim99@51: void mergeContinue( bool bStart, bool bVerbose ); joachim99@8: void resizeEvent(QResizeEvent* e); joachim99@8: bool m_bAllowResizeEvents; joachim99@8: joachim99@8: void prepareListView(); 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@51: void prepareMergeStart( QListViewItem* pBegin, QListViewItem* 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@41: { return m_dirA.absFilePath() + "/" + mfi.m_subPath; } joachim99@8: QString fullNameB( const MergeFileInfos& mfi ) joachim99@41: { return m_dirB.absFilePath() + "/" + mfi.m_subPath; } joachim99@8: QString fullNameC( const MergeFileInfos& mfi ) joachim99@41: { return m_dirC.absFilePath() + "/" + mfi.m_subPath; } joachim99@8: QString fullNameDest( const MergeFileInfos& mfi ) joachim99@8: { return m_dirDestInternal.absFilePath() + "/" + mfi.m_subPath; } 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@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@8: joachim99@8: OptionDialog* m_pOptions; joachim99@8: KIconLoader* m_pIconLoader; joachim99@8: StatusMessageBox* m_pStatusMessageBox; 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@51: KAction* dirStartOperation; joachim99@51: KAction* dirRunOperationForCurrentItem; joachim99@51: KAction* dirCompareCurrent; joachim99@51: KAction* dirMergeCurrent; joachim99@51: KAction* dirRescan; joachim99@51: KAction* dirChooseAEverywhere; joachim99@51: KAction* dirChooseBEverywhere; joachim99@51: KAction* dirChooseCEverywhere; joachim99@51: KAction* dirAutoChoiceEverywhere; joachim99@51: KAction* dirDoNothingEverywhere; joachim99@51: KAction* dirFoldAll; joachim99@51: KAction* dirUnfoldAll; joachim99@51: joachim99@51: KAction* dirCurrentDoNothing; joachim99@51: KAction* dirCurrentChooseA; joachim99@51: KAction* dirCurrentChooseB; joachim99@51: KAction* dirCurrentChooseC; joachim99@51: KAction* dirCurrentMerge; joachim99@51: KAction* dirCurrentDelete; joachim99@51: joachim99@51: KAction* dirCurrentSyncDoNothing; joachim99@51: KAction* dirCurrentSyncCopyAToB; joachim99@51: KAction* dirCurrentSyncCopyBToA; joachim99@51: KAction* dirCurrentSyncDeleteA; joachim99@51: KAction* dirCurrentSyncDeleteB; joachim99@51: KAction* dirCurrentSyncDeleteAAndB; joachim99@51: KAction* dirCurrentSyncMergeToA; joachim99@51: KAction* dirCurrentSyncMergeToB; joachim99@51: KAction* dirCurrentSyncMergeToAAndB; joachim99@8: signals: joachim99@8: void startDiffMerge(QString fn1,QString fn2, QString fn3, QString ofn, QString,QString,QString); joachim99@8: void checkIfCanContinue( bool* pbContinue ); joachim99@8: void updateAvailabilities(); joachim99@8: protected slots: joachim99@8: void onDoubleClick( QListViewItem* lvi ); joachim99@8: void onClick( QListViewItem* lvi, const QPoint&, int c ); joachim99@8: void onSelectionChanged(QListViewItem* lvi); joachim99@8: }; joachim99@8: joachim99@8: 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@8: QListView* getInfoList() {return m_pInfoList;} 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@8: QListView* m_pInfoList; joachim99@8: }; joachim99@8: joachim99@8: joachim99@8: #endif