File indexing completed on 2024-05-12 05:54:35

0001 /*
0002     SPDX-FileCopyrightText: 2009 Csaba Karai <krusader@users.sourceforge.net>
0003     SPDX-FileCopyrightText: 2009-2022 Krusader Krew <https://krusader.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #ifndef LISTER_H
0009 #define LISTER_H
0010 
0011 // QtCore
0012 #include <QList>
0013 #include <QMutex>
0014 #include <QTextCodec>
0015 #include <QTimer>
0016 // QtGui
0017 #include <QColor>
0018 // QtWidgets
0019 #include <QShortcut>
0020 #include <QWidget>
0021 
0022 #include <KCompletion/KLineEdit>
0023 #include <KParts/BrowserExtension>
0024 #include <KParts/Part>
0025 #include <KTextWidgets/KTextEdit>
0026 
0027 #include "../FileSystem/krquery.h"
0028 
0029 #define SLIDER_MAX 10000
0030 #define MAX_CHAR_LENGTH 4
0031 
0032 class Lister;
0033 class QLabel;
0034 class QProgressBar;
0035 class QPushButton;
0036 class QToolButton;
0037 class QAction;
0038 class QTemporaryFile;
0039 class ListerEncodingMenu;
0040 
0041 class ListerTextArea : public KTextEdit
0042 {
0043     Q_OBJECT
0044 
0045 public:
0046     ListerTextArea(Lister *lister, QWidget *parent);
0047     void reset();
0048     void calculateText(const bool forcedUpdate = false);
0049     void redrawTextArea(const bool forcedUpdate = false);
0050 
0051     qint64 textToFilePositionOnScreen(const int x, const int y, bool &isfirst);
0052     void fileToTextPositionOnScreen(const qint64 p, const bool isfirst, int &x, int &y);
0053 
0054     int tabWidth()
0055     {
0056         return _tabWidth;
0057     }
0058     bool hexMode()
0059     {
0060         return _hexMode;
0061     }
0062     void setHexMode(const bool hexMode);
0063 
0064     void copySelectedToClipboard();
0065     QString getSelectedText();
0066     void clearSelection();
0067 
0068     void getCursorPosition(int &x, int &y);
0069     qint64 getCursorPosition(bool &isfirst);
0070     qint64 getCursorAnchor()
0071     {
0072         return _cursorAnchorPos;
0073     }
0074     void setCursorPositionInDocument(const qint64 p, const bool isfirst);
0075     void ensureVisibleCursor();
0076     void deleteAnchor()
0077     {
0078         _cursorAnchorPos = -1;
0079     }
0080 
0081     void setAnchorAndCursor(const qint64 anchor, const qint64 cursor);
0082     void sizeChanged();
0083 
0084 protected:
0085     void resizeEvent(QResizeEvent *event) override;
0086     void keyPressEvent(QKeyEvent *e) override;
0087     void mousePressEvent(QMouseEvent *e) override;
0088     void mouseDoubleClickEvent(QMouseEvent *e) override;
0089     void mouseMoveEvent(QMouseEvent *e) override;
0090     void wheelEvent(QWheelEvent *event) override;
0091 
0092     QStringList readLines(const qint64 filePos, qint64 &endPos, const int lines, QList<qint64> *locs = nullptr);
0093     QString readSection(qint64 p1, qint64 p2);
0094     void setUpScrollBar();
0095     void setCursorPositionOnScreen(const int x, const int y, const int anchorX = -1, const int anchorY = -1);
0096     void handleAnchorChange(const int oldAnchor);
0097     void performAnchorChange(const int anchor);
0098     void getScreenPosition(const int position, int &x, int &y);
0099 
0100 public slots:
0101     void slotActionTriggered(const int action);
0102 
0103 protected slots:
0104     void slotCursorPositionChanged();
0105     void zoomIn(const int range = 1);
0106     void zoomOut(const int range = 1);
0107 
0108 protected:
0109     Lister *_lister;
0110 
0111     qint64 _screenStartPos = 0;
0112     qint64 _screenEndPos = 0;
0113     qint64 _averagePageSize = 0;
0114 
0115     qint64 _lastPageStartPos = 0;
0116 
0117     int _sizeX = -1;
0118     int _sizeY = -1;
0119     int _pageSize = 0;
0120 
0121     int _tabWidth = 4;
0122 
0123     bool _sizeChanged = false;
0124 
0125     QStringList _rowContent;
0126     QList<qint64> _rowStarts;
0127 
0128     qint64 _cursorPos = -1;
0129     bool _cursorAtFirstColumn = true;
0130     bool _skipCursorChangedListener = false;
0131 
0132     qint64 _cursorAnchorPos = -1;
0133 
0134     int _skippedLines = 0;
0135 
0136     bool _inSliderOp = false;
0137     bool _hexMode = false;
0138     bool _redrawing = false;
0139 
0140     QMutex _cursorBlinkMutex;
0141     QTimer _blinkTimer;
0142 };
0143 
0144 class ListerBrowserExtension : public KParts::BrowserExtension
0145 {
0146     Q_OBJECT
0147 
0148 public:
0149     explicit ListerBrowserExtension(Lister *lister);
0150 
0151 public slots:
0152     void copy();
0153     void print();
0154 
0155 protected:
0156     Lister *_lister;
0157 };
0158 
0159 class ListerPane : public QWidget
0160 {
0161     Q_OBJECT
0162 
0163 public:
0164     ListerPane(Lister *lister, QWidget *parent);
0165 
0166 protected:
0167     bool event(QEvent *event) override;
0168 
0169 protected:
0170     bool handleCloseEvent(QEvent *e);
0171     Lister *_lister;
0172 };
0173 
0174 class Lister : public KParts::ReadOnlyPart
0175 {
0176     Q_OBJECT
0177 
0178 public:
0179     explicit Lister(QWidget *parent);
0180 
0181     QScrollBar *scrollBar()
0182     {
0183         return _scrollBar;
0184     }
0185     ListerTextArea *textArea()
0186     {
0187         return _textArea;
0188     }
0189 
0190     inline qint64 fileSize()
0191     {
0192         return _fileSize;
0193     }
0194     QByteArray cacheChunk(const qint64 filePos, const qint64 maxSize);
0195 
0196     bool isSearchEnabled();
0197     void enableSearch(const bool);
0198     void enableActions(const bool);
0199 
0200     QString characterSet()
0201     {
0202         return _characterSet;
0203     }
0204     QTextCodec *codec()
0205     {
0206         return _codec;
0207     }
0208     void setCharacterSet(const QString &set);
0209     void setHexMode(const bool);
0210 
0211     QStringList readHexLines(qint64 &filePos, const qint64 endPos, const int columns, const int lines);
0212     int hexBytesPerLine(const int columns);
0213     int hexPositionDigits();
0214     int hexIndexToPosition(const int columns, const int index);
0215     int hexPositionToIndex(const int columns, const int position);
0216 
0217 public slots:
0218     void searchAction()
0219     {
0220         enableSearch(true);
0221     }
0222     void searchNext();
0223     void searchPrev();
0224     void searchDelete();
0225     void jumpToPosition();
0226     void saveAs();
0227     void saveSelected();
0228     void print();
0229     void toggleHexMode();
0230     void slotUpdate();
0231 
0232 protected slots:
0233     void slotSearchMore();
0234 
0235     void searchSucceeded();
0236     void searchFailed();
0237     void searchTextChanged();
0238 
0239     void slotDataSend(KIO::Job *, QByteArray &);
0240     void slotSendFinished(KJob *);
0241 
0242 protected:
0243     bool openUrl(const QUrl &url) override;
0244     bool closeUrl() override
0245     {
0246         return true;
0247     }
0248     bool openFile() override
0249     {
0250         return true;
0251     }
0252     void guiActivateEvent(KParts::GUIActivateEvent *event) override;
0253     void setColor(const bool match, const bool restore);
0254     void hideProgressBar();
0255     void updateProgressBar();
0256     void resetSearchPosition();
0257 
0258     qint64 getFileSize();
0259     void search(const bool forward, const bool restart = false);
0260     QStringList readLines(qint64 &filePos, const qint64 endPos, const int columns, const int lines);
0261 
0262     QTimer _searchUpdateTimer;
0263     ListerTextArea *_textArea;
0264     QScrollBar *_scrollBar;
0265     QLabel *_listerLabel;
0266     KLineEdit *_searchLineEdit;
0267     QProgressBar *_searchProgressBar;
0268     QToolButton *_searchStopButton;
0269     QPushButton *_searchNextButton;
0270     QPushButton *_searchPrevButton;
0271     bool _searchInProgress = false;
0272     bool _searchHexadecimal = false;
0273     QPushButton *_searchOptions;
0274     QLabel *_statusLabel;
0275 
0276     QAction *_fromCursorAction;
0277     QAction *_caseSensitiveAction;
0278     QAction *_matchWholeWordsOnlyAction;
0279     QAction *_regExpAction;
0280     QAction *_hexAction;
0281 
0282     QAction *_actionSaveSelected;
0283     QAction *_actionSaveAs;
0284     QAction *_actionPrint;
0285     QAction *_actionSearch;
0286     QAction *_actionSearchNext;
0287     QAction *_actionSearchPrev;
0288     QAction *_actionJumpToPosition;
0289     QAction *_actionHexMode;
0290 
0291     QString _filePath;
0292     qint64 _fileSize = 0;
0293 
0294     QByteArray _cache;
0295     qint64 _cachePos = 0;
0296 
0297     KrQuery _searchQuery;
0298     QByteArray _searchHexQuery;
0299     qint64 _searchPosition = 0;
0300     bool _searchIsForward = true;
0301     qint64 _searchLastFailedPosition = -1;
0302     int _searchProgressCounter = 0;
0303 
0304     QColor _originalBackground;
0305     QColor _originalForeground;
0306 
0307     QString _characterSet;
0308     QTextCodec *_codec = QTextCodec::codecForLocale();
0309 
0310     QTemporaryFile *_tempFile = nullptr;
0311 
0312     bool _downloading = false;
0313     bool _restartFromBeginning = false;
0314     QTimer _downloadUpdateTimer;
0315 
0316     qint64 _savePosition = 0;
0317     qint64 _saveEnd = 0;
0318 };
0319 
0320 #endif // __LISTER_H__