File indexing completed on 2024-04-28 17:01:01
0001 // clang-format off 0002 /* 0003 * KDiff3 - Text Diff And Merge Tool 0004 * 0005 * SPDX-FileCopyrightText: 2002-2011 Joachim Eibl, joachim.eibl at gmx.de 0006 * SPDX-FileCopyrightText: 2018-2020 Michael Reeves reeves.87@gmail.com 0007 * SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 // clang-format on 0010 0011 #ifndef KDIFF3_H 0012 #define KDIFF3_H 0013 0014 #include "diff.h" 0015 #include "defmac.h" 0016 #include "combiners.h" 0017 #include "SourceData.h" 0018 #include "TypeUtils.h" 0019 0020 #include <boost/signals2.hpp> 0021 0022 #include <memory> 0023 0024 // include files for Qt 0025 #include <QAction> 0026 #include <QApplication> 0027 #include <QEventLoop> 0028 #include <QPointer> 0029 #include <QScrollBar> 0030 #include <QSharedPointer> 0031 #include <QSplitter> 0032 0033 // include files for KDE 0034 #include <KConfigGroup> 0035 #include <KMainWindow> 0036 #include <KSharedConfig> 0037 #include <KToggleAction> 0038 #include <QShortcut> 0039 0040 // forward declaration of the KDiff3 classes 0041 class Options; 0042 class OptionDialog; 0043 0044 class Overview; 0045 enum class e_OverviewMode; 0046 class FindDialog; 0047 //class ManualDiffHelpDialog; 0048 class DiffTextWindow; 0049 class DiffTextWindowFrame; 0050 class MergeResultWindow; 0051 class WindowTitleWidget; 0052 0053 class QStatusBar; 0054 class QMenu; 0055 0056 class KToolBar; 0057 class KActionCollection; 0058 0059 class KDiff3Shell; 0060 class DirectoryMergeWindow; 0061 class DirectoryMergeInfo; 0062 0063 class ReversibleScrollBar : public QScrollBar 0064 { 0065 Q_OBJECT 0066 bool* m_pbRightToLeftLanguage; 0067 qint32 m_realVal; 0068 0069 public: 0070 ReversibleScrollBar(Qt::Orientation o, bool* pbRightToLeftLanguage) 0071 : QScrollBar(o) 0072 { 0073 m_pbRightToLeftLanguage = pbRightToLeftLanguage; 0074 m_realVal = 0; 0075 chk_connect_a(this, &ReversibleScrollBar::valueChanged, this, &ReversibleScrollBar::slotValueChanged); 0076 } 0077 void setAgain() { setValue(m_realVal); } 0078 0079 void setValue(qint32 i) 0080 { 0081 if(m_pbRightToLeftLanguage != nullptr && *m_pbRightToLeftLanguage) 0082 QScrollBar::setValue(maximum() - (i - minimum())); 0083 else 0084 QScrollBar::setValue(i); 0085 } 0086 0087 [[nodiscard]] qint32 value() const 0088 { 0089 return m_realVal; 0090 } 0091 public Q_SLOTS: 0092 void slotValueChanged(qint32 i) 0093 { 0094 m_realVal = i; 0095 if(m_pbRightToLeftLanguage != nullptr && *m_pbRightToLeftLanguage) 0096 m_realVal = maximum() - (i - minimum()); 0097 Q_EMIT valueChanged2(m_realVal); 0098 } 0099 0100 Q_SIGNALS: 0101 void valueChanged2(qint32); 0102 }; 0103 0104 /* 0105 InitFlag 0106 */ 0107 0108 enum class InitFlag 0109 { 0110 loadFiles = 1, 0111 useCurrentEncoding = 2, 0112 autoSolve = 4, 0113 initGUI = 8, 0114 defaultFlags = loadFiles | autoSolve | initGUI 0115 }; 0116 0117 Q_DECLARE_FLAGS(InitFlags, InitFlag); 0118 Q_DECLARE_OPERATORS_FOR_FLAGS(InitFlags); 0119 0120 class KDiff3App: public QMainWindow 0121 { 0122 Q_OBJECT 0123 0124 public: 0125 /** constructor of KDiff3App, calls all init functions to create the application. 0126 */ 0127 KDiff3App(QWidget* parent, const QString& name, KDiff3Shell* pKDiff3Shell); 0128 ~KDiff3App() override; 0129 0130 /** initializes the KActions of the application */ 0131 void initActions(KActionCollection*); 0132 0133 bool restoreWindow(const KSharedConfigPtr config); 0134 void saveWindow(const KSharedConfigPtr config); 0135 0136 /** save general Options like all bar positions and status as well as the geometry 0137 and the recent file list to the configuration file */ 0138 void saveOptions(KSharedConfigPtr); 0139 0140 /** read general Options again and initialize all variables like the recent file list */ 0141 void readOptions(KSharedConfigPtr); 0142 0143 // Finish initialisation 0144 void completeInit(const QString& fn1 = QString(), const QString& fn2 = QString(), const QString& fn3 = QString()); 0145 //Restore goementry and showMainWindow 0146 void showMainWindow(); 0147 0148 /** queryClose is called by KMainWindow on each closeEvent of a window. Against the 0149 * default implementation (only returns true), this calles saveModified() on the document object to ask if the document shall 0150 * be saved if Modified; on cancel the closeEvent is rejected. 0151 * @see KMainWindow#queryClose 0152 * @see KMainWindow#closeEvent 0153 */ 0154 virtual bool queryClose(); 0155 [[nodiscard]] virtual bool isFileSaved() const; 0156 [[nodiscard]] virtual bool isDirComparison() const; 0157 0158 static bool isTripleDiff() { return m_bTripleDiff; } 0159 0160 [[nodiscard]] KActionCollection* actionCollection() const; 0161 0162 static boost::signals2::signal<QString (), FirstNonEmpty<QString>> getSelection; 0163 static boost::signals2::signal<bool(), or_> allowCopy; 0164 static boost::signals2::signal<bool(), or_> allowCut; 0165 0166 bool canContinue(); 0167 0168 Q_SIGNALS: 0169 void createNewInstance(const QString& fn1, const QString& fn2, const QString& fn3); 0170 0171 void sigRecalcWordWrap(); 0172 0173 void finishDrop(); 0174 0175 void showWhiteSpaceToggled(); 0176 void showLineNumbersToggled(); 0177 void doRefresh(); 0178 0179 void autoSolve(); 0180 void unsolve(); 0181 void mergeHistory(); 0182 void regExpAutoMerge(); 0183 0184 void goCurrent(); 0185 void goTop(); 0186 void goBottom(); 0187 void goPrevUnsolvedConflict(); 0188 0189 void goNextUnsolvedConflict(); 0190 void goPrevConflict(); 0191 0192 void goNextConflict(); 0193 void goPrevDelta(); 0194 void goNextDelta(); 0195 0196 void cut(); 0197 0198 void copy(); 0199 0200 void selectAll(); 0201 0202 void changeOverViewMode(e_OverviewMode); 0203 public Q_SLOTS: 0204 0205 /** open a file and load it into the document*/ 0206 void slotFileOpen(); 0207 void slotFileOpen2(QStringList &errors, const QString& fn1, const QString& fn2, const QString& fn3, const QString& ofn, 0208 const QString& an1, const QString& an2, const QString& an3, TotalDiffStatus* pTotalDiffStatus); 0209 0210 void slotFileNameChanged(const QString& fileName, e_SrcSelector winIdx); 0211 0212 /** save a document */ 0213 void slotFileSave(); 0214 /** save a document by a new filename*/ 0215 void slotFileSaveAs(); 0216 0217 void slotFilePrint(); 0218 0219 /** closes all open windows by calling close() on each memberList item until the list is empty, then quits the application. 0220 * If queryClose() returns false because the user canceled the saveModified() dialog, the closing breaks. 0221 */ 0222 void slotFileQuit(); 0223 0224 void slotEditUndo(){}; 0225 /** put the marked text/object into the clipboard and remove 0226 * it from the document 0227 */ 0228 void slotEditCut(); 0229 /** put the marked text/object into the clipboard 0230 */ 0231 void slotEditCopy(); 0232 /** paste the clipboard into the document 0233 */ 0234 void slotEditPaste(); 0235 /** toggles the statusbar 0236 */ 0237 void slotViewStatusBar(); 0238 /** changes the statusbar contents for the standard label permanently, used to indicate current actions. 0239 * @param text the text that is displayed in the statusbar 0240 */ 0241 void slotStatusMsg(const QString& text); 0242 0243 void resizeDiffTextWindowHeight(qint32 newHeight); 0244 void slotRecalcWordWrap(); 0245 void postRecalcWordWrap(); 0246 void slotFinishRecalcWordWrap(qint32 visibleTextWidth); 0247 0248 void showPopupMenu(const QPoint& point); 0249 0250 void scrollDiffTextWindow(qint32 deltaX, qint32 deltaY); 0251 void scrollMergeResultWindow(qint32 deltaX, qint32 deltaY); 0252 void sourceMask(qint32 srcMask, qint32 enabledMask); 0253 0254 void slotDirShowBoth(); 0255 void slotDirViewToggle(); 0256 0257 void slotUpdateAvailabilities(); 0258 void slotEditSelectAll(); 0259 void slotEditFind(); 0260 void slotEditFindNext(); 0261 void slotGoCurrent(); 0262 void slotGoTop(); 0263 void slotGoBottom(); 0264 void slotGoPrevUnsolvedConflict(); 0265 void slotGoNextUnsolvedConflict(); 0266 void slotGoPrevConflict(); 0267 void slotGoNextConflict(); 0268 void slotGoPrevDelta(); 0269 void slotGoNextDelta(); 0270 void slotGoToLine(); 0271 void slotChooseA(); 0272 void slotChooseB(); 0273 void slotChooseC(); 0274 void slotAutoSolve(); 0275 void slotUnsolve(); 0276 void slotMergeHistory(); 0277 void slotRegExpAutoMerge(); 0278 void slotConfigure(); 0279 void slotConfigureKeys(); 0280 void slotRefresh(); 0281 void slotSelectionEnd(); 0282 void slotSelectionStart(); 0283 void slotClipboardChanged(); 0284 void slotOutputModified(bool); 0285 void slotFinishMainInit(); 0286 void slotMergeCurrentFile(); 0287 void slotReload(); 0288 void slotShowWhiteSpaceToggled(); 0289 void slotShowLineNumbersToggled(); 0290 void slotAutoAdvanceToggled(); 0291 void slotWordWrapToggled(); 0292 void slotShowWindowAToggled(); 0293 void slotShowWindowBToggled(); 0294 void slotShowWindowCToggled(); 0295 void slotWinFocusNext(); 0296 void slotWinFocusPrev(); 0297 void slotWinToggleSplitterOrientation(); 0298 void slotOverviewNormal(); 0299 void slotOverviewAB(); 0300 void slotOverviewAC(); 0301 void slotOverviewBC(); 0302 void slotSplitDiff(); 0303 void slotJoinDiffs(); 0304 void slotAddManualDiffHelp(); 0305 void slotClearManualDiffHelpList(); 0306 void slotNoRelevantChangesDetected(); 0307 void slotEncodingChanged(const QByteArray&); 0308 0309 void slotFinishDrop(); 0310 0311 void setHScrollBarRange(); 0312 0313 void slotFocusChanged(QWidget *old, QWidget *now); 0314 Q_SIGNALS: 0315 void updateAvailabilities(); 0316 0317 protected: 0318 void setLockPainting(bool bLock); 0319 void createCaption(); 0320 void initDirectoryMergeActions(); 0321 /** sets up the statusbar for the main window by initialzing a statuslabel. */ 0322 void initStatusBar(); 0323 0324 /** creates the centerwidget of the KMainWindow instance and sets it as the view */ 0325 void initView(); 0326 0327 private: 0328 void mainInit(TotalDiffStatus* pTotalDiffStatus, const InitFlags inFlags = InitFlag::defaultFlags); 0329 void mainWindowEnable(bool bEnable); 0330 void wheelEvent(QWheelEvent* pWheelEvent) override; 0331 void keyPressEvent(QKeyEvent* event) override; 0332 void resizeEvent(QResizeEvent*) override; 0333 0334 void doFileCompare(); 0335 bool doDirectoryCompare(const bool bCreateNewInstance); 0336 void improveFilenames(); 0337 0338 void choose(e_SrcSelector choice); 0339 0340 [[nodiscard]] QStatusBar* statusBar() const; 0341 [[nodiscard]] KToolBar* toolBar(const QLatin1String &toolBarId) const; 0342 void recalcWordWrap(qint32 visibleTextWidthForPrinting = -1); 0343 0344 bool canCut(); 0345 bool canCopy(); 0346 0347 bool mInitCalled = false; 0348 0349 // QAction pointers to enable/disable actions 0350 QPointer<QAction> fileOpen; 0351 QPointer<QAction> fileSave; 0352 QPointer<QAction> fileSaveAs; 0353 QPointer<QAction> filePrint; 0354 QPointer<QAction> fileQuit; 0355 QPointer<QAction> fileReload; 0356 QPointer<QAction> editUndo; 0357 QPointer<QAction> editCut; 0358 QPointer<QAction> editCopy; 0359 QPointer<QAction> editPaste; 0360 QPointer<QAction> editSelectAll; 0361 KToggleAction* viewStatusBar = nullptr; 0362 0363 QPointer<QShortcut> mEscapeAction; 0364 //////////////////////////////////////////////////////////////////////// 0365 // Special KDiff3 specific stuff starts here 0366 QPointer<QAction> editFind; 0367 QPointer<QAction> editFindNext; 0368 0369 QPointer<QAction> mGoCurrent; 0370 QPointer<QAction> mGoTop; 0371 QPointer<QAction> mGoBottom; 0372 QPointer<QAction> mGoPrevUnsolvedConflict; 0373 QPointer<QAction> mGoNextUnsolvedConflict; 0374 QPointer<QAction> mGoPrevConflict; 0375 QPointer<QAction> mGoNextConflict; 0376 QPointer<QAction> mGoPrevDelta; 0377 QPointer<QAction> mGoNextDelta; 0378 QPointer<QAction> mGotoLine; 0379 KToggleAction* chooseA = nullptr; 0380 KToggleAction* chooseB = nullptr; 0381 KToggleAction* chooseC = nullptr; 0382 KToggleAction* autoAdvance = nullptr; 0383 KToggleAction* wordWrap = nullptr; 0384 QPointer<QAction> splitDiff; 0385 QPointer<QAction> joinDiffs; 0386 QPointer<QAction> addManualDiffHelp; 0387 QPointer<QAction> clearManualDiffHelpList; 0388 KToggleAction* showWhiteSpaceCharacters = nullptr; 0389 KToggleAction* showWhiteSpace = nullptr; 0390 KToggleAction* showLineNumbers = nullptr; 0391 QPointer<QAction> mAutoSolve; 0392 QPointer<QAction> mUnsolve; 0393 QPointer<QAction> mMergeHistory; 0394 QPointer<QAction> mergeRegExp; 0395 KToggleAction* showWindowA = nullptr; 0396 KToggleAction* showWindowB = nullptr; 0397 KToggleAction* showWindowC = nullptr; 0398 QPointer<QAction> winFocusNext; 0399 QPointer<QAction> winFocusPrev; 0400 QPointer<QAction> winToggleSplitOrientation; 0401 KToggleAction* dirShowBoth = nullptr; 0402 QPointer<QAction> dirViewToggle; 0403 KToggleAction* overviewModeNormal = nullptr; 0404 KToggleAction* overviewModeAB = nullptr; 0405 KToggleAction* overviewModeAC = nullptr; 0406 KToggleAction* overviewModeBC = nullptr; 0407 0408 QMenu* m_pMergeEditorPopupMenu = nullptr; 0409 0410 QWidget* m_pMainWidget = nullptr; // Contains vertical splitter and horiz scrollbar 0411 QWidget* m_pCentralWidget = nullptr; 0412 QWidget* m_pMergeWindowFrame = nullptr; 0413 ReversibleScrollBar* m_pHScrollBar = nullptr; 0414 0415 QPointer<DiffTextWindow> m_pDiffTextWindow1; 0416 QPointer<DiffTextWindow> m_pDiffTextWindow2; 0417 QPointer<DiffTextWindow> m_pDiffTextWindow3; 0418 DiffTextWindowFrame* m_pDiffTextWindowFrame1 = nullptr; 0419 DiffTextWindowFrame* m_pDiffTextWindowFrame2 = nullptr; 0420 DiffTextWindowFrame* m_pDiffTextWindowFrame3 = nullptr; 0421 QSplitter* m_pDiffWindowSplitter = nullptr; 0422 0423 MergeResultWindow* m_pMergeResultWindow = nullptr; 0424 WindowTitleWidget* m_pMergeResultWindowTitle = nullptr; 0425 static bool m_bTripleDiff; 0426 0427 QDockWidget* m_pDirectoryMergeDock = nullptr; 0428 DirectoryMergeWindow* m_pDirectoryMergeWindow = nullptr; 0429 QDockWidget* m_pDirectoryMergeInfoDock = nullptr; 0430 DirectoryMergeInfo* m_pDirectoryMergeInfo = nullptr; 0431 bool m_bDirCompare = false; 0432 0433 Overview* m_pOverview = nullptr; 0434 0435 QWidget* m_pCornerWidget = nullptr; 0436 0437 TotalDiffStatus *m_totalDiffStatus = new TotalDiffStatus(); 0438 0439 QSharedPointer<SourceData> m_sd1 = QSharedPointer<SourceData>::create(); 0440 QSharedPointer<SourceData> m_sd2 = QSharedPointer<SourceData>::create(); 0441 QSharedPointer<SourceData> m_sd3 = QSharedPointer<SourceData>::create(); 0442 0443 QString m_outputFilename; 0444 bool m_bDefaultFilename = true; 0445 0446 DiffList m_diffList12; 0447 DiffList m_diffList23; 0448 DiffList m_diffList13; 0449 Diff3LineList m_diff3LineList; 0450 Diff3LineVector mDiff3LineVector; 0451 ManualDiffHelpList m_manualDiffHelpList; 0452 0453 LineType m_neededLines = 0; 0454 qint32 m_DTWHeight = 0; 0455 bool m_bOutputModified = false; 0456 bool m_bFileSaved = false; 0457 bool m_bTimerBlock = false; // Synchronization 0458 0459 OptionDialog* m_pOptionDialog = nullptr; 0460 FindDialog* m_pFindDialog = nullptr; 0461 0462 bool m_bFinishMainInit = false; 0463 bool m_bLoadFiles = false; 0464 0465 KDiff3Shell* m_pKDiff3Shell = nullptr; 0466 bool m_bAutoFlag = false; 0467 bool m_bAutoMode = false; 0468 bool m_bRecalcWordWrapPosted = false; 0469 0470 qint32 m_firstD3LIdx = 0; // only needed during recalcWordWrap 0471 QPointer<QEventLoop> m_pEventLoopForPrinting; 0472 0473 bool mRunnablesStarted = false; 0474 0475 QStringList mErrors; 0476 /* 0477 This list exists solely to auto disconnect boost signals. 0478 */ 0479 std::list<boost::signals2::scoped_connection> connections; 0480 }; 0481 0482 extern std::unique_ptr<Options> gOptions; 0483 0484 #endif // KDIFF3_H