File indexing completed on 2024-04-21 04:58:24

0001 /*  This file is part of the KDE project
0002     SPDX-FileCopyrightText: 1999 Simon Hausmann <hausmann@kde.org>
0003     SPDX-FileCopyrightText: 2007 Eduardo Robles Elvira <edulix@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #ifndef __konq_viewmanager_h__
0009 #define __konq_viewmanager_h__
0010 
0011 #include "konqprivate_export.h"
0012 #include "konqfactory.h"
0013 #include "konqframe.h"
0014 #include "konqopenurlrequest.h"
0015 
0016 #include <QMap>
0017 #include <QPointer>
0018 #include <QUrl>
0019 
0020 #include <KService>
0021 #include <KParts/PartManager>
0022 #include <KSharedConfig>
0023 #include <KPluginMetaData>
0024 
0025 class KonqFrameTabs;
0026 class QString;
0027 class KConfig;
0028 class KConfigGroup;
0029 class KonqMainWindow;
0030 class KonqFrameBase;
0031 class KonqFrameContainer;
0032 class KonqFrameContainerBase;
0033 class KonqView;
0034 class KonqClosedTabItem;
0035 class KonqClosedWindowItem;
0036 
0037 namespace KParts
0038 {
0039 class ReadOnlyPart;
0040 }
0041 
0042 class KONQ_TESTS_EXPORT KonqViewManager : public KParts::PartManager
0043 {
0044     Q_OBJECT
0045 public:
0046     explicit KonqViewManager(KonqMainWindow *mainWindow);
0047     ~KonqViewManager() override;
0048 
0049     KonqView *createFirstView(const QString &mimeType, const QString &serviceName);
0050 
0051     /**
0052      * Splits the view, depending on orientation, either horizontally or
0053      * vertically. The first view in the splitter will contain the initial
0054      * view, the other will be a new one, constructed from the same service
0055      * (part) as the first view.
0056      * Returns the newly created view or 0 if the view couldn't be created.
0057      *
0058      * @param newOneFirst if true, move the new view as the first one (left or top)
0059      */
0060     KonqView *splitView(KonqView *view,
0061                         Qt::Orientation orientation,
0062                         bool newOneFirst = false, bool forceAutoEmbed = false);
0063 
0064     /**
0065      * Does basically the same as splitView() but inserts the new view inside the
0066      * specified container (usually used with the main container, to insert
0067      * the new view at the top of the view tree).
0068      * Returns the newly created view or 0 if the view couldn't be created.
0069      *
0070      * @param newOneFirst if true, move the new view as the first one (left or top)
0071      */
0072     KonqView *splitMainContainer(KonqView *currentView,
0073                                  Qt::Orientation orientation,
0074                                  const QString &serviceType = QString(),
0075                                  const QString &serviceName = QString(),
0076                                  bool newOneFirst = false);
0077 
0078     /**
0079      * Adds a tab to m_tabContainer
0080      */
0081     KonqView *addTab(const QString &serviceType,
0082                      const QString &serviceName = QString(),
0083                      bool passiveMode = false, bool openAfterCurrentPage = false, int pos = -1);
0084 
0085     /**
0086      * Duplicates the specified tab
0087      */
0088     void duplicateTab(int tabIndex, bool openAfterCurrentPage = false);
0089 
0090     /**
0091      * creates a new tab from a history entry
0092      * used for MMB on back/forward
0093      */
0094     KonqView *addTabFromHistory(KonqView *currentView, int steps, bool openAfterCurrentPage);
0095 
0096     /**
0097      * Break the specified tab off into a new window
0098      */
0099     KonqMainWindow *breakOffTab(int tab, const QSize &windowSize);
0100 
0101     /**
0102      * Guess!:-)
0103      * Also takes care of setting another view as active if @p view was the active view
0104      */
0105     void removeView(KonqView *view);
0106 
0107     /**
0108      * Removes specified tab
0109      * Also takes care of setting another view as active if the active view was in this tab
0110      */
0111     void removeTab(KonqFrameBase *tab, bool emitAboutToRemoveSignal = true);
0112 
0113     /**
0114      * Removes all, but the specified tab.
0115      * Also takes care of setting the specified tab as active if the active view was not in this tab
0116      * @param tabIndex the index of the tab
0117      */
0118     void removeOtherTabs(int tabIndex);
0119 
0120     /**
0121      * Locates and activates the next tab
0122      *
0123      */
0124     void activateNextTab();
0125 
0126     /**
0127      * Locates and activates the previous tab
0128      *
0129      */
0130     void activatePrevTab();
0131 
0132     /**
0133      * Activate given tab
0134      *
0135      */
0136     void activateTab(int position);
0137 
0138     /**
0139      * @brief The index of the current tab
0140      * @return the index of the current tab
0141      */
0142     int currentTabIndex() const;
0143 
0144     /**
0145      * @brief The number of tabs
0146      * @return the number of tabs
0147      */
0148     int tabsCount() const;
0149 
0150     void moveTabBackward();
0151     void moveTabForward();
0152 
0153     void reloadAllTabs();
0154 
0155     /**
0156      * Creates the tabwidget on demand and returns it.
0157      */
0158     KonqFrameTabs *tabContainer();
0159 
0160     /**
0161      * Returns true if the tabwidget exists and the tabbar is visible
0162      */
0163     bool isTabBarVisible() const;
0164     
0165     /**
0166      * Forces hiding the tab bar, regardless of settings or number of tabs
0167      * 
0168      * This is used to provide movie full screen
0169      */
0170     void forceHideTabBar(bool force);
0171 
0172     // Apply configuration that applies to us, like alwaysTabbedMode.
0173     void applyConfiguration();
0174 
0175     /**
0176      * Brings the tab specified by @p tabIndex to the front of the stack
0177      */
0178     void showTab(int tabIndex);
0179 
0180     /**
0181      * Brings the tab specified by @p view to the front of the stack
0182      * Deprecated, used the other one; this one breaks too easily with split views
0183      * (if passing the current view to @p view)
0184      */
0185     void showTab(KonqView *view);
0186 
0187     /**
0188      * Updates favicon pixmaps used in tabs
0189      *
0190      */
0191     void updatePixmaps();
0192 
0193     /**
0194      * Saves the current view layout to a group in a config file.
0195      * This is shared between saveViewProfileToFile and saveProperties (session management)
0196      * Remove config file before saving, especially if SaveUrls is false.
0197      * @param cfg the config file
0198      * @param options whether to save nothing, the URLs or the complete history of each view in the profile
0199      */
0200     void saveViewConfigToGroup(KConfigGroup &cfg, KonqFrameBase::Options options);
0201 
0202     /**
0203      * Loads a view layout from a config file. Removes all views before loading.
0204      * @param cfg the config file
0205      * @param filename if set, remember the file name of the profile (for save settings)
0206      * It has to be under the profiles dir. Otherwise, set to QString()
0207      * @param forcedUrl if set, the URL to open, whatever the profile says
0208      * @param req attributes related to @p forcedUrl
0209      * settings, they will be reset to the defaults
0210      */
0211     void loadViewConfigFromGroup(const KConfigGroup &cfg, const QString &filename,
0212                                   const QUrl &forcedUrl = QUrl(),
0213                                   const KonqOpenURLRequest &req = KonqOpenURLRequest(),
0214                                   bool openUrl = true);
0215     /**
0216      * Whether we are currently loading a profile
0217      */
0218     bool isLoadingProfile() const
0219     {
0220         return m_bLoadingProfile;
0221     }
0222 
0223     void clear();
0224 
0225     KonqView *chooseNextView(KonqView *view);
0226 
0227     /**
0228      * Called whenever
0229      * - the total number of views changed
0230      * - the number of views in passive mode changed
0231      * The implementation takes care of showing or hiding the statusbar indicators
0232      */
0233     void viewCountChanged();
0234 
0235     KonqMainWindow *mainWindow() const
0236     {
0237         return m_pMainWindow;
0238     }
0239 
0240     /**
0241      * Reimplemented from PartManager
0242      */
0243     void removePart(KParts::Part *part) override;
0244 
0245     /**
0246      * Reimplemented from PartManager
0247      */
0248     void setActivePart(KParts::Part *part, QWidget *widget = nullptr) override;
0249 
0250     void doSetActivePart(KParts::ReadOnlyPart *part);
0251 
0252     void applyWindowSize(const KConfigGroup &profileGroup);
0253 
0254 #ifndef NDEBUG
0255     void printFullHierarchy();
0256 #endif
0257 
0258     void setLoading(KonqView *view, bool loading);
0259 
0260     /**
0261      * Creates a copy of the current window
0262      */
0263     KonqMainWindow *duplicateWindow();
0264 
0265     /**
0266      * Open a saved window.
0267      *
0268      * @param openTabsInsideCurrentWindow if true, it will try to open the
0269      * tabs inside current window.
0270      */
0271     KonqMainWindow *openSavedWindow(const KConfigGroup &configGroup,
0272                                     bool openTabsInsideCurrentWindow);
0273 
0274     /**
0275      * Open a saved window in a new KonqMainWindow instance.
0276      * It doesn't have the openTabsInsideCurrentWindow because this is the
0277      * static version.
0278      */
0279     static KonqMainWindow *openSavedWindow(const KConfigGroup &configGroup);
0280 
0281 public Q_SLOTS:
0282     /**
0283      * Opens a previously closed window in a new window
0284      */
0285     static void openClosedWindow(const KonqClosedWindowItem &closedTab);
0286 
0287     /**
0288      * Opens a previously closed tab in a new tab
0289      */
0290     void openClosedTab(const KonqClosedTabItem &closedTab);
0291 
0292     /**
0293      * @brief Applies any relevant configuration settings
0294      */
0295     void reparseConfiguration();
0296 
0297 private Q_SLOTS:
0298     void emitActivePartChanged();
0299 
0300     void slotPassiveModePartDeleted();
0301 
0302     void slotActivePartChanged(KParts::Part *newPart);
0303 
0304     /**
0305      * @brief Apply delayed loading to a tab
0306      * @param idx the index of the tab
0307      * @see KonqView::delayedLoad
0308      */
0309     void delayedLoadTab(int idx);
0310 
0311 signals:
0312 // the signal is only emitted when the contents of the view represented by
0313 // "tab" are going to be lost for good.
0314     void aboutToRemoveTab(KonqFrameBase *tab);
0315 
0316 private:
0317 
0318     /**
0319      * @brief Struct containing the parameters to load a view from a configuration object
0320      */
0321     struct LoadViewUrlData {
0322         const QUrl& defaultUrl; //!<The default URL to load if none is specified
0323         const QUrl &forcedUrl; //!<The URL to load instead of the one specified in the configuration object
0324         const QString &forcedService; //!<The service (part) to use instead of the default one
0325         bool openUrl; //!<Whether to open URLs at all
0326     };
0327 
0328     /**
0329      * Load the config entries for a view.
0330      * @param cfg the config object
0331      * @param parent the container where the new item should be put
0332      * @param name the name of the item
0333      * @param viewData how to load a view
0334      * @param openAfterCurrentPage whether the item should be put after the current tab or not
0335      * @param pos the position of the new item. -1 means at the end
0336      * @todo Refactor all the loading code
0337      */
0338     void loadItem(const KConfigGroup &cfg, KonqFrameContainerBase *parent,
0339                   const QString &name, const LoadViewUrlData &viewData,
0340                   bool openAfterCurrentPage = false, int pos = -1);
0341 
0342     void loadRootItem(const KConfigGroup &cfg, KonqFrameContainerBase *parent,
0343                       const QUrl &defaultURL, bool openUrl,
0344                       const QUrl &forcedUrl, const QString &forcedService = QString(),
0345                       bool openAfterCurrentPage = false,
0346                       int pos = -1);
0347 
0348     void createTabContainer(QWidget *parent, KonqFrameContainerBase *parentContainer);
0349 
0350     /**
0351      * Creates a new View based on the given ServiceType. If serviceType is empty
0352      * it clones the current view.
0353      * Returns the newly created view.
0354      */
0355     KonqViewFactory createView(const QString &serviceType,  /* can be servicetype or mimetype */
0356                                const QString &serviceName,
0357                                KPluginMetaData &service,
0358                                QVector<KPluginMetaData> &partServiceOffers,
0359                                KService::List &appServiceOffers,
0360                                bool forceAutoEmbed = false);
0361 
0362     /**
0363      * Mainly creates the backend structure(KonqView) for a view and
0364      * connects it
0365      */
0366     KonqView *setupView(KonqFrameContainerBase *parentContainer,
0367                         KonqViewFactory &viewFactory,
0368                         const KPluginMetaData &service,
0369                         const QVector<KPluginMetaData> &partServiceOffers,
0370                         const KService::List &appServiceOffers,
0371                         const QString &serviceType,
0372                         bool passiveMode, bool openAfterCurrentPage = false, int pos = -1);
0373 
0374     KonqView* setupView(KonqFrameContainerBase *parentContainer, bool passiveMode, bool openAfterCurrentPage = false, int pos = -1);
0375 
0376     /**
0377      * @brief Loads a view item from a `KConfigGroup`
0378      * @param cfg the config group to load the view from
0379      * @param prefix the string to append to the entry names to obtain the keys in @p cfg
0380      * @param parent the frame container the view should belong to
0381      * @param name the name of the view
0382      * @param defaultURL the default URL to use if none is provided by @p cfg
0383      * @param openUrl whether to open an URL in the view
0384      * @param forcedService the plugin id of the plugin to use for the view
0385      * @param openAfterCurrentPage whether or not the view should be opened after the current page
0386      * @param pos the position of the view in @p parent. If -1, the view will be last.
0387      *  Ignored if @p openAfterCurrentPage is `true` and @p parent is a container of type \link KonqFrameBase::Tabs Tabs\endlink
0388      * @todo Refactor
0389      */
0390     void loadViewItem(const KConfigGroup &cfg, const QString &prefix, KonqFrameContainerBase *parent,
0391                                const QString &name, const LoadViewUrlData &data, bool openAfterCurrentPage, int pos);
0392 
0393     /**
0394      * @brief Load an item representing a tab from a configuration object
0395      * @param cfg the configuration object
0396      * @param prefix the string to append to the entry names to obtain the keys in @p cfg
0397      * @param parent the frame container the tab should belong to
0398      * @param viewData how to load the views in the tab
0399      */
0400     void loadTabsItem(const KConfigGroup &cfg, const QString &prefix, KonqFrameContainerBase *parent, const LoadViewUrlData &viewData);
0401 
0402     /**
0403      * @brief Load an item representing a container (split view) from a configuration object
0404      * @param cfg the configuration object
0405      * @param prefix the string to append to the entry names to obtain the keys in @p cfg
0406      * @param parent the frame container the container should belong to
0407      * @param name the name of the container
0408      * @param openAfterCurrentPage whether or not the container should be opened after the current page
0409      * @param pos the position of the container in @p parent. If -1, the container will be last.
0410      *  Ignored if @p openAfterCurrentPage is `true` and @p parent is a container of type \link KonqFrameBase::Tabs Tabs\endlink
0411      * @param viewData how to load the views in the container
0412      */
0413     void loadContainerItem(const KConfigGroup &cfg, const QString &prefix, KonqFrameContainerBase *parent, const QString &name,
0414                            bool openAfterCurrentPage, int pos, const LoadViewUrlData &viewData);
0415 
0416     /**
0417      * @brief Restore the status of a view not contained in the tab widget from a configuration group
0418      *
0419      * This restores history and opens the correct URL in the view
0420      * @param view the view whose history should be restored
0421      * @param cfg the configuration group to read history from
0422      * @param prefix the prefix to append to keys to read entries in @p cfg
0423      * @param defaultURL a default URL to use
0424      * @param serviceType the service type to display
0425      */
0426     void restoreViewOutsideTabContainer(KonqView *view, const KConfigGroup &cfg, const QString &prefix, const QUrl &defaultURL, const QString &serviceType);
0427 
0428 #ifndef NDEBUG
0429     //just for debugging
0430     void printSizeInfo(KonqFrameBase *frame,
0431                        KonqFrameContainerBase *parent,
0432                        const char *msg);
0433 #endif
0434 
0435     KonqMainWindow *m_pMainWindow;
0436 
0437     KonqFrameTabs *m_tabContainer;
0438 
0439     bool m_bLoadingProfile;
0440 
0441     QMap<QString /*display name*/, QString /*path to file*/> m_mapProfileNames;
0442 };
0443 
0444 #endif