1 /* ============================================================
2 * TabManager plugin for Falkon
3 * Copyright (C) 2013-2018 S. Razi Alavizadeh <s.r.alavizadeh@gmail.com>
4 * Copyright (C) 2017-2018 David Rosca <nowrep@gmail.com>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 * ============================================================ */
19 #include "tabmanagerwidgetcontroller.h"
20 #include "tabmanagerwidget.h"
21 #include "abstractbuttoninterface.h"
22 #include "browserwindow.h"
23 #include "tabwidget.h"
24 #include "mainapplication.h"
25 #include "tabbar.h"
26 #include "statusbar.h"
27 #include "navigationbar.h"
28 
29 #include <QDesktopWidget>
30 #include <QAction>
31 #include <QStyle>
32 
33 #include <QDebug>
34 
35 class TabManagerButton : public AbstractButtonInterface
36 {
37     Q_OBJECT
38 public:
TabManagerButton(QObject * parent=nullptr)39     explicit TabManagerButton(QObject *parent = nullptr)
40         : AbstractButtonInterface(parent)
41     {
42     }
43 
id() const44     QString id() const override
45     {
46         return QSL("tabmanager-icon");
47     }
48 
name() const49     QString name() const override
50     {
51         return tr("Tab Manager button");
52     }
53 };
54 
55 
TabManagerWidgetController(QObject * parent)56 TabManagerWidgetController::TabManagerWidgetController(QObject* parent)
57     : SideBarInterface(parent)
58     , m_defaultTabManager(0)
59     , m_groupType(TabManagerWidget::GroupByWindow)
60 {
61 }
62 
~TabManagerWidgetController()63 TabManagerWidgetController::~TabManagerWidgetController()
64 {
65 }
66 
title() const67 QString TabManagerWidgetController::title() const
68 {
69     return tr("Tab Manager");
70 }
71 
createMenuAction()72 QAction* TabManagerWidgetController::createMenuAction()
73 {
74     QAction* act = new QAction(tr("Tab Manager"), this);
75     act->setCheckable(true);
76     act->setIcon(QIcon(":tabmanager/data/tabmanager.png"));
77     act->setShortcut(QKeySequence("Ctrl+Shift+M"));
78     act->setData("TabManager");
79 
80     return act;
81 }
82 
createSideBarWidget(BrowserWindow * mainWindow)83 QWidget* TabManagerWidgetController::createSideBarWidget(BrowserWindow* mainWindow)
84 {
85     return createTabManagerWidget(mainWindow, mainWindow);
86 }
87 
createStatusBarIcon(BrowserWindow * mainWindow)88 AbstractButtonInterface* TabManagerWidgetController::createStatusBarIcon(BrowserWindow* mainWindow)
89 {
90     if (!defaultTabManager()) {
91         return 0;
92     }
93 
94     if (m_statusBarIcons.contains(mainWindow)) {
95         return m_statusBarIcons.value(mainWindow);
96     }
97 
98     TabManagerButton* icon = new TabManagerButton(this);
99     icon->setIcon(QPixmap(":tabmanager/data/tabmanager.png"));
100     icon->setTitle(tr("Tab Manager"));
101     icon->setToolTip(tr("Show Tab Manager"));
102     connect(icon, &AbstractButtonInterface::clicked, this, [=](AbstractButtonInterface::ClickController *c) {
103         if (!defaultTabManager()) {
104             return;
105         }
106 
107         static int frameWidth = (defaultTabManager()->frameGeometry().width() - defaultTabManager()->geometry().width()) / 2;
108         static int titleBarHeight = defaultTabManager()->style()->pixelMetric(QStyle::PM_TitleBarHeight);
109 
110         QSize newSize(defaultTabManager()->width(), mainWindow->height() - titleBarHeight - frameWidth);
111         QRect newGeo(c->popupPosition(newSize), newSize);
112         defaultTabManager()->setGeometry(newGeo);
113         raiseTabManager();
114 
115         QTimer::singleShot(0, this, [=]() {
116             c->popupClosed();
117         });
118     });
119 
120     QAction* showAction = createMenuAction();
121     showAction->setCheckable(false);
122     showAction->setParent(icon);
123     mainWindow->addAction(showAction);
124     connect(showAction, SIGNAL(triggered()), this, SLOT(raiseTabManager()));
125 
126     m_statusBarIcons.insert(mainWindow, icon);
127     m_actions.insert(mainWindow, showAction);
128 
129     return icon;
130 }
131 
groupType()132 TabManagerWidget::GroupType TabManagerWidgetController::groupType()
133 {
134     return m_groupType;
135 }
136 
setGroupType(TabManagerWidget::GroupType type)137 void TabManagerWidgetController::setGroupType(TabManagerWidget::GroupType type)
138 {
139     m_groupType = type;
140 }
141 
createTabManagerWidget(BrowserWindow * mainClass,QWidget * parent,bool defaultWidget)142 TabManagerWidget* TabManagerWidgetController::createTabManagerWidget(BrowserWindow* mainClass, QWidget* parent, bool defaultWidget)
143 {
144     TabManagerWidget* tabManagerWidget = new TabManagerWidget(mainClass, parent, defaultWidget);
145     tabManagerWidget->setGroupType(m_groupType);
146 
147     if (defaultWidget) {
148         m_defaultTabManager = tabManagerWidget;
149         QAction* showAction = createMenuAction();
150         showAction->setCheckable(false);
151         showAction->setParent(m_defaultTabManager);
152         m_defaultTabManager->addAction(showAction);
153         connect(showAction, SIGNAL(triggered()), this, SLOT(raiseTabManager()));
154         connect(tabManagerWidget, SIGNAL(showSideBySide()), this, SLOT(showSideBySide()));
155     }
156     else {
157         m_defaultTabManager = 0;
158     }
159 
160     connect(tabManagerWidget, SIGNAL(groupTypeChanged(TabManagerWidget::GroupType)), this, SLOT(setGroupType(TabManagerWidget::GroupType)));
161     connect(this, SIGNAL(requestRefreshTree(WebPage*)), tabManagerWidget, SLOT(delayedRefreshTree(WebPage*)));
162 
163     emit requestRefreshTree();
164 
165     return tabManagerWidget;
166 }
167 
defaultTabManager()168 TabManagerWidget* TabManagerWidgetController::defaultTabManager()
169 {
170     return m_defaultTabManager;
171 }
172 
addStatusBarIcon(BrowserWindow * window)173 void TabManagerWidgetController::addStatusBarIcon(BrowserWindow* window)
174 {
175     if (window) {
176         window->statusBar()->addButton(createStatusBarIcon(window));
177         window->navigationBar()->addToolButton(createStatusBarIcon(window));
178     }
179 }
180 
removeStatusBarIcon(BrowserWindow * window)181 void TabManagerWidgetController::removeStatusBarIcon(BrowserWindow* window)
182 {
183     if (window) {
184         window->statusBar()->removeButton(m_statusBarIcons.value(window));
185         window->navigationBar()->removeToolButton(m_statusBarIcons.value(window));
186         window->removeAction(m_actions.value(window));
187         delete m_actions.value(window);
188         delete m_statusBarIcons.value(window);
189         m_statusBarIcons.remove(window);
190         m_actions.remove(window);
191     }
192 }
193 
mainWindowDeleted(BrowserWindow * window)194 void TabManagerWidgetController::mainWindowDeleted(BrowserWindow* window)
195 {
196     removeStatusBarIcon(window);
197 
198     emit requestRefreshTree();
199 }
200 
raiseTabManager()201 void TabManagerWidgetController::raiseTabManager()
202 {
203     if (!defaultTabManager()) {
204         return;
205     }
206 
207     defaultTabManager()->activateWindow();
208     defaultTabManager()->showNormal();
209     defaultTabManager()->raise();
210 }
211 
showSideBySide()212 void TabManagerWidgetController::showSideBySide()
213 {
214     if (!defaultTabManager()) {
215         return;
216     }
217     const QRect &availableGeometry = mApp->desktop()->availableGeometry(defaultTabManager());
218     static int frameWidth = (defaultTabManager()->frameGeometry().width() - defaultTabManager()->geometry().width()) / 2;
219     static int titleBarHeight = defaultTabManager()->style()->pixelMetric(QStyle::PM_TitleBarHeight);
220 
221     QRect managerRect(availableGeometry.left() + frameWidth, availableGeometry.top() + titleBarHeight,
222                       defaultTabManager()->width(), availableGeometry.height() - titleBarHeight - frameWidth);
223     QRect windowRect(managerRect.topRight().x() + 2 * frameWidth, managerRect.top(),
224                        availableGeometry.width() - managerRect.width() - 4 * frameWidth, managerRect.height());
225 
226     defaultTabManager()->setGeometry(managerRect);
227     mApp->getWindow()->setGeometry(windowRect);
228     mApp->getWindow()->showNormal();
229     mApp->getWindow()->raise();
230 
231     defaultTabManager()->show();
232     defaultTabManager()->activateWindow();
233     defaultTabManager()->raise();
234 }
235 
emitRefreshTree()236 void TabManagerWidgetController::emitRefreshTree()
237 {
238     emit requestRefreshTree();
239 }
240 
241 #include "tabmanagerwidgetcontroller.moc"
242