File indexing completed on 2024-05-12 04:57:57
0001 /* ============================================================ 0002 * Falkon - Qt web browser 0003 * Copyright (C) 2010-2014 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 "bookmarksmanager.h" 0019 #include "ui_bookmarksmanager.h" 0020 #include "bookmarksmodel.h" 0021 #include "bookmarkstools.h" 0022 #include "bookmarkitem.h" 0023 #include "bookmarks.h" 0024 #include "mainapplication.h" 0025 #include "browserwindow.h" 0026 #include "iconprovider.h" 0027 #include "qztools.h" 0028 0029 #include <QMenu> 0030 #include <QTimer> 0031 0032 BookmarksManager::BookmarksManager(BrowserWindow* window, QWidget* parent) 0033 : QWidget(parent) 0034 , ui(new Ui::BookmarksManager) 0035 , m_window(window) 0036 , m_bookmarks(mApp->bookmarks()) 0037 , m_selectedBookmark(nullptr) 0038 , m_blockDescriptionChangedSignal(false) 0039 , m_adjustHeaderSizesOnShow(true) 0040 { 0041 ui->setupUi(this); 0042 ui->tree->setViewType(BookmarksTreeView::BookmarksManagerViewType); 0043 0044 connect(ui->tree, &BookmarksTreeView::bookmarkActivated, this, &BookmarksManager::bookmarkActivated); 0045 connect(ui->tree, &BookmarksTreeView::bookmarkCtrlActivated, this, &BookmarksManager::bookmarkCtrlActivated); 0046 connect(ui->tree, &BookmarksTreeView::bookmarkShiftActivated, this, &BookmarksManager::bookmarkShiftActivated); 0047 connect(ui->tree, SIGNAL(bookmarksSelected(QList<BookmarkItem*>)), this, SLOT(bookmarksSelected(QList<BookmarkItem*>))); 0048 connect(ui->tree, &BookmarksTreeView::contextMenuRequested, this, &BookmarksManager::createContextMenu); 0049 0050 // Box for editing bookmarks 0051 updateEditBox(nullptr); 0052 connect(ui->title, &QLineEdit::textEdited, this, &BookmarksManager::bookmarkEdited); 0053 connect(ui->address, &QLineEdit::textEdited, this, &BookmarksManager::bookmarkEdited); 0054 connect(ui->keyword, &QLineEdit::textEdited, this, &BookmarksManager::bookmarkEdited); 0055 connect(ui->description, &QPlainTextEdit::textChanged, this, &BookmarksManager::descriptionEdited); 0056 } 0057 0058 BookmarksManager::~BookmarksManager() 0059 { 0060 delete ui; 0061 } 0062 0063 void BookmarksManager::setMainWindow(BrowserWindow* window) 0064 { 0065 if (window) { 0066 m_window = window; 0067 } 0068 } 0069 0070 void BookmarksManager::search(const QString &string) 0071 { 0072 ui->tree->search(string); 0073 } 0074 0075 void BookmarksManager::bookmarkActivated(BookmarkItem* item) 0076 { 0077 openBookmark(item); 0078 } 0079 0080 void BookmarksManager::bookmarkCtrlActivated(BookmarkItem* item) 0081 { 0082 openBookmarkInNewTab(item); 0083 } 0084 0085 void BookmarksManager::bookmarkShiftActivated(BookmarkItem* item) 0086 { 0087 openBookmarkInNewWindow(item); 0088 } 0089 0090 void BookmarksManager::bookmarksSelected(const QList<BookmarkItem*> &items) 0091 { 0092 if (items.size() != 1) { 0093 m_selectedBookmark = nullptr; 0094 updateEditBox(nullptr); 0095 } 0096 else { 0097 m_selectedBookmark = items.at(0); 0098 updateEditBox(m_selectedBookmark); 0099 } 0100 } 0101 0102 void BookmarksManager::createContextMenu(const QPoint &pos) 0103 { 0104 QMenu menu; 0105 QAction* actNewTab = menu.addAction(IconProvider::newTabIcon(), tr("Open in new tab")); 0106 QAction* actNewWindow = menu.addAction(IconProvider::newWindowIcon(), tr("Open in new window")); 0107 QAction* actNewPrivateWindow = menu.addAction(IconProvider::privateBrowsingIcon(), tr("Open in new private window")); 0108 0109 menu.addSeparator(); 0110 QAction *actNewBookmark = menu.addAction(tr("New Bookmark"), this, SLOT(addBookmark())); 0111 QAction *actNewFolder = menu.addAction(tr("New Folder"), this, &BookmarksManager::addFolder); 0112 QAction *actNewSeparator = menu.addAction(tr("New Separator"), this, &BookmarksManager::addSeparator); 0113 menu.addSeparator(); 0114 QAction* actDelete = menu.addAction(QIcon::fromTheme(QSL("edit-delete")), tr("Delete")); 0115 0116 connect(actNewTab, SIGNAL(triggered()), this, SLOT(openBookmarkInNewTab())); 0117 connect(actNewWindow, SIGNAL(triggered()), this, SLOT(openBookmarkInNewWindow())); 0118 connect(actNewPrivateWindow, SIGNAL(triggered()), this, SLOT(openBookmarkInNewPrivateWindow())); 0119 connect(actDelete, &QAction::triggered, this, &BookmarksManager::deleteBookmarks); 0120 0121 bool canBeDeleted = false; 0122 const QList<BookmarkItem*> items = ui->tree->selectedBookmarks(); 0123 0124 for (BookmarkItem* item : items) { 0125 if (m_bookmarks->canBeModified(item)) { 0126 canBeDeleted = true; 0127 break; 0128 } 0129 } 0130 0131 if (!canBeDeleted) { 0132 actDelete->setDisabled(true); 0133 } 0134 0135 if (!m_selectedBookmark || !m_selectedBookmark->isUrl()) { 0136 actNewTab->setDisabled(true); 0137 actNewWindow->setDisabled(true); 0138 actNewPrivateWindow->setDisabled(true); 0139 } 0140 0141 if (!m_selectedBookmark) { 0142 actNewBookmark->setDisabled(true); 0143 actNewFolder->setDisabled(true); 0144 actNewSeparator->setDisabled(true); 0145 } 0146 0147 menu.exec(pos); 0148 } 0149 0150 void BookmarksManager::openBookmark(BookmarkItem* item) 0151 { 0152 item = item ? item : m_selectedBookmark; 0153 BookmarksTools::openBookmark(getWindow(), item); 0154 } 0155 0156 void BookmarksManager::openBookmarkInNewTab(BookmarkItem* item) 0157 { 0158 item = item ? item : m_selectedBookmark; 0159 BookmarksTools::openBookmarkInNewTab(getWindow(), item); 0160 } 0161 0162 void BookmarksManager::openBookmarkInNewWindow(BookmarkItem* item) 0163 { 0164 item = item ? item : m_selectedBookmark; 0165 BookmarksTools::openBookmarkInNewWindow(item); 0166 } 0167 0168 void BookmarksManager::openBookmarkInNewPrivateWindow(BookmarkItem* item) 0169 { 0170 item = item ? item : m_selectedBookmark; 0171 BookmarksTools::openBookmarkInNewPrivateWindow(item); 0172 } 0173 0174 void BookmarksManager::addBookmark() 0175 { 0176 auto* item = new BookmarkItem(BookmarkItem::Url); 0177 item->setTitle(tr("New Bookmark")); 0178 item->setUrl(QUrl(QSL("http://"))); 0179 addBookmark(item); 0180 } 0181 0182 void BookmarksManager::addFolder() 0183 { 0184 auto* item = new BookmarkItem(BookmarkItem::Folder); 0185 item->setTitle(tr("New Folder")); 0186 addBookmark(item); 0187 } 0188 0189 void BookmarksManager::addSeparator() 0190 { 0191 auto* item = new BookmarkItem(BookmarkItem::Separator); 0192 addBookmark(item); 0193 } 0194 0195 void BookmarksManager::deleteBookmarks() 0196 { 0197 const QList<BookmarkItem*> items = ui->tree->selectedBookmarks(); 0198 0199 for (BookmarkItem* item : items) { 0200 if (m_bookmarks->canBeModified(item)) { 0201 m_bookmarks->removeBookmark(item); 0202 } 0203 } 0204 } 0205 0206 void BookmarksManager::bookmarkEdited() 0207 { 0208 Q_ASSERT(ui->tree->selectedBookmarks().count() == 1); 0209 0210 BookmarkItem* item = ui->tree->selectedBookmarks().at(0); 0211 item->setTitle(ui->title->text()); 0212 item->setUrl(QUrl::fromEncoded(ui->address->text().toUtf8())); 0213 item->setKeyword(ui->keyword->text()); 0214 item->setDescription(ui->description->toPlainText()); 0215 0216 m_bookmarks->changeBookmark(item); 0217 } 0218 0219 void BookmarksManager::descriptionEdited() 0220 { 0221 // There is no textEdited() signal in QPlainTextEdit 0222 // textChanged() is emitted also when text is changed programatically 0223 if (!m_blockDescriptionChangedSignal) { 0224 bookmarkEdited(); 0225 } 0226 } 0227 0228 void BookmarksManager::enableUpdates() 0229 { 0230 setUpdatesEnabled(true); 0231 } 0232 0233 void BookmarksManager::updateEditBox(BookmarkItem* item) 0234 { 0235 setUpdatesEnabled(false); 0236 m_blockDescriptionChangedSignal = true; 0237 0238 bool editable = bookmarkEditable(item); 0239 bool showAddressAndKeyword = item && item->isUrl(); 0240 0241 if (!item) { 0242 ui->title->clear(); 0243 ui->address->clear(); 0244 ui->keyword->clear(); 0245 ui->description->clear(); 0246 } 0247 else { 0248 ui->title->setText(item->title()); 0249 ui->address->setText(QString::fromUtf8(item->url().toEncoded())); 0250 ui->keyword->setText(item->keyword()); 0251 ui->description->setPlainText(item->description()); 0252 0253 ui->title->setCursorPosition(0); 0254 ui->address->setCursorPosition(0); 0255 ui->keyword->setCursorPosition(0); 0256 ui->description->moveCursor(QTextCursor::Start); 0257 } 0258 0259 ui->title->setReadOnly(!editable); 0260 ui->address->setReadOnly(!editable); 0261 ui->keyword->setReadOnly(!editable); 0262 ui->description->setReadOnly(!editable); 0263 0264 ui->labelAddress->setVisible(showAddressAndKeyword); 0265 ui->address->setVisible(showAddressAndKeyword); 0266 ui->labelKeyword->setVisible(showAddressAndKeyword); 0267 ui->keyword->setVisible(showAddressAndKeyword); 0268 0269 // Without removing widgets from layout, there is unwanted extra spacing 0270 auto* l = static_cast<QFormLayout*>(ui->editBox->layout()); 0271 0272 if (showAddressAndKeyword) { 0273 // Show Address + Keyword 0274 l->insertRow(1, ui->labelAddress, ui->address); 0275 l->insertRow(2, ui->labelKeyword, ui->keyword); 0276 } 0277 else { 0278 // Hide Address + Keyword 0279 l->removeWidget(ui->labelAddress); 0280 l->removeWidget(ui->labelKeyword); 0281 l->removeWidget(ui->address); 0282 l->removeWidget(ui->keyword); 0283 } 0284 0285 m_blockDescriptionChangedSignal = false; 0286 0287 // Prevent flickering 0288 QTimer::singleShot(10, this, &BookmarksManager::enableUpdates); 0289 } 0290 0291 bool BookmarksManager::bookmarkEditable(BookmarkItem* item) const 0292 { 0293 return item && (item->isFolder() || item->isUrl()) && m_bookmarks->canBeModified(item); 0294 } 0295 0296 void BookmarksManager::addBookmark(BookmarkItem* item) 0297 { 0298 BookmarkItem* parent = parentForNewBookmark(); 0299 Q_ASSERT(parent); 0300 0301 int row = 0; 0302 if (m_selectedBookmark->isUrl() || m_selectedBookmark->isSeparator()) { 0303 row = m_bookmarks->model()->index(m_selectedBookmark).row(); 0304 } 0305 m_bookmarks->insertBookmark(parent, row, item); 0306 0307 // Select newly added bookmark 0308 ui->tree->selectBookmark(item); 0309 ui->tree->ensureBookmarkVisible(item); 0310 0311 // Start editing title 0312 if (!item->isSeparator()) { 0313 ui->title->setFocus(); 0314 ui->title->selectAll(); 0315 } 0316 } 0317 0318 BookmarkItem* BookmarksManager::parentForNewBookmark() const 0319 { 0320 if (m_selectedBookmark && m_selectedBookmark->isFolder()) { 0321 return m_selectedBookmark; 0322 } 0323 0324 if (!m_selectedBookmark || m_selectedBookmark->parent() == m_bookmarks->rootItem()) { 0325 return m_bookmarks->unsortedFolder(); 0326 } 0327 0328 return m_selectedBookmark->parent(); 0329 } 0330 0331 void BookmarksManager::keyPressEvent(QKeyEvent* event) 0332 { 0333 switch (event->key()) { 0334 case Qt::Key_Delete: 0335 deleteBookmarks(); 0336 break; 0337 } 0338 0339 QWidget::keyPressEvent(event); 0340 } 0341 0342 BrowserWindow* BookmarksManager::getWindow() 0343 { 0344 if (!m_window) { 0345 m_window = mApp->getWindow(); 0346 } 0347 return m_window.data(); 0348 } 0349 0350 void BookmarksManager::showEvent(QShowEvent* event) 0351 { 0352 QWidget::showEvent(event); 0353 0354 if (m_adjustHeaderSizesOnShow) { 0355 ui->tree->header()->resizeSection(0, ui->tree->header()->width() / 1.9); 0356 m_adjustHeaderSizesOnShow = false; 0357 } 0358 }