Falkon Develop
Cross-platform Qt-based web browser
bookmarksmanager.cpp
Go to the documentation of this file.
1/* ============================================================
2* Falkon - Qt web browser
3* Copyright (C) 2010-2014 David Rosca <nowrep@gmail.com>
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#include "bookmarksmanager.h"
19#include "ui_bookmarksmanager.h"
20#include "bookmarksmodel.h"
21#include "bookmarkstools.h"
22#include "bookmarkitem.h"
23#include "bookmarks.h"
24#include "mainapplication.h"
25#include "browserwindow.h"
26#include "iconprovider.h"
27#include "qztools.h"
28
29#include <QMenu>
30#include <QTimer>
31
33 : QWidget(parent)
34 , ui(new Ui::BookmarksManager)
35 , m_window(window)
36 , m_bookmarks(mApp->bookmarks())
37 , m_selectedBookmark(nullptr)
38 , m_blockDescriptionChangedSignal(false)
39 , m_adjustHeaderSizesOnShow(true)
40{
41 ui->setupUi(this);
43
44 connect(ui->tree, &BookmarksTreeView::bookmarkActivated, this, &BookmarksManager::bookmarkActivated);
45 connect(ui->tree, &BookmarksTreeView::bookmarkCtrlActivated, this, &BookmarksManager::bookmarkCtrlActivated);
46 connect(ui->tree, &BookmarksTreeView::bookmarkShiftActivated, this, &BookmarksManager::bookmarkShiftActivated);
47 connect(ui->tree, SIGNAL(bookmarksSelected(QList<BookmarkItem*>)), this, SLOT(bookmarksSelected(QList<BookmarkItem*>)));
48 connect(ui->tree, &BookmarksTreeView::contextMenuRequested, this, &BookmarksManager::createContextMenu);
49
50 // Box for editing bookmarks
51 updateEditBox(nullptr);
52 connect(ui->title, &QLineEdit::textEdited, this, &BookmarksManager::bookmarkEdited);
53 connect(ui->address, &QLineEdit::textEdited, this, &BookmarksManager::bookmarkEdited);
54 connect(ui->keyword, &QLineEdit::textEdited, this, &BookmarksManager::bookmarkEdited);
55 connect(ui->description, &QPlainTextEdit::textChanged, this, &BookmarksManager::descriptionEdited);
56}
57
59{
60 delete ui;
61}
62
64{
65 if (window) {
66 m_window = window;
67 }
68}
69
70void BookmarksManager::search(const QString &string)
71{
72 ui->tree->search(string);
73}
74
75void BookmarksManager::bookmarkActivated(BookmarkItem* item)
76{
77 openBookmark(item);
78}
79
80void BookmarksManager::bookmarkCtrlActivated(BookmarkItem* item)
81{
82 openBookmarkInNewTab(item);
83}
84
85void BookmarksManager::bookmarkShiftActivated(BookmarkItem* item)
86{
87 openBookmarkInNewWindow(item);
88}
89
90void BookmarksManager::bookmarksSelected(const QList<BookmarkItem*> &items)
91{
92 if (items.size() != 1) {
93 m_selectedBookmark = nullptr;
94 updateEditBox(nullptr);
95 }
96 else {
97 m_selectedBookmark = items.at(0);
98 updateEditBox(m_selectedBookmark);
99 }
100}
101
102void BookmarksManager::createContextMenu(const QPoint &pos)
103{
104 QMenu menu;
105 QAction* actNewTab = menu.addAction(IconProvider::newTabIcon(), tr("Open in new tab"));
106 QAction* actNewWindow = menu.addAction(IconProvider::newWindowIcon(), tr("Open in new window"));
107 QAction* actNewPrivateWindow = menu.addAction(IconProvider::privateBrowsingIcon(), tr("Open in new private window"));
108
109 menu.addSeparator();
110 QAction *actNewBookmark = menu.addAction(tr("New Bookmark"), this, SLOT(addBookmark()));
111 QAction *actNewFolder = menu.addAction(tr("New Folder"), this, &BookmarksManager::addFolder);
112 QAction *actNewSeparator = menu.addAction(tr("New Separator"), this, &BookmarksManager::addSeparator);
113 menu.addSeparator();
114 QAction* actDelete = menu.addAction(QIcon::fromTheme(QSL("edit-delete")), tr("Delete"));
115
116 connect(actNewTab, SIGNAL(triggered()), this, SLOT(openBookmarkInNewTab()));
117 connect(actNewWindow, SIGNAL(triggered()), this, SLOT(openBookmarkInNewWindow()));
118 connect(actNewPrivateWindow, SIGNAL(triggered()), this, SLOT(openBookmarkInNewPrivateWindow()));
119 connect(actDelete, &QAction::triggered, this, &BookmarksManager::deleteBookmarks);
120
121 bool canBeDeleted = false;
122 const QList<BookmarkItem*> items = ui->tree->selectedBookmarks();
123
124 for (BookmarkItem* item : items) {
125 if (m_bookmarks->canBeModified(item)) {
126 canBeDeleted = true;
127 break;
128 }
129 }
130
131 if (!canBeDeleted) {
132 actDelete->setDisabled(true);
133 }
134
135 if (!m_selectedBookmark || !m_selectedBookmark->isUrl()) {
136 actNewTab->setDisabled(true);
137 actNewWindow->setDisabled(true);
138 actNewPrivateWindow->setDisabled(true);
139 }
140
141 if (!m_selectedBookmark) {
142 actNewBookmark->setDisabled(true);
143 actNewFolder->setDisabled(true);
144 actNewSeparator->setDisabled(true);
145 }
146
147 menu.exec(pos);
148}
149
150void BookmarksManager::openBookmark(BookmarkItem* item)
151{
152 item = item ? item : m_selectedBookmark;
153 BookmarksTools::openBookmark(getWindow(), item);
154}
155
156void BookmarksManager::openBookmarkInNewTab(BookmarkItem* item)
157{
158 item = item ? item : m_selectedBookmark;
159 BookmarksTools::openBookmarkInNewTab(getWindow(), item);
160}
161
162void BookmarksManager::openBookmarkInNewWindow(BookmarkItem* item)
163{
164 item = item ? item : m_selectedBookmark;
166}
167
168void BookmarksManager::openBookmarkInNewPrivateWindow(BookmarkItem* item)
169{
170 item = item ? item : m_selectedBookmark;
172}
173
174void BookmarksManager::addBookmark()
175{
176 auto* item = new BookmarkItem(BookmarkItem::Url);
177 item->setTitle(tr("New Bookmark"));
178 item->setUrl(QUrl(QSL("http://")));
179 addBookmark(item);
180}
181
182void BookmarksManager::addFolder()
183{
184 auto* item = new BookmarkItem(BookmarkItem::Folder);
185 item->setTitle(tr("New Folder"));
186 addBookmark(item);
187}
188
189void BookmarksManager::addSeparator()
190{
191 auto* item = new BookmarkItem(BookmarkItem::Separator);
192 addBookmark(item);
193}
194
195void BookmarksManager::deleteBookmarks()
196{
197 const QList<BookmarkItem*> items = ui->tree->selectedBookmarks();
198
199 for (BookmarkItem* item : items) {
200 if (m_bookmarks->canBeModified(item)) {
201 m_bookmarks->removeBookmark(item);
202 }
203 }
204}
205
206void BookmarksManager::bookmarkEdited()
207{
208 Q_ASSERT(ui->tree->selectedBookmarks().count() == 1);
209
210 BookmarkItem* item = ui->tree->selectedBookmarks().at(0);
211 item->setTitle(ui->title->text());
212 item->setUrl(QUrl::fromEncoded(ui->address->text().toUtf8()));
213 item->setKeyword(ui->keyword->text());
214 item->setDescription(ui->description->toPlainText());
215
216 m_bookmarks->changeBookmark(item);
217}
218
219void BookmarksManager::descriptionEdited()
220{
221 // There is no textEdited() signal in QPlainTextEdit
222 // textChanged() is emitted also when text is changed programatically
223 if (!m_blockDescriptionChangedSignal) {
224 bookmarkEdited();
225 }
226}
227
228void BookmarksManager::enableUpdates()
229{
230 setUpdatesEnabled(true);
231}
232
233void BookmarksManager::updateEditBox(BookmarkItem* item)
234{
235 setUpdatesEnabled(false);
236 m_blockDescriptionChangedSignal = true;
237
238 bool editable = bookmarkEditable(item);
239 bool showAddressAndKeyword = item && item->isUrl();
240
241 if (!item) {
242 ui->title->clear();
243 ui->address->clear();
244 ui->keyword->clear();
245 ui->description->clear();
246 }
247 else {
248 ui->title->setText(item->title());
249 ui->address->setText(QString::fromUtf8(item->url().toEncoded()));
250 ui->keyword->setText(item->keyword());
251 ui->description->setPlainText(item->description());
252
253 ui->title->setCursorPosition(0);
254 ui->address->setCursorPosition(0);
255 ui->keyword->setCursorPosition(0);
256 ui->description->moveCursor(QTextCursor::Start);
257 }
258
259 ui->title->setReadOnly(!editable);
260 ui->address->setReadOnly(!editable);
261 ui->keyword->setReadOnly(!editable);
262 ui->description->setReadOnly(!editable);
263
264 ui->labelAddress->setVisible(showAddressAndKeyword);
265 ui->address->setVisible(showAddressAndKeyword);
266 ui->labelKeyword->setVisible(showAddressAndKeyword);
267 ui->keyword->setVisible(showAddressAndKeyword);
268
269 // Without removing widgets from layout, there is unwanted extra spacing
270 auto* l = static_cast<QFormLayout*>(ui->editBox->layout());
271
272 if (showAddressAndKeyword) {
273 // Show Address + Keyword
274 l->insertRow(1, ui->labelAddress, ui->address);
275 l->insertRow(2, ui->labelKeyword, ui->keyword);
276 }
277 else {
278 // Hide Address + Keyword
279 l->removeWidget(ui->labelAddress);
280 l->removeWidget(ui->labelKeyword);
281 l->removeWidget(ui->address);
282 l->removeWidget(ui->keyword);
283 }
284
285 m_blockDescriptionChangedSignal = false;
286
287 // Prevent flickering
288 QTimer::singleShot(10, this, &BookmarksManager::enableUpdates);
289}
290
291bool BookmarksManager::bookmarkEditable(BookmarkItem* item) const
292{
293 return item && (item->isFolder() || item->isUrl()) && m_bookmarks->canBeModified(item);
294}
295
296void BookmarksManager::addBookmark(BookmarkItem* item)
297{
298 BookmarkItem* parent = parentForNewBookmark();
299 Q_ASSERT(parent);
300
301 int row = 0;
302 if (m_selectedBookmark->isUrl() || m_selectedBookmark->isSeparator()) {
303 row = m_bookmarks->model()->index(m_selectedBookmark).row();
304 }
305 m_bookmarks->insertBookmark(parent, row, item);
306
307 // Select newly added bookmark
308 ui->tree->selectBookmark(item);
309 ui->tree->ensureBookmarkVisible(item);
310
311 // Start editing title
312 if (!item->isSeparator()) {
313 ui->title->setFocus();
314 ui->title->selectAll();
315 }
316}
317
318BookmarkItem* BookmarksManager::parentForNewBookmark() const
319{
320 if (m_selectedBookmark && m_selectedBookmark->isFolder()) {
321 return m_selectedBookmark;
322 }
323
324 if (!m_selectedBookmark || m_selectedBookmark->parent() == m_bookmarks->rootItem()) {
325 return m_bookmarks->unsortedFolder();
326 }
327
328 return m_selectedBookmark->parent();
329}
330
331void BookmarksManager::keyPressEvent(QKeyEvent* event)
332{
333 switch (event->key()) {
334 case Qt::Key_Delete:
335 deleteBookmarks();
336 break;
337 }
338
339 QWidget::keyPressEvent(event);
340}
341
342BrowserWindow* BookmarksManager::getWindow()
343{
344 if (!m_window) {
345 m_window = mApp->getWindow();
346 }
347 return m_window.data();
348}
349
350void BookmarksManager::showEvent(QShowEvent* event)
351{
352 QWidget::showEvent(event);
353
354 if (m_adjustHeaderSizesOnShow) {
355 ui->tree->header()->resizeSection(0, ui->tree->header()->width() / 1.9);
356 m_adjustHeaderSizesOnShow = false;
357 }
358}
QString keyword() const
bool isFolder() const
void setDescription(const QString &description)
bool isSeparator() const
QString description() const
QUrl url() const
void setKeyword(const QString &keyword)
bool isUrl() const
BookmarkItem * parent() const
QString title() const
void setUrl(const QUrl &url)
void setTitle(const QString &title)
BookmarkItem * rootItem() const
Definition: bookmarks.cpp:69
void changeBookmark(BookmarkItem *item)
Definition: bookmarks.cpp:170
BookmarkItem * unsortedFolder() const
Definition: bookmarks.cpp:84
bool canBeModified(BookmarkItem *item) const
Definition: bookmarks.cpp:104
bool removeBookmark(BookmarkItem *item)
Definition: bookmarks.cpp:157
void insertBookmark(BookmarkItem *parent, int row, BookmarkItem *item)
Definition: bookmarks.cpp:144
BookmarksModel * model() const
Definition: bookmarks.cpp:94
void setMainWindow(BrowserWindow *window)
BookmarksManager(BrowserWindow *window, QWidget *parent=nullptr)
~BookmarksManager() override
void search(const QString &string)
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
static void openBookmarkInNewTab(BrowserWindow *window, BookmarkItem *item)
static void openBookmark(BrowserWindow *window, BookmarkItem *item)
static void openBookmarkInNewPrivateWindow(BookmarkItem *item)
static void openBookmarkInNewWindow(BookmarkItem *item)
void bookmarkShiftActivated(BookmarkItem *item)
void bookmarkCtrlActivated(BookmarkItem *item)
void bookmarkActivated(BookmarkItem *item)
void contextMenuRequested(const QPoint &point)
static QIcon privateBrowsingIcon()
static QIcon newWindowIcon()
static QIcon newTabIcon()
#define mApp
#define QSL(x)
Definition: qzcommon.h:40