File indexing completed on 2024-04-28 05:49:35
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 2001 Christoph Cullmann <cullmann@kde.org> 0003 SPDX-FileCopyrightText: 2001 Joseph Wenninger <jowenn@kde.org> 0004 SPDX-FileCopyrightText: 2001 Anders Lund <anders.lund@lund.tdcadsl.dk> 0005 0006 SPDX-License-Identifier: LGPL-2.0-only 0007 */ 0008 0009 #pragma once 0010 0011 #include <ktexteditor/document.h> 0012 #include <ktexteditor/view.h> 0013 0014 #include "doc_or_widget.h" 0015 #include "kateprivate_export.h" 0016 #include "katetabbar.h" 0017 0018 #include <QWidget> 0019 0020 class KConfigBase; 0021 class KateViewManager; 0022 class QStackedWidget; 0023 class QToolButton; 0024 class LocationHistoryTest; 0025 class KToggleAction; 0026 0027 class KATE_PRIVATE_EXPORT KateViewSpace : public QWidget 0028 { 0029 Q_OBJECT 0030 0031 friend class LocationHistoryTest; 0032 friend class KateViewManagementTests; 0033 0034 public: 0035 explicit KateViewSpace(KateViewManager *, QWidget *parent = nullptr, const char *name = nullptr); 0036 0037 ~KateViewSpace() override; 0038 0039 /** 0040 * Returns \e true, if this view space is currently the active view space. 0041 */ 0042 bool isActiveSpace() const; 0043 0044 /** 0045 * Depending on @p active, mark this view space as active or inactive. 0046 * Called from the view manager. 0047 */ 0048 void setActive(bool active); 0049 0050 /** 0051 * @return the view manager that this viewspace belongs to 0052 */ 0053 KateViewManager *viewManager() const 0054 { 0055 return m_viewManager; 0056 } 0057 0058 /** 0059 * Create new view for given document 0060 * @param doc document to create view for 0061 * @return new created view 0062 */ 0063 KTextEditor::View *createView(KTextEditor::Document *doc); 0064 void removeView(KTextEditor::View *v); 0065 0066 bool showView(KTextEditor::View *view) 0067 { 0068 return showView(view->document()); 0069 } 0070 bool showView(DocOrWidget); 0071 0072 // might be nullptr, if there is no view 0073 KTextEditor::View *currentView(); 0074 0075 void saveConfig(KConfigBase *config, int myIndex, const QString &viewConfGrp); 0076 void restoreConfig(KateViewManager *viewMan, const KConfigBase *config, const QString &group); 0077 0078 /** 0079 * Returns the document list of this tab bar. 0080 * @return document list in order of tabs 0081 */ 0082 QList<DocOrWidget> documentList() const 0083 { 0084 return m_tabBar->documentList(); 0085 } 0086 0087 int tabCount() const 0088 { 0089 return m_tabBar->count(); 0090 } 0091 0092 /** 0093 * How many documents are registered here? 0094 */ 0095 int numberOfRegisteredDocuments() const 0096 { 0097 return m_registeredDocuments.size(); 0098 } 0099 0100 /** 0101 * Register one document for this view space. 0102 * Each registered document will get e.g. a tab bar button. 0103 */ 0104 void registerDocument(KTextEditor::Document *doc); 0105 0106 /** 0107 * closes the view of the provided doc in this viewspace 0108 */ 0109 void closeDocument(KTextEditor::Document *doc); 0110 0111 /* 0112 * Does this viewspace contain @p doc 0113 */ 0114 bool hasDocument(DocOrWidget doc) const; 0115 0116 bool hasViewForDocument(KTextEditor::Document *doc) const 0117 { 0118 return m_docToView.find(doc) != m_docToView.end(); 0119 } 0120 0121 /** 0122 * Removes @p doc from this space and returns the associated 0123 * view or a widget 0124 * Used for dnd 0125 */ 0126 QWidget *takeView(DocOrWidget); 0127 0128 /** 0129 * Adds @p view to this space 0130 * Used for dnd to add a view from another viewspace 0131 */ 0132 void addView(QWidget *w); 0133 0134 /** 0135 * Event filter to catch events from view space tool buttons. 0136 */ 0137 bool eventFilter(QObject *obj, QEvent *event) override; 0138 0139 /** 0140 * Focus the previous tab in the tabbar. 0141 */ 0142 void focusPrevTab(); 0143 0144 /** 0145 * Focus the next tab in the tabbar. 0146 */ 0147 void focusNextTab(); 0148 0149 /** 0150 * Add a non KTE-View as a tab 0151 */ 0152 void addWidgetAsTab(QWidget *widget); 0153 0154 /** 0155 * Does this viewspace contain any not KTextEditor::View widgets? 0156 */ 0157 bool hasWidgets() const; 0158 0159 /** 0160 * Does the current tab contains a widget 0161 * that is not a KTextEditor::View 0162 * 0163 * If the current active tab has a KTE::View 0164 * this will return nullptr 0165 */ 0166 QWidget *currentWidget(); 0167 0168 /// Returns all non-KTE::View widgets 0169 QWidgetList widgets() const; 0170 0171 bool closeTabWithWidget(QWidget *widget); 0172 0173 bool activateWidget(QWidget *widget); 0174 0175 // BEGIN Location History Stuff 0176 0177 /** 0178 * go forward in location history 0179 */ 0180 void goForward(); 0181 0182 /** 0183 * go back in location history 0184 */ 0185 void goBack(); 0186 0187 /** 0188 * Is back history avail? 0189 */ 0190 bool isHistoryBackEnabled() const; 0191 0192 /** 0193 * Is forward history avail? 0194 */ 0195 bool isHistoryForwardEnabled() const; 0196 0197 /** 0198 * Add a jump location for jumping back and forth between history 0199 */ 0200 void addPositionToHistory(const QUrl &url, KTextEditor::Cursor, bool calledExternally = false); 0201 0202 // END Location History Stuff 0203 0204 void focusNavigationBar(); 0205 0206 // ensure we have a view for the current document tab, e.g. after document closing 0207 void ensureViewForCurrentTab() 0208 { 0209 // just trigger change view, will do the needful 0210 changeView(m_tabBar->currentIndex()); 0211 } 0212 0213 protected: 0214 // DND 0215 void dragEnterEvent(QDragEnterEvent *e) override; 0216 void dragLeaveEvent(QDragLeaveEvent *e) override; 0217 void dropEvent(QDropEvent *e) override; 0218 0219 Q_SIGNALS: 0220 void viewSpaceEmptied(KateViewSpace *vs); 0221 0222 public Q_SLOTS: 0223 void documentDestroyed(QObject *doc); 0224 void updateDocumentName(KTextEditor::Document *doc); 0225 void updateDocumentUrl(KTextEditor::Document *doc); 0226 0227 private Q_SLOTS: 0228 void tabBarToggled(); 0229 void urlBarToggled(bool); 0230 void changeView(int buttonId); 0231 0232 /** 0233 * Save @p v config 0234 * This function is called when closing the view 0235 * When the viewspace itself saves its config, it doesn't use this function 0236 */ 0237 void saveViewConfig(KTextEditor::View *v); 0238 0239 /** 0240 * Calls this slot to make this view space the currently active view space. 0241 * Making it active goes through the KateViewManager. 0242 * @param focusCurrentView if @e true, the current view will get focus 0243 */ 0244 void makeActive(bool focusCurrentView = true); 0245 0246 /** 0247 * This slot is called by the tabbar, if tab @p id was closed through the 0248 * context menu. 0249 */ 0250 void closeTabRequest(int id); 0251 0252 /** 0253 * This slot is called when the context menu is requested for button 0254 * @p id at position @p globalPos. 0255 * @param id the button, or -1 if the context menu was requested on 0256 * at a place where no tab exists 0257 * @param globalPos the position of the context menu in global coordinates 0258 */ 0259 void showContextMenu(int id, const QPoint &globalPos); 0260 0261 /** 0262 * Called to create a new empty document. 0263 */ 0264 void createNewDocument(); 0265 0266 /** 0267 * Read and apply the config for this view space. 0268 */ 0269 void readConfig(); 0270 0271 /** 0272 * Document created or deleted, used to auto hide/show the tabs 0273 */ 0274 void updateTabBar(); 0275 0276 private: 0277 bool acceptsDroppedTab(const class QMimeData *tabMimeData); 0278 /** 0279 * Returns the amount of documents in KateDocManager that currently 0280 * have no tab in this tab bar. 0281 */ 0282 int hiddenDocuments() const; 0283 0284 // The following functions are for unit-testing purposes 0285 size_t ¤tLoc() 0286 { 0287 return currentLocation; 0288 } 0289 0290 auto &locationHistoryBuffer() 0291 { 0292 return m_locations; 0293 } 0294 0295 void removeWidget(QWidget *w); 0296 0297 private: 0298 // Kate's view manager 0299 KateViewManager *m_viewManager; 0300 0301 // config group string, used for restoring View session configuration 0302 QString m_group; 0303 0304 // flag that indicates whether this view space is the active one. 0305 // correct setter: m_viewManager->setActiveSpace(this); 0306 bool m_isActiveSpace; 0307 0308 // widget stack that contains all KTE::Views 0309 QStackedWidget *stack; 0310 0311 // jump location history for this view-space 0312 struct Location { 0313 QUrl url; 0314 KTextEditor::Cursor cursor; 0315 }; 0316 0317 std::vector<Location> m_locations; 0318 size_t currentLocation = 0; 0319 0320 /** 0321 * all documents this view space is aware of 0322 * depending on the limit of tabs, not all will have a corresponding 0323 * tab in the KateTabBar 0324 * these are stored in used order (MRU last) 0325 */ 0326 QList<DocOrWidget> m_registeredDocuments; 0327 0328 // the list of views that are contained in this view space, 0329 // mapped through a hash from Document to View. 0330 // note: the number of entries match stack->count(); 0331 std::unordered_map<KTextEditor::Document *, KTextEditor::View *> m_docToView; 0332 0333 // tab bar that contains viewspace tabs 0334 KateTabBar *m_tabBar; 0335 0336 // split action 0337 QToolButton *m_split; 0338 0339 // quick open action 0340 QToolButton *m_quickOpen; 0341 0342 // go back in history button (only visible when the tab bar is visible) 0343 QToolButton *m_historyBack; 0344 0345 // go forward in history button (only visible when the tab bar is visible) 0346 QToolButton *m_historyForward; 0347 0348 // rubber band to indicate drag and drop 0349 std::unique_ptr<class QRubberBand> m_dropIndicator; 0350 0351 class KateUrlBar *m_urlBar = nullptr; 0352 0353 struct TopBarLayout { 0354 class QHBoxLayout *tabBarLayout = nullptr; 0355 class QVBoxLayout *mainLayout = nullptr; 0356 } m_layout; 0357 0358 // should the tab bar be auto hidden if just one document is open? 0359 bool m_autoHideTabBar = false; 0360 0361 // Block adding position to history if this is true 0362 bool m_blockAddHistory = false; 0363 0364 // Option in Split Views toolButton menu to 0365 // Synchronise (vertical) scrollbars of the active view 0366 KToggleAction *m_toggleSynchronisedScrolling; 0367 };