File indexing completed on 2024-11-10 08:10:47

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 DIFFTEXTWINDOW_H
0012 #define DIFFTEXTWINDOW_H
0013 
0014 #include "diff.h"
0015 #include "SourceData.h"
0016 
0017 #include "LineRef.h"
0018 #include "TypeUtils.h"
0019 
0020 #include <QLabel>
0021 #include <QMouseEvent>
0022 #include <QPaintEvent>
0023 #include <QPointer>
0024 #include <QSharedPointer>
0025 #include <QString>
0026 #include <QWheelEvent>
0027 
0028 #include <boost/signals2.hpp>
0029 #include <list>
0030 #include <memory>
0031 #include <vector>
0032 
0033 class QMenu;
0034 class QPushButton;
0035 class QScrollBar;
0036 class QStatusBar;
0037 class RecalcWordWrapThread;
0038 class Options;
0039 class DiffTextWindowData;
0040 class DiffTextWindowFrame;
0041 class EncodingLabel;
0042 class RLPainter;
0043 class SourceData;
0044 class FileNameLineEdit;
0045 
0046 class KDiff3App;
0047 
0048 class DiffTextWindow: public QWidget
0049 {
0050     Q_OBJECT
0051   public:
0052     //Using this as a scoped global
0053     static QPointer<QScrollBar> mVScrollBar;
0054     static QAtomicInteger<size_t> maxThreads();
0055 
0056     DiffTextWindow(DiffTextWindowFrame* pParent, e_SrcSelector winIdx, KDiff3App& app);
0057     ~DiffTextWindow() override;
0058     void init(
0059         const QString& fileName,
0060         const char* pTextCodec,
0061         e_LineEndStyle eLineEndStyle,
0062         const std::shared_ptr<LineDataVector>& pLineData,
0063         LineType size,
0064         const Diff3LineVector* pDiff3LineVector,
0065         const ManualDiffHelpList* pManualDiffHelpList);
0066 
0067     void setupConnections(const KDiff3App* app);
0068 
0069     void reset();
0070     void convertToLinePos(qint32 x, qint32 y, LineRef& line, qint32& pos);
0071 
0072     [[nodiscard]] QString getSelection() const;
0073     [[nodiscard]] LineRef getFirstLine() const;
0074     LineRef calcTopLineInFile(const LineRef firstLine) const;
0075 
0076     [[nodiscard]] qint32 getMaxTextWidth() const;
0077     [[nodiscard]] LineType getNofLines() const;
0078     [[nodiscard]] LineType getNofVisibleLines() const;
0079     [[nodiscard]] qint32 getVisibleTextAreaWidth() const;
0080 
0081     LineType convertLineToDiff3LineIdx(const LineRef line) const;
0082     LineRef convertDiff3LineIdxToLine(const LineType d3lIdx) const;
0083 
0084     void convertD3LCoordsToLineCoords(LineType d3LIdx, QtSizeType d3LPos, LineRef& line, QtSizeType& pos) const;
0085     void convertLineCoordsToD3LCoords(LineRef line, QtSizeType pos, LineType& d3LIdx, QtSizeType& d3LPos) const;
0086 
0087     void convertSelectionToD3LCoords() const;
0088 
0089     bool findString(const QString& s, LineRef& d3vLine, QtSizeType& posInLine, bool bDirDown, bool bCaseSensitive);
0090     void setSelection(LineRef firstLine, QtSizeType startPos, LineRef lastLine, QtSizeType endPos, LineRef& l, QtSizeType& p);
0091     void getSelectionRange(LineRef* firstLine, LineRef* lastLine, e_CoordType coordType) const;
0092 
0093     void setPaintingAllowed(bool bAllowPainting);
0094     void recalcWordWrap(bool bWordWrap, QtSizeType wrapLineVectorSize, qint32 visibleTextWidth);
0095     void recalcWordWrapHelper(QtSizeType wrapLineVectorSize, qint32 visibleTextWidth, size_t cacheListIdx);
0096 
0097     void printWindow(RLPainter& painter, const QRect& view, const QString& headerText, qint32 line, const LineType linesPerPage, const QColor& fgColor);
0098     void print(RLPainter& painter, const QRect& r, qint32 firstLine, const LineType nofLinesPerPage);
0099 
0100     static bool startRunnables();
0101 
0102     [[nodiscard]] bool isThreeWay() const;
0103     [[nodiscard]] const QString& getFileName() const;
0104 
0105     [[nodiscard]] e_SrcSelector getWindowIndex() const;
0106 
0107     [[nodiscard]] const QString getEncodingDisplayString() const;
0108     [[nodiscard]] e_LineEndStyle getLineEndStyle() const;
0109     [[nodiscard]] const Diff3LineVector* getDiff3LineVector() const;
0110 
0111     [[nodiscard]] qint32 getLineNumberWidth() const;
0112 
0113     void setSourceData(const QSharedPointer<SourceData>& inData);
0114 
0115     void scrollVertically(qint32 deltaY);
0116   Q_SIGNALS:
0117     void statusBarMessage(const QString& message);
0118     void resizeHeightChangedSignal(qint32 nofVisibleLines);
0119     void resizeWidthChangedSignal(qint32 nofVisibleColumns);
0120     void scrollDiffTextWindow(qint32 deltaX, qint32 deltaY);
0121     void newSelection();
0122     void selectionEnd();
0123     void setFastSelectorLine(LineType line);
0124     void gotFocus();
0125     void lineClicked(e_SrcSelector winIdx, LineRef line);
0126 
0127     void finishRecalcWordWrap(qint32 visibleTextWidthForPrinting);
0128 
0129     void finishDrop();
0130 
0131     void firstLineChanged(const LineRef firstLine);
0132   public Q_SLOTS:
0133     void setFirstLine(LineRef line);
0134     void setHorizScrollOffset(qint32 horizScrollOffset);
0135     void resetSelection();
0136     void setFastSelectorRange(qint32 line1, qint32 nofLines);
0137     void slotRefresh();
0138 
0139     void slotSelectAll();
0140 
0141     void slotCopy();
0142 
0143   protected:
0144     void mousePressEvent(QMouseEvent*) override;
0145     void mouseReleaseEvent(QMouseEvent*) override;
0146     void mouseMoveEvent(QMouseEvent*) override;
0147     void mouseDoubleClickEvent(QMouseEvent* e) override;
0148 
0149     void wheelEvent(QWheelEvent*) override;
0150 
0151     void paintEvent(QPaintEvent*) override;
0152     void dragEnterEvent(QDragEnterEvent* dragEnterEvent) override;
0153 
0154     void dropEvent(QDropEvent* dropEvent) override;
0155     void focusInEvent(QFocusEvent* e) override;
0156 
0157     void resizeEvent(QResizeEvent*) override;
0158     void timerEvent(QTimerEvent*) override;
0159 
0160   private:
0161     static std::vector<RecalcWordWrapThread*> s_runnables;
0162     static constexpr qint32 s_linesPerRunnable = 2000;
0163 
0164     /*
0165       This list exists solely to auto disconnect boost signals.
0166     */
0167     std::list<boost::signals2::scoped_connection> connections;
0168 
0169     KDiff3App& m_app;
0170     e_SrcSelector mWinIdx = e_SrcSelector::None;
0171     std::unique_ptr<DiffTextWindowData> d;
0172 
0173     void showStatusLine(const LineRef lineFromPos);
0174 
0175     bool canCopy() { return hasFocus() && !getSelection().isEmpty(); }
0176 };
0177 
0178 class DiffTextWindowFrame: public QWidget
0179 {
0180     Q_OBJECT
0181   public:
0182     DiffTextWindowFrame(QWidget* pParent, e_SrcSelector winIdx, const QSharedPointer<SourceData>& psd, KDiff3App& app);
0183     ~DiffTextWindowFrame() override;
0184     QPointer<DiffTextWindow> getDiffTextWindow();
0185     void init();
0186 
0187     void setupConnections(const KDiff3App* app);
0188 
0189   Q_SIGNALS:
0190     void fileNameChanged(const QString&, e_SrcSelector);
0191     void encodingChanged(const QByteArray&);
0192 
0193   public Q_SLOTS:
0194     void setFirstLine(LineRef firstLine);
0195 
0196   protected:
0197     bool eventFilter(QObject*, QEvent*) override;
0198     //void paintEvent(QPaintEvent*);
0199   private Q_SLOTS:
0200     void slotReturnPressed();
0201     void slotBrowseButtonClicked();
0202 
0203     void slotEncodingChanged(const QByteArray& name);
0204 
0205   private:
0206     QLabel* m_pLabel;
0207     QLabel* m_pTopLine;
0208     QLabel* m_pEncoding;
0209     QLabel* m_pLineEndStyle;
0210     QWidget* m_pTopLineWidget;
0211     FileNameLineEdit* m_pFileSelection;
0212     QPushButton* m_pBrowseButton;
0213 
0214     QPointer<DiffTextWindow> m_pDiffTextWindow;
0215     e_SrcSelector m_winIdx;
0216 
0217     QSharedPointer<SourceData> mSourceData;
0218 };
0219 
0220 class EncodingLabel: public QLabel
0221 {
0222     Q_OBJECT
0223   public:
0224     EncodingLabel(const QString& text, const QSharedPointer<SourceData>& psd);
0225 
0226   protected:
0227     void mouseMoveEvent(QMouseEvent* ev) override;
0228     void mousePressEvent(QMouseEvent* ev) override;
0229 
0230   Q_SIGNALS:
0231     void encodingChanged(const QByteArray&);
0232 
0233   private Q_SLOTS:
0234     void slotSelectEncoding();
0235 
0236   private:
0237     QMenu* m_pContextEncodingMenu;
0238     QSharedPointer<SourceData> m_pSourceData; //SourceData to get access to "isEmpty()" and "isFromBuffer()" functions
0239 
0240     void insertCodec(const QString& visibleCodecName, const QByteArray& nameArray, QList<QByteArray>& codecEnumList, QMenu* pMenu, const QByteArray& currentTextCodecEnum) const;
0241 };
0242 
0243 #endif