File indexing completed on 2024-05-12 04:58:21

0001 /* ============================================================
0002 * Falkon - Qt web browser
0003 * Copyright (C) 2010-2018 David Rosca <nowrep@gmail.com>
0004 *
0005 * This program is free software: you can redistribute it and/or modify
0006 * it under the terms of the GNU General Public License as published by
0007 * the Free Software Foundation, either version 3 of the License, or
0008 * (at your option) any later version.
0009 *
0010 * This program is distributed in the hope that it will be useful,
0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 * GNU General Public License for more details.
0014 *
0015 * You should have received a copy of the GNU General Public License
0016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017 * ============================================================ */
0018 #include "sidebar.h"
0019 #include "sidebarinterface.h"
0020 #include "docktitlebarwidget.h"
0021 #include "bookmarkssidebar.h"
0022 #include "historysidebar.h"
0023 #include "mainapplication.h"
0024 #include "browserwindow.h"
0025 #include "settings.h"
0026 
0027 #include <QMenu>
0028 #include <QActionGroup>
0029 
0030 QHash<QString, QPointer<SideBarInterface> > s_sidebars;
0031 
0032 SideBar::SideBar(SideBarManager* manager, BrowserWindow* window)
0033     : QWidget(window)
0034     , m_window(window)
0035     , m_manager(manager)
0036 {
0037     setObjectName("sidebar");
0038     setAttribute(Qt::WA_DeleteOnClose);
0039 
0040     m_layout = new QVBoxLayout(this);
0041     m_layout->setContentsMargins(0, 0, 0, 0);
0042     m_layout->setSpacing(0);
0043     setLayout(m_layout);
0044 
0045     m_titleBar = new DockTitleBarWidget(QString(), this);
0046     m_layout->addWidget(m_titleBar);
0047 }
0048 
0049 void SideBar::setTitle(const QString &title)
0050 {
0051     m_titleBar->setTitle(title);
0052 }
0053 
0054 void SideBar::setWidget(QWidget* widget)
0055 {
0056     if (m_layout->count() == 2) {
0057         delete m_layout->itemAt(1)->widget();
0058     }
0059 
0060     if (widget)
0061         m_layout->addWidget(widget);
0062 }
0063 
0064 void SideBar::showBookmarks()
0065 {
0066     m_titleBar->setTitle(tr("Bookmarks"));
0067     auto* bar = new BookmarksSidebar(m_window);
0068     setWidget(bar);
0069 }
0070 
0071 void SideBar::showHistory()
0072 {
0073     m_titleBar->setTitle(tr("History"));
0074     auto* bar = new HistorySideBar(m_window);
0075     setWidget(bar);
0076 }
0077 
0078 void SideBar::close()
0079 {
0080     m_manager->closeSideBar();
0081 
0082     QWidget* p = parentWidget();
0083     if (p) {
0084         p->setFocus();
0085     }
0086 
0087     QWidget::close();
0088 }
0089 
0090 SideBarManager::SideBarManager(BrowserWindow* parent)
0091     : QObject(parent)
0092     , m_window(parent)
0093 {
0094 }
0095 
0096 QString SideBarManager::activeSideBar() const
0097 {
0098     return m_activeBar;
0099 }
0100 
0101 void SideBarManager::createMenu(QMenu* menu)
0102 {
0103     m_window->removeActions(menu->actions());
0104     menu->clear();
0105 
0106     auto *group = new QActionGroup(menu);
0107 
0108     QAction* act = menu->addAction(SideBar::tr("Bookmarks"), this, &SideBarManager::slotShowSideBar);
0109     act->setCheckable(true);
0110     act->setShortcut(QKeySequence(QSL("Ctrl+Shift+B")));
0111     act->setData(QSL("Bookmarks"));
0112     act->setChecked(m_activeBar == QL1S("Bookmarks"));
0113     group->addAction(act);
0114 
0115     act = menu->addAction(SideBar::tr("History"), this, &SideBarManager::slotShowSideBar);
0116     act->setCheckable(true);
0117     act->setShortcut(QKeySequence(QSL("Ctrl+H")));
0118     act->setData(QSL("History"));
0119     act->setChecked(m_activeBar == QL1S("History"));
0120     group->addAction(act);
0121 
0122     for (const QPointer<SideBarInterface> &sidebar : std::as_const(s_sidebars)) {
0123         if (sidebar) {
0124             QAction* act = sidebar.data()->createMenuAction();
0125             act->setData(s_sidebars.key(sidebar));
0126             act->setChecked(m_activeBar == s_sidebars.key(sidebar));
0127             connect(act, &QAction::triggered, this, &SideBarManager::slotShowSideBar);
0128             menu->addAction(act);
0129             group->addAction(act);
0130         }
0131     }
0132 
0133     m_window->addActions(menu->actions());
0134 }
0135 
0136 void SideBarManager::addSidebar(const QString &id, SideBarInterface* interface)
0137 {
0138     s_sidebars[id] = interface;
0139 }
0140 
0141 void SideBarManager::removeSidebar(SideBarInterface *interface)
0142 {
0143     const QString id = s_sidebars.key(interface);
0144     if (id.isEmpty()) {
0145         return;
0146     }
0147 
0148     s_sidebars.remove(id);
0149 
0150     const auto windows = mApp->windows();
0151     for (BrowserWindow* window : windows) {
0152         window->sideBarManager()->sideBarRemoved(id);
0153     }
0154 }
0155 
0156 void SideBarManager::slotShowSideBar()
0157 {
0158     if (auto* act = qobject_cast<QAction*>(sender())) {
0159         showSideBar(act->data().toString());
0160     }
0161 }
0162 
0163 void SideBarManager::showSideBar(const QString &id, bool toggle)
0164 {
0165     if (id.isEmpty() || id == QL1S("None")) {
0166         return;
0167     }
0168 
0169     if (!m_sideBar) {
0170         m_sideBar = m_window->addSideBar();
0171         connect(m_sideBar, &QObject::destroyed, this, [this]() {
0172             m_activeBar.clear();
0173             m_window->saveSideBarSettings();
0174         });
0175     }
0176 
0177     if (id == m_activeBar) {
0178         if (!toggle) {
0179             return;
0180         }
0181         m_sideBar.data()->close();
0182         m_activeBar.clear();
0183         m_window->saveSideBarSettings();
0184         return;
0185     }
0186 
0187     if (id == QLatin1String("Bookmarks")) {
0188         m_sideBar.data()->showBookmarks();
0189     }
0190     else if (id == QLatin1String("History")) {
0191         m_sideBar.data()->showHistory();
0192     }
0193     else {
0194         SideBarInterface* sidebar = s_sidebars[id].data();
0195         if (!sidebar) {
0196             m_sideBar.data()->close();
0197             return;
0198         }
0199 
0200         m_sideBar.data()->setTitle(sidebar->title());
0201         m_sideBar.data()->setWidget(sidebar->createSideBarWidget(m_window));
0202     }
0203 
0204     m_activeBar = id;
0205     m_window->saveSideBarSettings();
0206 }
0207 
0208 void SideBarManager::sideBarRemoved(const QString &id)
0209 {
0210     if (m_activeBar == id && m_sideBar) {
0211         m_sideBar.data()->setWidget(nullptr);
0212         m_sideBar.data()->close();
0213     }
0214 }
0215 
0216 void SideBarManager::closeSideBar()
0217 {
0218     if (mApp->isClosing()) {
0219         return;
0220     }
0221 
0222     m_activeBar.clear();
0223     m_window->saveSideBarSettings();
0224 }