1 /**************************************************************************
2 * Otter Browser: Web browser controlled by the user, not vice-versa.
3 * Copyright (C) 2018 Michal Dutkiewicz aka Emdek <michal@emdek.pl>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 **************************************************************************/
19
20 #include "TabHistoryContentsWidget.h"
21 #include "../../../core/ThemesManager.h"
22 #include "../../../ui/Action.h"
23 #include "../../../ui/MainWindow.h"
24 #include "../../../ui/Window.h"
25
26 #include "ui_TabHistoryContentsWidget.h"
27
28 #include <QtWidgets/QDesktopWidget>
29 #include <QtWidgets/QToolTip>
30
31 namespace Otter
32 {
33
TabHistoryContentsWidget(const QVariantMap & parameters,QWidget * parent)34 TabHistoryContentsWidget::TabHistoryContentsWidget(const QVariantMap ¶meters, QWidget *parent) : ContentsWidget(parameters, nullptr, parent),
35 m_window(nullptr),
36 m_ui(new Ui::TabHistoryContentsWidget)
37 {
38 m_ui->setupUi(this);
39 m_ui->filterLineEditWidget->setClearOnEscape(true);
40 m_ui->historyViewWidget->setModel(new QStandardItemModel(this));
41 m_ui->historyViewWidget->viewport()->installEventFilter(this);
42 m_ui->historyViewWidget->viewport()->setMouseTracking(true);
43
44 const MainWindow *mainWindow(MainWindow::findMainWindow(parentWidget()));
45
46 if (mainWindow)
47 {
48 m_window = mainWindow->getActiveWindow();
49
50 connect(mainWindow, &MainWindow::currentWindowChanged, this, [=]()
51 {
52 Window *window(mainWindow->getActiveWindow());
53
54 if (window != m_window)
55 {
56 if (m_window)
57 {
58 disconnect(m_window, &Window::loadingStateChanged, this, &TabHistoryContentsWidget::updateHistory);
59 }
60
61 m_window = window;
62
63 if (window)
64 {
65 connect(window, &Window::loadingStateChanged, this, &TabHistoryContentsWidget::updateHistory);
66 }
67 }
68
69 updateHistory();
70 });
71 }
72
73 updateHistory();
74
75 connect(m_ui->filterLineEditWidget, &LineEditWidget::textChanged, m_ui->historyViewWidget, &ItemViewWidget::setFilterString);
76 connect(m_ui->historyViewWidget, &ItemViewWidget::customContextMenuRequested, this, &TabHistoryContentsWidget::showContextMenu);
77 connect(m_ui->historyViewWidget, &ItemViewWidget::clicked, [&](const QModelIndex &index)
78 {
79 if (m_window && m_window->getWebWidget())
80 {
81 m_window->triggerAction(ActionsManager::GoToHistoryIndexAction, {{QLatin1String("index"), index.row()}});
82 }
83 });
84 }
85
~TabHistoryContentsWidget()86 TabHistoryContentsWidget::~TabHistoryContentsWidget()
87 {
88 delete m_ui;
89 }
90
changeEvent(QEvent * event)91 void TabHistoryContentsWidget::changeEvent(QEvent *event)
92 {
93 ContentsWidget::changeEvent(event);
94
95 if (event->type() == QEvent::LanguageChange)
96 {
97 m_ui->retranslateUi(this);
98 }
99 }
100
updateHistory()101 void TabHistoryContentsWidget::updateHistory()
102 {
103 if (m_window)
104 {
105 const WindowHistoryInformation history(m_window->getHistory());
106
107 m_ui->historyViewWidget->getSourceModel()->clear();
108
109 for (int i = 0; i < history.entries.count(); ++i)
110 {
111 QStandardItem *item(new QStandardItem(history.entries.at(i).getTitle()));
112 item->setData((history.entries.at(i).icon.isNull() ? ThemesManager::createIcon(QLatin1String("text-html")) : history.entries.at(i).icon), Qt::DecorationRole);
113 item->setData(history.entries.at(i).url, UrlRole);
114 item->setData(history.entries.at(i).time, TimeVisitedRole);
115 item->setFlags(item->flags() | Qt::ItemNeverHasChildren);
116
117 if (i == history.index)
118 {
119 QFont font(item->font());
120 font.setBold(true);
121
122 item->setFont(font);
123 }
124
125 m_ui->historyViewWidget->getSourceModel()->appendRow(item);
126 }
127 }
128 else
129 {
130 m_ui->historyViewWidget->getSourceModel()->clear();
131 }
132 }
133
showContextMenu(const QPoint & position)134 void TabHistoryContentsWidget::showContextMenu(const QPoint &position)
135 {
136 const QModelIndex index(m_ui->historyViewWidget->indexAt(position));
137 ActionExecutor::Object executor(m_window, m_window);
138 QMenu menu(this);
139
140 if (index.isValid())
141 {
142 menu.addAction(new Action(ActionsManager::GoToHistoryIndexAction, {{QLatin1String("index"), index.row()}}, {{QLatin1String("icon"), {}}, {QLatin1String("text"), QCoreApplication::translate("actions", "Go to History Entry")}}, executor, &menu));
143 menu.addSeparator();
144 menu.addAction(new Action(ActionsManager::RemoveHistoryIndexAction, {{QLatin1String("index"), index.row()}}, executor, &menu));
145 menu.addAction(new Action(ActionsManager::RemoveHistoryIndexAction, {{QLatin1String("index"), index.row()}, {QLatin1String("clearGlobalHistory"), true}}, executor, &menu));
146 menu.addSeparator();
147 }
148
149 menu.addAction(new Action(ActionsManager::ClearTabHistoryAction, {}, executor, &menu));
150 menu.addAction(new Action(ActionsManager::ClearTabHistoryAction, {{QLatin1String("clearGlobalHistory"), true}}, {{QLatin1String("text"), QT_TRANSLATE_NOOP("actions", "Purge Tab History")}}, executor, &menu));
151 menu.exec(m_ui->historyViewWidget->mapToGlobal(position));
152 }
153
getTitle() const154 QString TabHistoryContentsWidget::getTitle() const
155 {
156 return tr("Tab History");
157 }
158
getType() const159 QLatin1String TabHistoryContentsWidget::getType() const
160 {
161 return QLatin1String("tabHistory");
162 }
163
getUrl() const164 QUrl TabHistoryContentsWidget::getUrl() const
165 {
166 return {};
167 }
168
getIcon() const169 QIcon TabHistoryContentsWidget::getIcon() const
170 {
171 return ThemesManager::createIcon(QLatin1String("tab-history"), false);
172 }
173
eventFilter(QObject * object,QEvent * event)174 bool TabHistoryContentsWidget::eventFilter(QObject *object, QEvent *event)
175 {
176 if (object == m_ui->historyViewWidget->viewport() && event->type() == QEvent::ToolTip)
177 {
178 const QHelpEvent *helpEvent(static_cast<QHelpEvent*>(event));
179 const QModelIndex index(m_ui->historyViewWidget->indexAt(helpEvent->pos()));
180 QString toolTip;
181
182 if (index.isValid())
183 {
184 toolTip = tr("Title: %1").arg(index.data(TitleRole).toString()) + QLatin1Char('\n') + tr("Address: %1").arg(index.data(UrlRole).toUrl().toDisplayString());
185
186 if (!index.data(TimeVisitedRole).isNull())
187 {
188 toolTip.append(QLatin1Char('\n') + tr("Date: %1").arg(Utils::formatDateTime(index.data(TimeVisitedRole).toDateTime())));
189 }
190 }
191
192 QToolTip::showText(helpEvent->globalPos(), QFontMetrics(QToolTip::font()).elidedText(toolTip, Qt::ElideRight, (QApplication::desktop()->screenGeometry(m_ui->historyViewWidget).width() / 2)), m_ui->historyViewWidget, m_ui->historyViewWidget->visualRect(index));
193
194 return true;
195 }
196
197 return ContentsWidget::eventFilter(object, event);
198 }
199
200 }
201