From a8b92f26bcd9fa5c1e77c8e8e5d6ce6f16a68bae Mon Sep 17 00:00:00 2001 From: kh1 Date: Wed, 17 Feb 2010 18:04:25 +0100 Subject: Implement bookmark manager widget. Add some more flexible approach to rename, export and import bookmarks. --- tools/assistant/tools/assistant/assistant.pro | 3 + .../assistant/tools/assistant/bookmarkmanager.cpp | 74 ++--- tools/assistant/tools/assistant/bookmarkmanager.h | 8 +- .../tools/assistant/bookmarkmanagerwidget.cpp | 321 +++++++++++++++++++++ .../tools/assistant/bookmarkmanagerwidget.h | 102 +++++++ .../tools/assistant/bookmarkmanagerwidget.ui | 137 +++++++++ tools/assistant/tools/assistant/bookmarkmodel.cpp | 12 + tools/assistant/tools/assistant/bookmarkmodel.h | 1 + 8 files changed, 606 insertions(+), 52 deletions(-) create mode 100644 tools/assistant/tools/assistant/bookmarkmanagerwidget.cpp create mode 100644 tools/assistant/tools/assistant/bookmarkmanagerwidget.h create mode 100644 tools/assistant/tools/assistant/bookmarkmanagerwidget.ui diff --git a/tools/assistant/tools/assistant/assistant.pro b/tools/assistant/tools/assistant/assistant.pro index 0733128..ff0ecc5 100644 --- a/tools/assistant/tools/assistant/assistant.pro +++ b/tools/assistant/tools/assistant/assistant.pro @@ -21,6 +21,7 @@ HEADERS += aboutdialog.h \ bookmarkfiltermodel.h \ bookmarkitem.h \ bookmarkmanager.h \ + bookmarkmanagerwidget.h \ bookmarkmodel.h \ centralwidget.h \ cmdlineparser.h \ @@ -49,6 +50,7 @@ SOURCES += aboutdialog.cpp \ bookmarkfiltermodel.cpp \ bookmarkitem.cpp \ bookmarkmanager.cpp \ + bookmarkmanagerwidget.cpp \ bookmarkmodel.cpp \ centralwidget.cpp \ cmdlineparser.cpp \ @@ -72,6 +74,7 @@ SOURCES += aboutdialog.cpp \ ../shared/collectionconfiguration.cpp \ FORMS += bookmarkdialog.ui \ + bookmarkmanagerwidget.ui \ bookmarkwidget.ui \ filternamedialog.ui \ installdialog.ui \ diff --git a/tools/assistant/tools/assistant/bookmarkmanager.cpp b/tools/assistant/tools/assistant/bookmarkmanager.cpp index 00f6346..70f562e 100644 --- a/tools/assistant/tools/assistant/bookmarkmanager.cpp +++ b/tools/assistant/tools/assistant/bookmarkmanager.cpp @@ -41,6 +41,7 @@ #include "tracer.h" #include "bookmarkmanager.h" +#include "bookmarkmanagerwidget.h" #include "bookmarkdialog.h" #include "bookmarkfiltermodel.h" #include "bookmarkitem.h" @@ -48,15 +49,11 @@ #include "centralwidget.h" #include "helpenginewrapper.h" -#include #include #include #include #include -#include -#include "xbelsupport.h" - QT_BEGIN_NAMESPACE // -- BookmarkManager::BookmarkWidget @@ -163,6 +160,7 @@ BookmarkManager::BookmarkManager() , bookmarkModel(new BookmarkModel) , bookmarkWidget(new BookmarkWidget) , bookmarkTreeView(new BookmarkTreeView) + , bookmarkManagerWidget(0) { TRACE_OBJ bookmarkWidget->installEventFilter(this); @@ -198,6 +196,7 @@ BookmarkManager::BookmarkManager() BookmarkManager::~BookmarkManager() { TRACE_OBJ + delete bookmarkManagerWidget; HelpEngineWrapper::instance().setBookmarks(bookmarkModel->bookmarks()); delete bookmarkModel; } @@ -338,10 +337,21 @@ void BookmarkManager::removeBookmark() removeItem(bookmarkTreeView->currentIndex()); } -//void BookmarkManager::manageBookmarks() -//{ -// TRACE_OBJ -//} +void BookmarkManager::manageBookmarks() +{ + TRACE_OBJ + if (bookmarkManagerWidget == 0) { + bookmarkManagerWidget = new BookmarkManagerWidget(bookmarkModel); + connect(bookmarkManagerWidget, SIGNAL(setSource(QUrl)), this, + SIGNAL(setSource(QUrl))); + connect(bookmarkManagerWidget, SIGNAL(setSourceInNewTab(QUrl)) + , this, SIGNAL(setSourceInNewTab(QUrl))); + connect(bookmarkManagerWidget, SIGNAL(managerWidgetAboutToClose()) + , this, SLOT(managerWidgetAboutToClose())); + } + bookmarkManagerWidget->show(); + bookmarkManagerWidget->raise(); +} void BookmarkManager::refeshBookmarkMenu() { @@ -351,10 +361,8 @@ void BookmarkManager::refeshBookmarkMenu() bookmarkMenu->clear(); - //bookmarkMenu->addAction(tr("Manage Bookmarks..."), this, - // SLOT(manageBookmarks())); - bookmarkMenu->addAction(tr("Import..."), this, SLOT(importBookmarks())); - bookmarkMenu->addAction(tr("Export..."), this, SLOT(exportBookmarks())); + bookmarkMenu->addAction(tr("Manage Bookmarks..."), this, + SLOT(manageBookmarks())); bookmarkMenu->addAction(tr("Add Bookmark..."), this, SLOT(addBookmark()), QKeySequence(tr("Ctrl+D"))); bookmarkMenu->addSeparator(); @@ -378,42 +386,6 @@ void BookmarkManager::renameBookmark(const QModelIndex &index) bookmarkModel->setItemsEditable(false); } -void BookmarkManager::importBookmarks() -{ - TRACE_OBJ - const QString &fileName = QFileDialog::getOpenFileName(0, tr("Open File"), - QDir::currentPath(), tr("Files (*.xbel)")); - - if (fileName.isEmpty()) - return; - - QFile file(fileName); - if (file.open(QIODevice::ReadOnly)) { - XbelReader reader(bookmarkModel); - reader.readFromFile(&file); - } -} - -void BookmarkManager::exportBookmarks() -{ - TRACE_OBJ - QString fileName = QFileDialog::getSaveFileName(0, tr("Save File"), - QLatin1String("untitled.xbel"), tr("Files (*.xbel)")); - - const QLatin1String suffix(".xbel"); - if (!fileName.endsWith(suffix)) - fileName.append(suffix); - - QFile file(fileName); - if (file.open(QIODevice::WriteOnly)) { - XbelWriter writer(bookmarkModel); - writer.writeToFile(&file); - } else { - QMessageBox::information(bookmarkTreeView, tr("Qt Assistant"), - tr("Unable to save bookmarks."), tr("OK")); - } -} - void BookmarkManager::setSourceFromAction(QAction *action) { TRACE_OBJ @@ -487,6 +459,12 @@ void BookmarkManager::focusInEvent() bookmarkTreeView->setCurrentIndex(index); } +void BookmarkManager::managerWidgetAboutToClose() +{ + delete bookmarkManagerWidget; + bookmarkManagerWidget = 0; +} + void BookmarkManager::textChanged(const QString &text) { TRACE_OBJ diff --git a/tools/assistant/tools/assistant/bookmarkmanager.h b/tools/assistant/tools/assistant/bookmarkmanager.h index 88342d5..c26dad8 100644 --- a/tools/assistant/tools/assistant/bookmarkmanager.h +++ b/tools/assistant/tools/assistant/bookmarkmanager.h @@ -48,6 +48,7 @@ QT_BEGIN_NAMESPACE +class BookmarkManagerWidget; class BookmarkModel; class BookmarkFilterModel; class QKeyEvent; @@ -90,17 +91,15 @@ private slots: void addBookmark(); void removeBookmark(); -// void manageBookmarks(); + void manageBookmarks(); void refeshBookmarkMenu(); void renameBookmark(const QModelIndex &index); - void importBookmarks(); - void exportBookmarks(); - void setSourceFromAction(QAction *action); void setSourceFromIndex(const QModelIndex &index, bool newTab = false); void focusInEvent(); + void managerWidgetAboutToClose(); void textChanged(const QString &text); void customContextMenuRequested(const QPoint &point); @@ -118,6 +117,7 @@ private: BookmarkWidget *bookmarkWidget; BookmarkTreeView *bookmarkTreeView; + BookmarkManagerWidget *bookmarkManagerWidget; }; class BookmarkManager::BookmarkWidget : public QWidget diff --git a/tools/assistant/tools/assistant/bookmarkmanagerwidget.cpp b/tools/assistant/tools/assistant/bookmarkmanagerwidget.cpp new file mode 100644 index 0000000..65df6be --- /dev/null +++ b/tools/assistant/tools/assistant/bookmarkmanagerwidget.cpp @@ -0,0 +1,321 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Assistant of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "bookmarkmanagerwidget.h" +#include "bookmarkitem.h" +#include "bookmarkmodel.h" +#include "tracer.h" +#include "xbelsupport.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +namespace { + #define TR(x) QCoreApplication::translate("BookmarkManager", x) +} + +BookmarkManagerWidget::BookmarkManagerWidget(BookmarkModel *sourceModel, + QWidget *parent) + : QWidget(parent) + , bookmarkModel(sourceModel) +{ + TRACE_OBJ + ui.setupUi(this); + + ui.treeView->setModel(bookmarkModel); + + ui.treeView->expandAll(); + ui.treeView->installEventFilter(this); + ui.treeView->viewport()->installEventFilter(this); + ui.treeView->setContextMenuPolicy(Qt::CustomContextMenu); + + connect(ui.treeView, SIGNAL(customContextMenuRequested(QPoint)), this, + SLOT(customContextMenuRequested(QPoint))); + + connect(ui.remove, SIGNAL(clicked()), this, SLOT(removeItem())); + connect(ui.lineEdit, SIGNAL(textChanged(QString)), this, + SLOT(textChanged(QString))); + new QShortcut(QKeySequence::Find, ui.lineEdit, SLOT(setFocus())); + + importExportMenu.addAction(tr("Import..."), this, SLOT(importBookmarks())); + importExportMenu.addAction(tr("Export..."), this, SLOT(exportBookmarks())); + ui.importExport->setMenu(&importExportMenu); + + new QShortcut(QKeySequence::FindNext, this, SLOT(findNext())); + new QShortcut(QKeySequence::FindPrevious, this, SLOT(findPrevious())); + + connect(bookmarkModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, + SLOT(refeshBookmarkCache())); + connect(bookmarkModel, SIGNAL(rowsInserted(QModelIndex, int, int)), this, + SLOT(refeshBookmarkCache())); + connect(bookmarkModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, + SLOT(refeshBookmarkCache())); + + ui.treeView->setCurrentIndex(ui.treeView->indexAt(QPoint(2, 2))); +} + +BookmarkManagerWidget::~BookmarkManagerWidget() +{ + TRACE_OBJ +} + +void BookmarkManagerWidget::closeEvent(QCloseEvent *event) +{ + TRACE_OBJ + event->accept(); + emit managerWidgetAboutToClose(); +} + +void BookmarkManagerWidget::renameItem(const QModelIndex &index) +{ + TRACE_OBJ + // check if we should rename the "Bookmarks Menu", bail + if (!bookmarkModel->parent(index).isValid()) + return; + + bookmarkModel->setItemsEditable(true); + ui.treeView->edit(index); + bookmarkModel->setItemsEditable(false); +} + +static int nextIndex(int current, int count, bool forward) +{ + TRACE_OBJ + if (current >= 0) + return (forward ? (current + 1) : ((current - 1) + count)) % count; + return 0; +} + +void BookmarkManagerWidget::selectNextIndex(bool direction) const +{ + QModelIndex current = ui.treeView->currentIndex(); + if (current.isValid() && !cache.isEmpty()) { + current = cache.at(nextIndex(cache.indexOf(current), cache.count(), + direction)); + } + ui.treeView->setCurrentIndex(current); +} + +bool BookmarkManagerWidget::eventFilter(QObject *object, QEvent *event) +{ + TRACE_OBJ + if (object != ui.treeView && object != ui.treeView->viewport()) + return QWidget::eventFilter(object, event); + + if (event->type() == QEvent::KeyPress) { + QKeyEvent *ke = static_cast(event); + switch (ke->key()) { + case Qt::Key_F2: { + renameItem(ui.treeView->currentIndex()); + } break; + + case Qt::Key_Delete: { + removeItem(ui.treeView->currentIndex()); + } break; + + default: break; + } + } + + if (event->type() == QEvent::MouseButtonRelease) { + QMouseEvent *me = static_cast(event); + switch (me->button()) { + case Qt::LeftButton: { + if (me->modifiers() & Qt::ControlModifier) + setSourceFromIndex(ui.treeView->currentIndex(), true); + } break; + + case Qt::MidButton: { + setSourceFromIndex(ui.treeView->currentIndex(), true); + } break; + + default: break; + } + } + return QObject::eventFilter(object, event); +} + +void BookmarkManagerWidget::findNext() +{ + TRACE_OBJ + selectNextIndex(true); +} + +void BookmarkManagerWidget::findPrevious() +{ + TRACE_OBJ + selectNextIndex(false); +} + +void BookmarkManagerWidget::importBookmarks() +{ + TRACE_OBJ + const QString &fileName = QFileDialog::getOpenFileName(0, TR("Open File"), + QDir::currentPath(), TR("Files (*.xbel)")); + + if (fileName.isEmpty()) + return; + + QFile file(fileName); + if (file.open(QIODevice::ReadOnly)) { + XbelReader reader(bookmarkModel); + reader.readFromFile(&file); + } +} + +void BookmarkManagerWidget::exportBookmarks() +{ + TRACE_OBJ + QString fileName = QFileDialog::getSaveFileName(0, TR("Save File"), + QLatin1String("untitled.xbel"), TR("Files (*.xbel)")); + + const QLatin1String suffix(".xbel"); + if (!fileName.endsWith(suffix)) + fileName.append(suffix); + + QFile file(fileName); + if (file.open(QIODevice::WriteOnly)) { + XbelWriter writer(bookmarkModel); + writer.writeToFile(&file); + } else { + QMessageBox::information(this, TR("Qt Assistant"), + TR("Unable to save bookmarks."), TR("OK")); + } +} + +void BookmarkManagerWidget::refeshBookmarkCache() +{ + TRACE_OBJ + cache.clear(); + + const QString &text = ui.lineEdit->text(); + if (!text.isEmpty()) + cache = bookmarkModel->indexListFor(text); +} + +void BookmarkManagerWidget::textChanged(const QString &/*text*/) +{ + TRACE_OBJ + refeshBookmarkCache(); + if (!cache.isEmpty()) + ui.treeView->setCurrentIndex(cache.at(0)); +} + +void BookmarkManagerWidget::removeItem(const QModelIndex &index) +{ + TRACE_OBJ + QModelIndex current = index.isValid() ? index : ui.treeView->currentIndex(); + if (!bookmarkModel->parent(current).isValid()) + return; // check if we should delete the "Bookmarks Menu", bail + + if (bookmarkModel->hasChildren(current)) { + int value = QMessageBox::question(this, TR("Remove"), TR("You are going" + "to delete a Folder, this will also
remove it's content. Are " + "you sure to continue?"), + QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel); + if (value == QMessageBox::Cancel) + return; + } + bookmarkModel->removeItem(current); +} + +void BookmarkManagerWidget::customContextMenuRequested(const QPoint &point) +{ + TRACE_OBJ + const QModelIndex &index = ui.treeView->indexAt(point); + if (!index.isValid()) + return; + + // check if we should open the menu on "Bookmarks Menu", bail + if (!bookmarkModel->parent(index).isValid()) + return; + + QAction *remove = 0; + QAction *rename = 0; + QAction *showItem = 0; + QAction *showItemInNewTab = 0; + + QMenu menu(QLatin1String("")); + if (bookmarkModel->data(index, UserRoleFolder).toBool()) { + remove = menu.addAction(TR("Delete Folder")); + rename = menu.addAction(TR("Rename Folder")); + } else { + showItem = menu.addAction(TR("Show Bookmark")); + showItemInNewTab = menu.addAction(TR("Show Bookmark in New Tab")); + menu.addSeparator(); + remove = menu.addAction(TR("Delete Bookmark")); + rename = menu.addAction(TR("Rename Bookmark")); + } + + QAction *pickedAction = menu.exec(ui.treeView->mapToGlobal(point)); + if (pickedAction == rename) + renameItem(index); + else if (pickedAction == remove) + removeItem(index); + else if (pickedAction == showItem || pickedAction == showItemInNewTab) + setSourceFromIndex(index, pickedAction == showItemInNewTab); +} + +void +BookmarkManagerWidget::setSourceFromIndex(const QModelIndex &index, bool newTab) +{ + TRACE_OBJ + if (bookmarkModel->data(index, UserRoleFolder).toBool()) + return; + + const QVariant &data = bookmarkModel->data(index, UserRoleUrl); + if (data.canConvert()) { + if (newTab) + emit setSourceInNewTab(data.toUrl()); + else + emit setSource(data.toUrl()); + } +} + +QT_END_NAMESPACE diff --git a/tools/assistant/tools/assistant/bookmarkmanagerwidget.h b/tools/assistant/tools/assistant/bookmarkmanagerwidget.h new file mode 100644 index 0000000..94384a6 --- /dev/null +++ b/tools/assistant/tools/assistant/bookmarkmanagerwidget.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Assistant of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef BOOKMARKMANAGERWIDGET_H +#define BOOKMARKMANAGERWIDGET_H + +#include "ui_bookmarkmanagerwidget.h" + +#include + +#include + +QT_BEGIN_NAMESPACE + +class BookmarkModel; +class QCloseEvent; +class QString; + +class BookmarkManagerWidget : public QWidget +{ + Q_OBJECT +public: + BookmarkManagerWidget(BookmarkModel *bookmarkModel, QWidget *parent = 0); + ~BookmarkManagerWidget(); + +protected: + void closeEvent(QCloseEvent *event); + +signals: + void setSource(const QUrl &url); + void setSourceInNewTab(const QUrl &url); + + void managerWidgetAboutToClose(); + +private: + void renameItem(const QModelIndex &index); + void selectNextIndex(bool direction) const; + bool eventFilter(QObject *object, QEvent *event); + +private slots: + void findNext(); + void findPrevious(); + + void importBookmarks(); + void exportBookmarks(); + + void refeshBookmarkCache(); + void textChanged(const QString &text); + + void removeItem(const QModelIndex &index = QModelIndex()); + + void customContextMenuRequested(const QPoint &point); + void setSourceFromIndex(const QModelIndex &index, bool newTab = false); + +private: + QMenu importExportMenu; + Ui::BookmarkManagerWidget ui; + QList cache; + + BookmarkModel *bookmarkModel; +}; + +QT_END_NAMESPACE + +#endif // BOOKMARKMANAGERWIDGET_H \ No newline at end of file diff --git a/tools/assistant/tools/assistant/bookmarkmanagerwidget.ui b/tools/assistant/tools/assistant/bookmarkmanagerwidget.ui new file mode 100644 index 0000000..dc965d9 --- /dev/null +++ b/tools/assistant/tools/assistant/bookmarkmanagerwidget.ui @@ -0,0 +1,137 @@ + + + BookmarkManagerWidget + + + + 0 + 0 + 517 + 348 + + + + Manage Bookmarks + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Search: + + + + + + + + + + + + true + + + true + + + true + + + 1000 + + + true + + + true + + + 225 + + + 50 + + + 225 + + + 50 + + + + + + + + + Remove + + + + + + + Import and Backup + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + OK + + + + + + + + + + + pushButton_5 + clicked() + BookmarkManagerWidget + close() + + + 445 + 328 + + + 340 + 313 + + + + + diff --git a/tools/assistant/tools/assistant/bookmarkmodel.cpp b/tools/assistant/tools/assistant/bookmarkmodel.cpp index f9c9980..e446ff0 100644 --- a/tools/assistant/tools/assistant/bookmarkmodel.cpp +++ b/tools/assistant/tools/assistant/bookmarkmodel.cpp @@ -306,6 +306,18 @@ BookmarkModel::itemFromIndex(const QModelIndex &index) const return rootItem; } +QList +BookmarkModel::indexListFor(const QString &label) const +{ + QList hits; + const QModelIndexList &list = collectItems(QModelIndex()); + foreach(const QModelIndex &index, list) { + if (index.data().toString().contains(label, Qt::CaseInsensitive)) + hits.prepend(index); // list is reverse sorted + } + return hits; +} + bool BookmarkModel::insertRows(int position, int rows, const QModelIndex &parent) { diff --git a/tools/assistant/tools/assistant/bookmarkmodel.h b/tools/assistant/tools/assistant/bookmarkmodel.h index 6b2a0b8..6469258 100644 --- a/tools/assistant/tools/assistant/bookmarkmodel.h +++ b/tools/assistant/tools/assistant/bookmarkmodel.h @@ -84,6 +84,7 @@ public: QModelIndex indexFromItem(BookmarkItem *item) const; BookmarkItem *itemFromIndex(const QModelIndex &index) const; + QList indexListFor(const QString &label) const; bool insertRows(int position, int rows, const QModelIndex &parent); bool removeRows(int position, int rows, const QModelIndex &parent); -- cgit v0.12