File indexing completed on 2024-04-28 05:49:33

0001 /*
0002     SPDX-FileCopyrightText: 2014 Dominik Haumann <dhaumann@kde.org>
0003     SPDX-FileCopyrightText: 2020 Christoph Cullmann <cullmann@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #pragma once
0009 
0010 #include "doc_or_widget.h"
0011 #include <QTabBar>
0012 
0013 #include <unordered_map>
0014 
0015 namespace KTextEditor
0016 {
0017 class Document;
0018 }
0019 
0020 /**
0021  * The \p KateTabBar class provides a tab bar, e.g. for tabbed documents.
0022  *
0023  * The API closely follows the API of QTabBar.
0024  *
0025  * @author Dominik Haumann
0026  */
0027 class KateTabBar : public QTabBar
0028 {
0029     Q_OBJECT
0030     Q_PROPERTY(bool isActive READ isActive WRITE setActive)
0031 
0032 public:
0033     explicit KateTabBar(QWidget *parent = nullptr);
0034 
0035     /**
0036      * Read and apply tab limit as configured
0037      */
0038     void readConfig();
0039 
0040     void tabInserted(int idx) override;
0041 
0042     /**
0043      * Get the ID of the tab that is located left of the current tab.
0044      * The return value is -1, if there is no previous tab.
0045      */
0046     int prevTab() const;
0047 
0048     /**
0049      * Get the ID of the tab that is located right of the current tab.
0050      * The return value is -1, if there is no next tab.
0051      */
0052     int nextTab() const;
0053 
0054     /**
0055      * Returns whether a tab with ID \a id exists.
0056      */
0057     bool containsTab(int index) const;
0058 
0059     QVariant ensureValidTabData(int idx);
0060 
0061     void setCurrentDocument(DocOrWidget);
0062     int documentIdx(DocOrWidget);
0063     void setTabDocument(int idx, DocOrWidget doc);
0064     DocOrWidget tabDocument(int idx);
0065     void removeDocument(DocOrWidget doc);
0066     void setModifiedStateIcon(int idx, KTextEditor::Document *doc);
0067 
0068     /**
0069      * Marks this tabbar as active. That is, current-tab indicators are
0070      * properly highlighted, indicating that child widgets of this tabbar
0071      * will get input.
0072      *
0073      * This concept is mostly useful, if your application has multiple tabbars.
0074      * Inactive tabbars are grayed out.
0075      */
0076     void setActive(bool active);
0077 
0078     /**
0079      * Returns whether this tabbar is active.
0080      */
0081     bool isActive() const;
0082 
0083     /**
0084      * Returns the document list of this tab bar.
0085      * @return document list in order of tabs
0086      */
0087     QList<DocOrWidget> documentList() const;
0088 
0089 Q_SIGNALS:
0090     /**
0091      * This signal is emitted whenever the context menu is requested for
0092      * button @p id at position @p globalPos.
0093      * @param id the button, or -1 if the context menu was requested on
0094      *        at a place where no tab exists
0095      * @param globalPos the position of the context menu in global coordinates
0096      */
0097     void contextMenuRequest(int id, const QPoint &globalPos);
0098 
0099     /**
0100      * This signal is emitted whenever the users double clicks on the free
0101      * space next to the tab bar. Typically, a new document should be
0102      * created.
0103      */
0104     void newTabRequested();
0105 
0106     /**
0107      * This signal is emitted whenever the tab bar was clicked while the
0108      * tab bar is not the active view space tab bar.
0109      */
0110     void activateViewSpaceRequested();
0111 
0112 protected:
0113     //! Override to avoid requesting a new tab.
0114     void mouseDoubleClickEvent(QMouseEvent *event) override;
0115 
0116     //! Override to request making the tab bar active.
0117     void mousePressEvent(QMouseEvent *event) override;
0118 
0119     void mouseMoveEvent(QMouseEvent *) override;
0120 
0121     //! Request context menu
0122     void contextMenuEvent(QContextMenuEvent *ev) override;
0123 
0124 private:
0125     using QTabBar::addTab;
0126     using QTabBar::insertTab;
0127 
0128     bool m_isActive = false;
0129     DocOrWidget m_beingAdded = static_cast<QWidget *>(nullptr);
0130 
0131     /**
0132      * limit of number of tabs we should keep
0133      * default unlimited == 0
0134      */
0135     int m_tabCountLimit = 0;
0136 
0137     /**
0138      * next lru counter value for a tab
0139      */
0140     quint64 m_lruCounter = 0;
0141 
0142     /**
0143      * should a double click create a new document?
0144      */
0145     bool m_doubleClickNewDocument = false;
0146 
0147     /*
0148      * should a middle click close a document?
0149      */
0150     bool m_middleClickCloseDocument = false;
0151 
0152     /**
0153      * Should the new tab open in front of current tab
0154      */
0155     bool m_openNewTabInFrontOfCurrent = false;
0156 
0157     /**
0158      * LRU counter storage, to determine which document has which age
0159      * simple 64-bit counter, worst thing that can happen on 64-bit wraparound
0160      * is a bit strange tab replacement a few times
0161      */
0162     std::unordered_map<DocOrWidget, std::pair<quint64, bool>> m_docToLruCounterAndHasTab;
0163 
0164     QPoint dragStartPos;
0165     QPoint dragHotspotPos;
0166 };