diff options
author | Andrea Diamantini <adjam7@gmail.com> | 2012-07-31 18:15:08 +0200 |
---|---|---|
committer | Andrea Diamantini <adjam7@gmail.com> | 2012-12-10 02:48:04 +0100 |
commit | f53c040991f8b84fba1c6ce72087408f06df6a7c (patch) | |
tree | 8072afc4fde8236894504684d9ed46cef9042ca1 /src/bookmarks | |
parent | detach tab action restored :) (diff) | |
download | rekonq-f53c040991f8b84fba1c6ce72087408f06df6a7c.tar.xz |
Bookmark Manager restore
Diffstat (limited to 'src/bookmarks')
-rw-r--r-- | src/bookmarks/bookmarkmanager.cpp | 313 | ||||
-rw-r--r-- | src/bookmarks/bookmarkmanager.h | 170 | ||||
-rw-r--r-- | src/bookmarks/bookmarkowner.cpp | 428 | ||||
-rw-r--r-- | src/bookmarks/bookmarkowner.h | 159 | ||||
-rw-r--r-- | src/bookmarks/bookmarkscontextmenu.cpp | 162 | ||||
-rw-r--r-- | src/bookmarks/bookmarkscontextmenu.h | 57 | ||||
-rw-r--r-- | src/bookmarks/bookmarkstoolbar.cpp | 609 | ||||
-rw-r--r-- | src/bookmarks/bookmarkstoolbar.h | 111 |
8 files changed, 2009 insertions, 0 deletions
diff --git a/src/bookmarks/bookmarkmanager.cpp b/src/bookmarks/bookmarkmanager.cpp new file mode 100644 index 00000000..25c78044 --- /dev/null +++ b/src/bookmarks/bookmarkmanager.cpp @@ -0,0 +1,313 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2012 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com> +* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +// Self Includes +#include "bookmarkmanager.h" +#include "bookmarkmanager.moc" + +// Local Includes +#include "application.h" +#include "bookmarkstoolbar.h" +#include "bookmarkowner.h" +// #include "iconmanager.h" +// #include "mainwindow.h" +// #include "webtab.h" + +// KDE Includes +#include <KActionCollection> +#include <KStandardDirs> + +// Qt Includes +#include <QtCore/QFile> + + +// ---------------------------------------------------------------------------------------------- + + +QWeakPointer<BookmarkManager> BookmarkManager::s_bookmarkManager; + + +BookmarkManager *BookmarkManager::self() +{ + if (s_bookmarkManager.isNull()) + { + s_bookmarkManager = new BookmarkManager(qApp); + } + return s_bookmarkManager.data(); +} + + +// ---------------------------------------------------------------------------------------------- + + +BookmarkManager::BookmarkManager(QObject *parent) + : QObject(parent) + , m_manager(0) + , m_owner(0) + , m_actionCollection(new KActionCollection(this)) +{ + m_manager = KBookmarkManager::userBookmarksManager(); + const QString bookmarksFile = KStandardDirs::locateLocal("data", QString::fromLatin1("konqueror/bookmarks.xml")); + + if (!QFile::exists(bookmarksFile)) + { + kDebug() << "copying of defaultbookmarks.xbel ..."; + + QString bookmarksDefaultPath = KStandardDirs::locate("appdata" , "defaultbookmarks.xbel"); + KBookmarkManager *tempManager = KBookmarkManager::managerForExternalFile(bookmarksDefaultPath); + + copyBookmarkGroup(tempManager->root(), rootGroup()); + m_manager->emitChanged(); + delete tempManager; + } + + connect(m_manager, SIGNAL(changed(QString, QString)), this, SLOT(slotBookmarksChanged())); + + // setup menu + m_owner = new BookmarkOwner(m_manager, this); + connect(m_owner, SIGNAL(openUrl(KUrl, Rekonq::OpenType)), this, SIGNAL(openUrl(KUrl, Rekonq::OpenType))); + + // bookmarks loading + connect(this, SIGNAL(openUrl(KUrl, Rekonq::OpenType)), rApp, SLOT(loadUrl(KUrl, Rekonq::OpenType))); +} + + +BookmarkManager::~BookmarkManager() +{ + delete m_manager; +} + + +void BookmarkManager::registerBookmarkBar(BookmarkToolBar *toolbar) +{ + if (m_bookmarkToolBars.contains(toolbar)) + return; + + m_bookmarkToolBars.append(toolbar); +} + + +void BookmarkManager::removeBookmarkBar(BookmarkToolBar *toolbar) +{ + m_bookmarkToolBars.removeOne(toolbar); +} + + +QAction* BookmarkManager::actionByName(const QString &name) +{ + QAction *action = m_actionCollection->action(name); + if (action) + return action; + return new QAction(this); +} + + +KBookmarkGroup BookmarkManager::rootGroup() +{ + return m_manager->root(); +} + + +QList<KBookmark> BookmarkManager::find(const QString &text) +{ + QList<KBookmark> list; + + KBookmarkGroup root = rootGroup(); + if (!root.isNull()) + for (KBookmark bookmark = root.first(); !bookmark.isNull(); bookmark = root.next(bookmark)) + find(&list, bookmark, text); + + return list; +} + + +KBookmark BookmarkManager::bookmarkForUrl(const KUrl &url) +{ + KBookmarkGroup root = rootGroup(); + if (root.isNull()) + return KBookmark(); + + return bookmarkForUrl(root, url); +} + + +void BookmarkManager::slotBookmarksChanged() +{ + Q_FOREACH(BookmarkToolBar * bookmarkToolBar, m_bookmarkToolBars) + { + if (bookmarkToolBar) + { + bookmarkToolBar->toolBar()->clear(); + fillBookmarkBar(bookmarkToolBar); + } + } + + // NOTE with this signal, we should (eventual) update about:bookmarks page... + emit bookmarksUpdated(); +} + + +void BookmarkManager::fillBookmarkBar(BookmarkToolBar *toolBar) +{ + KBookmarkGroup root = m_manager->toolbar(); + if (root.isNull()) + return; + + for (KBookmark bookmark = root.first(); !bookmark.isNull(); bookmark = root.next(bookmark)) + { + if (bookmark.isGroup()) + { + KBookmarkActionMenu *menuAction = new KBookmarkActionMenu(bookmark.toGroup(), this); + menuAction->setDelayed(false); + BookmarkMenu *bMenu = new BookmarkMenu(m_manager, m_owner, menuAction->menu(), bookmark.address()); + bMenu->setParent(menuAction->menu()); + + connect(menuAction->menu(), SIGNAL(aboutToShow()), toolBar, SLOT(menuDisplayed())); + connect(menuAction->menu(), SIGNAL(aboutToHide()), toolBar, SLOT(menuHidden())); + + toolBar->toolBar()->addAction(menuAction); + toolBar->toolBar()->widgetForAction(menuAction)->installEventFilter(toolBar); + } + else if (bookmark.isSeparator()) + { + toolBar->toolBar()->addSeparator(); + } + else + { + KBookmarkAction *action = new KBookmarkAction(bookmark, m_owner, this); +// FIXME action->setIcon(rApp->iconManager()->iconForUrl(KUrl(bookmark.url()))); + connect(action, SIGNAL(hovered()), toolBar, SLOT(actionHovered())); + toolBar->toolBar()->addAction(action); + toolBar->toolBar()->widgetForAction(action)->installEventFilter(toolBar); + } + } +} + + +void BookmarkManager::find(QList<KBookmark> *list, const KBookmark &bookmark, const QString &text) +{ + if (bookmark.isGroup()) + { + KBookmarkGroup group = bookmark.toGroup(); + for (KBookmark bm = group.first(); !bm.isNull(); bm = group.next(bm)) + find(list, bm, text); + } + else + { + QStringList words = text.split(' '); + bool matches = true; + Q_FOREACH(const QString & word, words) + { + if (!bookmark.url().url().contains(word, Qt::CaseInsensitive) + && !bookmark.fullText().contains(word, Qt::CaseInsensitive)) + { + matches = false; + break; + } + } + if (matches) + *list << bookmark; + } +} + + +KBookmark BookmarkManager::bookmarkForUrl(const KBookmark &bookmark, const KUrl &url) +{ + KBookmark found; + + if (bookmark.isGroup()) + { + KBookmarkGroup group = bookmark.toGroup(); + KBookmark bookmark = group.first(); + + while (!bookmark.isNull() && found.isNull()) + { + found = bookmarkForUrl(bookmark, url); + bookmark = group.next(bookmark); + } + } + else if (!bookmark.isSeparator() && bookmark.url() == url) + { + found = bookmark; + } + + return found; +} + + +void BookmarkManager::copyBookmarkGroup(const KBookmarkGroup &groupToCopy, KBookmarkGroup destGroup) +{ + KBookmark bookmark = groupToCopy.first(); + while (!bookmark.isNull()) + { + if (bookmark.isGroup()) + { + KBookmarkGroup newDestGroup = destGroup.createNewFolder(bookmark.text()); + if (bookmark.toGroup().isToolbarGroup()) + { + newDestGroup.internalElement().setAttribute("toolbar", "yes"); + newDestGroup.setIcon("bookmark-toolbar"); + } + copyBookmarkGroup(bookmark.toGroup(), newDestGroup); + } + else if (bookmark.isSeparator()) + { + destGroup.createNewSeparator(); + } + else + { + destGroup.addBookmark(bookmark.text(), bookmark.url()); + } + bookmark = groupToCopy.next(bookmark); + } +} + + +void BookmarkManager::slotEditBookmarks() +{ + m_manager->slotEditBookmarks(); +} + + +KBookmark BookmarkManager::findByAddress(const QString &address) +{ + return m_manager->findByAddress(address); +} + + +void BookmarkManager::openFolderinTabs(const KBookmarkGroup &bm) +{ + m_owner->openFolderinTabs(bm); +} + + +void BookmarkManager::emitChanged() +{ + m_manager->emitChanged(); +} diff --git a/src/bookmarks/bookmarkmanager.h b/src/bookmarks/bookmarkmanager.h new file mode 100644 index 00000000..d842c271 --- /dev/null +++ b/src/bookmarks/bookmarkmanager.h @@ -0,0 +1,170 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2012 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com> +* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +#ifndef BOOKMARK_MANAGER_H +#define BOOKMARK_MANAGER_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// KDE Includes +#include <KBookmark> + +// Qt Includes +#include <QObject> +#include <QWeakPointer> + +// Forward Declarations +class BookmarkToolBar; +class BookmarkOwner; +class BookmarkMenu; + +class KAction; +class KActionCollection; +class KBookmarkGroup; +class KBookmarkManager; +class KUrl; + +class QAction; + + +/** + * This class represent the interface to rekonq bookmarks system. + * All rekonq needs (Bookmarks Menu, Bookmarks Toolbar) is provided + * from this class. + * So it implements code to have each one. + */ +class BookmarkManager : public QObject +{ + Q_OBJECT + +public: + /** + * Entry point. + * Access to BookmarkManager class by using + * BookmarkManager::self()->thePublicMethodYouNeed() + */ + static BookmarkManager *self(); + + ~BookmarkManager(); + + /** + * @short set the Bookmarks Toolbar Action + */ + void registerBookmarkBar(BookmarkToolBar *toolbar); + void removeBookmarkBar(BookmarkToolBar *toolbar); + + /** + * @short Get action by name + * This method returns poiner bookmark action of given name. + * @pre m_actionCollection != NULL + * @param name Name of action you want to get + * @return It returns actions if one exists or empty object + */ + QAction* actionByName(const QString &name); + + /** + * returns Bookmark Manager root group + * + * @return the root bookmark group + */ + KBookmarkGroup rootGroup(); + + inline KBookmarkManager* manager() + { + return m_manager; + } + + inline BookmarkOwner* owner() + { + return m_owner; + } + + QList<KBookmark> find(const QString &text); + + KBookmark bookmarkForUrl(const KUrl &url); + + KBookmark findByAddress(const QString &); + + void openFolderinTabs(const KBookmarkGroup &bm); + + void emitChanged(); + + static inline QString bookmark_mime_type() + { + return QL1S("application/x-rekonq-bookmark"); + } + +private: + /** + * @short Class constructor. + * Connect BookmarksProvider with bookmarks source + * (actually konqueror's bookmarks). + * @param parent The WebWindow to provide bookmarks objects. + */ + BookmarkManager(QObject *parent = 0); + +public Q_SLOTS: + /** + * @short Waits for signal that the group with the address has been modified by the caller. + * Waits for signal that the group (or any of its children) with the address + * @p groupAddress (e.g. "/4/5") has been modified by the caller @p caller. + * @param groupAddress bookmark group address + * @param caller caller that modified the bookmarks + * @see KBookmarkManager::changed + */ + void slotBookmarksChanged(); + void fillBookmarkBar(BookmarkToolBar *toolBar); + + void slotEditBookmarks(); + +Q_SIGNALS: + /** + * @short This signal is emitted when an url has to be loaded + */ + void openUrl(const KUrl &, const Rekonq::OpenType &); + + void bookmarksUpdated(); + +private: + void find(QList<KBookmark> *list, const KBookmark &bookmark, const QString &text); + KBookmark bookmarkForUrl(const KBookmark &bookmark, const KUrl &url); + void copyBookmarkGroup(const KBookmarkGroup &groupToCopy, KBookmarkGroup destGroup); + + KBookmarkManager *m_manager; + BookmarkOwner *m_owner; + KActionCollection *m_actionCollection; + QList<BookmarkToolBar *> m_bookmarkToolBars; + + static QWeakPointer<BookmarkManager> s_bookmarkManager; +}; + + +#endif // BOOKMARK_MANAGER_H diff --git a/src/bookmarks/bookmarkowner.cpp b/src/bookmarks/bookmarkowner.cpp new file mode 100644 index 00000000..1c117824 --- /dev/null +++ b/src/bookmarks/bookmarkowner.cpp @@ -0,0 +1,428 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2012 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com> +* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +// Self Includes +#include "bookmarkowner.h" +#include "bookmarkowner.moc" + +// Local Includes +#include "bookmarkmanager.h" + +#include "application.h" +#include "tabwindow.h" +#include "webwindow.h" + +// KDE Includes +#include <KBookmarkDialog> +#include <KLocalizedString> +#include <KMessageBox> + +// Qt Includes +#include <QClipboard> + +// Nepomuk config include +#include "config-nepomuk.h" + +#ifdef HAVE_NEPOMUK +// Local Nepomuk Includes +#include "resourcelinkdialog.h" + +// Nepomuk Includes +#include <Nepomuk/Resource> +#include <Nepomuk/Vocabulary/NFO> +#endif + + +BookmarkOwner::BookmarkOwner(KBookmarkManager *manager, QObject *parent) + : QObject(parent) + , KBookmarkOwner() + , m_manager(manager) +{ +} + + +KAction* BookmarkOwner::createAction(const KBookmark &bookmark, const BookmarkAction &bmAction) +{ + switch (bmAction) + { + case OPEN: + return createAction(i18n("Open"), "tab-new", + i18n("Open bookmark in current tab"), SLOT(openBookmark(KBookmark)), bookmark); + case OPEN_IN_TAB: + return createAction(i18n("Open in New Tab"), "tab-new", + i18n("Open bookmark in new tab"), SLOT(openBookmarkInNewTab(KBookmark)), bookmark); + case OPEN_IN_WINDOW: + return createAction(i18n("Open in New Window"), "window-new", + i18n("Open bookmark in new window"), SLOT(openBookmarkInNewWindow(KBookmark)), bookmark); + case OPEN_FOLDER: + return createAction(i18n("Open Folder in Tabs"), "tab-new", + i18n("Open all the bookmarks in folder in tabs"), SLOT(openBookmarkFolder(KBookmark)), bookmark); + case BOOKMARK_PAGE: + return createAction(i18n("Add Bookmark"), "bookmark-new", + i18n("Bookmark current page"), SLOT(bookmarkCurrentPage(KBookmark)), bookmark); + case NEW_FOLDER: + return createAction(i18n("New Folder"), "folder-new", + i18n("Create a new bookmark folder"), SLOT(newBookmarkFolder(KBookmark)), bookmark); + case NEW_SEPARATOR: + return createAction(i18n("New Separator"), "edit-clear", + i18n("Create a new bookmark separator"), SLOT(newSeparator(KBookmark)), bookmark); + case COPY: + return createAction(i18n("Copy Link"), "edit-copy", + i18n("Copy the bookmark's link address"), SLOT(copyLink(KBookmark)), bookmark); + case EDIT: + return createAction(i18n("Edit"), "configure", + i18n("Edit the bookmark"), SLOT(editBookmark(KBookmark)), bookmark); +#ifdef HAVE_NEPOMUK + case FANCYBOOKMARK: + return createAction(i18n("Fancy Bookmark"), "nepomuk", + i18n("Link Nepomuk resources"), SLOT(fancyBookmark(KBookmark)), bookmark); +#endif + case DELETE: + return createAction(i18n("Delete"), "edit-delete", + i18n("Delete the bookmark"), SLOT(deleteBookmark(KBookmark)), bookmark); + case SET_TOOLBAR_FOLDER: + return createAction(i18n("Set as toolbar folder"), "bookmark-toolbar", + "", SLOT(setToolBarFolder(KBookmark)), bookmark); + case UNSET_TOOLBAR_FOLDER: + return createAction(i18n("Unset this folder as the toolbar folder"), "bookmark-toolbar", + "", SLOT(unsetToolBarFolder()), bookmark); + default: + ASSERT_NOT_REACHED(unknown BookmarkAction); + return 0; + } +} + + +QString BookmarkOwner::currentTitle() const +{ + return rApp->tabWindow()->currentWebWindow()->title(); +} + + +QString BookmarkOwner::currentUrl() const +{ + return rApp->tabWindow()->currentWebWindow()->url().toString(); +} + + +QList< QPair<QString, QString> > BookmarkOwner::currentBookmarkList() const +{ + QList< QPair<QString, QString> > bkList; + TabWindow *view = rApp->tabWindow(); + int tabNumber = view->count(); + + for (int i = 0; i < tabNumber; ++i) + { + QPair<QString, QString> item; + item.first = view->webWindow(i)->title(); + item.second = view->webWindow(i)->url().toString(); + bkList << item; + } + + return bkList; +} + + +void BookmarkOwner::openBookmark(const KBookmark &bookmark, + Qt::MouseButtons mouseButtons, + Qt::KeyboardModifiers keyboardModifiers) +{ + if (keyboardModifiers & Qt::ControlModifier || mouseButtons & Qt::MidButton) + openBookmarkInNewTab(bookmark); + else + openBookmark(bookmark); +} + + +void BookmarkOwner::openFolderinTabs(const KBookmarkGroup &bkGoup) +{ + QList<KUrl> urlList = bkGoup.groupUrlList(); + + if (urlList.length() > 8) + { + if (KMessageBox::warningContinueCancel( + rApp->tabWindow(), + i18ncp("%1=Number of tabs. Value is always >=8", + "You are about to open %1 tabs.\nAre you sure?", + "You are about to open %1 tabs.\nAre you sure?", urlList.length())) + != KMessageBox::Continue + ) + return; + } + + Q_FOREACH(const KUrl & url, urlList) + { + emit openUrl(url, Rekonq::NewFocusedTab); + } +} + + +void BookmarkOwner::openBookmark(const KBookmark &bookmark) +{ + emit openUrl(bookmark.url(), Rekonq::CurrentTab); +} + + +void BookmarkOwner::openBookmarkInNewTab(const KBookmark &bookmark) +{ + emit openUrl(bookmark.url(), Rekonq::NewTab); +} + + +void BookmarkOwner::openBookmarkInNewWindow(const KBookmark &bookmark) +{ + emit openUrl(bookmark.url(), Rekonq::NewWindow); +} + + +void BookmarkOwner::openBookmarkFolder(const KBookmark &bookmark) +{ + Q_ASSERT(bookmark.isGroup()); + openFolderinTabs(bookmark.toGroup()); +} + + +KBookmark BookmarkOwner::bookmarkCurrentPage(const KBookmark &bookmark) +{ + KBookmarkGroup parent; + + if (!bookmark.isNull()) + { + if (bookmark.isGroup()) + parent = bookmark.toGroup(); + else + parent = bookmark.parentGroup(); + } + else + { + parent = BookmarkManager::self()->rootGroup(); +#ifdef HAVE_NEPOMUK + Nepomuk::Resource nfoResource; + nfoResource = ((QUrl)currentUrl()); + nfoResource.addType(Nepomuk::Vocabulary::NFO::Website()); + nfoResource.setLabel(currentTitle()); +#endif + } + + KBookmark newBk = parent.addBookmark(currentTitle(), KUrl(currentUrl())); + if (!bookmark.isNull()) + parent.moveBookmark(newBk, bookmark); + + m_manager->emitChanged(parent); + return newBk; +} + + +KBookmarkGroup BookmarkOwner::newBookmarkFolder(const KBookmark &bookmark) +{ + KBookmarkGroup newBk; + KBookmarkDialog *dialog = bookmarkDialog(m_manager, 0); + QString folderName = i18n("New folder"); + + if (!bookmark.isNull()) + { + if (bookmark.isGroup()) + { + newBk = dialog->createNewFolder(folderName, bookmark); + } + else + { + newBk = dialog->createNewFolder(folderName, bookmark.parentGroup()); + if (!newBk.isNull()) + { + KBookmarkGroup parent = newBk.parentGroup(); + parent.moveBookmark(newBk, bookmark); + m_manager->emitChanged(parent); + } + } + } + else + { + newBk = dialog->createNewFolder(folderName); + } + + delete dialog; + return newBk; +} + + +KBookmark BookmarkOwner::newSeparator(const KBookmark &bookmark) +{ + KBookmark newBk; + + if (!bookmark.isNull()) + { + if (bookmark.isGroup()) + { + newBk = bookmark.toGroup().createNewSeparator(); + } + else + { + newBk = bookmark.parentGroup().createNewSeparator(); + newBk.parentGroup().moveBookmark(newBk, bookmark); + } + } + else + { + newBk = BookmarkManager::self()->rootGroup().createNewSeparator(); + } + + newBk.setIcon("edit-clear"); + + m_manager->emitChanged(newBk.parentGroup()); + return newBk; +} + + +void BookmarkOwner::copyLink(const KBookmark &bookmark) +{ + if (bookmark.isNull()) + return; + + QApplication::clipboard()->setText(bookmark.url().url()); +} + + +void BookmarkOwner::editBookmark(KBookmark bookmark) +{ + if (bookmark.isNull()) + return; + + KBookmarkDialog *dialog = bookmarkDialog(m_manager, 0); + dialog->editBookmark(bookmark); + + delete dialog; +} + + +#ifdef HAVE_NEPOMUK +void BookmarkOwner::fancyBookmark(KBookmark bookmark) +{ + Nepomuk::Resource nfoResource = (KUrl)bookmark.url(); + Nepomuk::ResourceLinkDialog r(nfoResource); + r.exec(); + +} +#endif + +bool BookmarkOwner::deleteBookmark(const KBookmark &bookmark) +{ + if (bookmark.isNull()) + return false; + + KBookmarkGroup bmg = bookmark.parentGroup(); + QString dialogCaption, dialogText; + + if (bookmark.isGroup()) + { + dialogCaption = i18n("Bookmark Folder Deletion"); + dialogText = i18n("Are you sure you wish to remove the bookmark folder\n\"%1\"?", bookmark.fullText()); + } + else if (bookmark.isSeparator()) + { + dialogCaption = i18n("Separator Deletion"); + dialogText = i18n("Are you sure you wish to remove this separator?"); + } + else + { + dialogCaption = i18n("Bookmark Deletion"); + dialogText = i18n("Are you sure you wish to remove the bookmark\n\"%1\"?", bookmark.fullText()); + } + + if (KMessageBox::warningContinueCancel( + 0, + dialogText, + dialogCaption, + KStandardGuiItem::del(), + KStandardGuiItem::cancel(), + "bookmarkDeletition_askAgain") + != KMessageBox::Continue + ) + return false; + + bmg.deleteBookmark(bookmark); +#ifdef HAVE_NEPOMUK + Nepomuk::Resource nfoResource(bookmark.url()); + nfoResource.remove(); +#endif + m_manager->emitChanged(bmg); + return true; +} + + +void BookmarkOwner::setToolBarFolder(KBookmark bookmark) +{ + if (!bookmark.isGroup()) + return; + + unsetToolBarFolder(); + bookmark.internalElement().setAttribute("toolbar", "yes"); + bookmark.setIcon("bookmark-toolbar"); + + m_manager->emitChanged(); +} + + +void BookmarkOwner::unsetToolBarFolder() +{ + KBookmarkGroup toolbar = m_manager->toolbar(); + if (!toolbar.isNull()) + { + toolbar.internalElement().setAttribute("toolbar", "no"); + toolbar.setIcon(""); + } + m_manager->emitChanged(); +} + + +KAction* BookmarkOwner::createAction(const QString &text, const QString &icon, + const QString &help, const char *slot, + const KBookmark &bookmark) +{ + CustomBookmarkAction *act = new CustomBookmarkAction(bookmark, KIcon(icon), text, this); + act->setHelpText(help); + connect(act, SIGNAL(triggered(KBookmark)), this, slot); + return act; +} + + +// ------------------------------------------------------------------------------------------------- + + +CustomBookmarkAction::CustomBookmarkAction(const KBookmark &bookmark, const KIcon &icon, const QString &text, QObject *parent) + : KAction(icon, text, parent) + , m_bookmark(bookmark) +{ + connect(this, SIGNAL(triggered()), this, SLOT(onActionTriggered())); +} + +void CustomBookmarkAction::onActionTriggered() +{ + emit triggered(m_bookmark); +} diff --git a/src/bookmarks/bookmarkowner.h b/src/bookmarks/bookmarkowner.h new file mode 100644 index 00000000..f0b238b9 --- /dev/null +++ b/src/bookmarks/bookmarkowner.h @@ -0,0 +1,159 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2012 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com> +* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +#ifndef BOOKMARKOWNER_H +#define BOOKMARKOWNER_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Nepomuk config include +#include "config-nepomuk.h" + +// KDE Includes +#include <KAction> +#include <KBookmarkOwner> + + +/** + * This class allows to manage bookmarks as actions. + */ +class REKONQ_TESTS_EXPORT BookmarkOwner : public QObject, public KBookmarkOwner +{ + Q_OBJECT + +public: + explicit BookmarkOwner(KBookmarkManager *manager, QObject *parent = 0); + + enum BookmarkAction + { + OPEN = 0, + OPEN_IN_TAB, + OPEN_IN_WINDOW, + OPEN_FOLDER, + BOOKMARK_PAGE, + NEW_FOLDER, + NEW_SEPARATOR, + COPY, + EDIT, +#ifdef HAVE_NEPOMUK + FANCYBOOKMARK, +#endif + DELETE, + NUM_ACTIONS, + SET_TOOLBAR_FOLDER, + UNSET_TOOLBAR_FOLDER + }; + + /** + * @return A new action for the given bookmark. + */ + KAction* createAction(const KBookmark &bookmark, const BookmarkAction &bmAction); + + // @{ + /** + * Functions to get current information. + */ + virtual QString currentTitle() const; + virtual QString currentUrl() const; + virtual QList< QPair<QString, QString> > currentBookmarkList() const; + // @} + + virtual bool supportsTabs() const + { + return true; + } + + // @{ + /** + * This functions emit signals that open the selected URLs + */ + virtual void openBookmark(const KBookmark &bookmark, + Qt::MouseButtons mouseButtons, + Qt::KeyboardModifiers keyboardModifiers); + virtual void openFolderinTabs(const KBookmarkGroup &bkGoup); + // @} + +public Q_SLOTS: + void openBookmark(const KBookmark &bookmark); + void openBookmarkInNewTab(const KBookmark &bookmark); + void openBookmarkInNewWindow(const KBookmark &bookmark); + void openBookmarkFolder(const KBookmark &bookmark); + + KBookmark bookmarkCurrentPage(const KBookmark &bookmark = KBookmark()); + KBookmarkGroup newBookmarkFolder(const KBookmark &bookmark = KBookmark()); + KBookmark newSeparator(const KBookmark &bookmark = KBookmark()); + + void copyLink(const KBookmark &bookmark); + void editBookmark(KBookmark bookmark); +#ifdef HAVE_NEPOMUK + void fancyBookmark(KBookmark bookmark); +#endif + bool deleteBookmark(const KBookmark &bookmark); + void setToolBarFolder(KBookmark bookmark = KBookmark()); + void unsetToolBarFolder(); + +Q_SIGNALS: + /** + * This signal is emitted when an url has to be loaded + * @param url the URL to load + */ + void openUrl(const KUrl &, const Rekonq::OpenType &); + +private: + KAction* createAction(const QString &text, const QString &icon, + const QString &help, const char *slot, + const KBookmark &bookmark); + + KBookmarkManager *m_manager; +}; + + +// ----------------------------------------------------------------------------------------------- + + +class CustomBookmarkAction : public KAction +{ + Q_OBJECT + +public: + CustomBookmarkAction(const KBookmark &bookmark, const KIcon &icon, const QString &text, QObject *parent); + +Q_SIGNALS: + void triggered(const KBookmark &); + +private Q_SLOTS: + void onActionTriggered(); + +private: + KBookmark m_bookmark; +}; + +#endif // BOOKMARKOWNER_H diff --git a/src/bookmarks/bookmarkscontextmenu.cpp b/src/bookmarks/bookmarkscontextmenu.cpp new file mode 100644 index 00000000..d0907660 --- /dev/null +++ b/src/bookmarks/bookmarkscontextmenu.cpp @@ -0,0 +1,162 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> +* Copyright (c) 2011-2012 by Phaneendra Hegde <pnh.pes@gmail.com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +// Self Includes +#include "bookmarkscontextmenu.h" + +// Nepomuk config include +#include "config-nepomuk.h" + +// Local Includes +#include "bookmarkowner.h" +#include "bookmarkmanager.h" + +// KDE Includes +#include <KBookmarkManager> + + +BookmarksContextMenu::BookmarksContextMenu(const KBookmark &bookmark, + KBookmarkManager *manager, + BookmarkOwner *owner, + bool nullForced, + QWidget *parent) + : KBookmarkContextMenu(bookmark, manager, owner, parent) + , m_bmOwner(owner) + , m_nullForced(nullForced) +{ +} + + +void BookmarksContextMenu::addBookmarkActions() +{ + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::OPEN_IN_TAB)); + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::OPEN_IN_WINDOW)); + + addSeparator(); + + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::BOOKMARK_PAGE)); + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::NEW_FOLDER)); + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::NEW_SEPARATOR)); + + addSeparator(); + + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::COPY)); + + addSeparator(); + + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::EDIT)); +#ifdef HAVE_NEPOMUK + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::FANCYBOOKMARK)); +#endif + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::DELETE)); +} + + +void BookmarksContextMenu::addFolderActions() +{ + KBookmarkGroup group = bookmark().toGroup(); + + if (bookmark().internalElement().attributeNode("toolbar").value() == "yes") + { + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::UNSET_TOOLBAR_FOLDER)); + } + else + { + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::SET_TOOLBAR_FOLDER)); + } + + if (!group.first().isNull()) + { + KBookmark child = group.first(); + + while (child.isGroup() || child.isSeparator()) + { + child = group.next(child); + } + + if (!child.isNull()) + { + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::OPEN_FOLDER)); + addSeparator(); + } + } + + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::BOOKMARK_PAGE)); + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::NEW_FOLDER)); + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::NEW_SEPARATOR)); + + addSeparator(); + + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::EDIT)); + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::DELETE)); +} + + +void BookmarksContextMenu::addSeparatorActions() +{ + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::BOOKMARK_PAGE)); + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::NEW_FOLDER)); + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::NEW_SEPARATOR)); + + addSeparator(); + + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::DELETE)); +} + + +void BookmarksContextMenu::addNullActions() +{ + KBookmarkManager *mngr = manager(); + if (mngr->toolbar().hasParent()) + { + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::UNSET_TOOLBAR_FOLDER)); + } + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::BOOKMARK_PAGE)); + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::NEW_FOLDER)); + addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::NEW_SEPARATOR)); +} + + +void BookmarksContextMenu::addActions() +{ + if (bookmark().isNull() || m_nullForced) + { + addNullActions(); + } + else if (bookmark().isSeparator()) + { + addSeparatorActions(); + } + else if (bookmark().isGroup()) + { + addFolderActions(); + } + else + { + addBookmarkActions(); + } +} diff --git a/src/bookmarks/bookmarkscontextmenu.h b/src/bookmarks/bookmarkscontextmenu.h new file mode 100644 index 00000000..c927f3a6 --- /dev/null +++ b/src/bookmarks/bookmarkscontextmenu.h @@ -0,0 +1,57 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +#ifndef BOOKMARKS_CONTEXT_MENU_H +#define BOOKMARKS_CONTEXT_MENU_H + +// KDE Includes +#include <KBookmarkMenu> + +// Forward Declarations +class BookmarkOwner; + + +class BookmarksContextMenu : public KBookmarkContextMenu +{ +public: + BookmarksContextMenu(const KBookmark &bookmark, + KBookmarkManager *manager, + BookmarkOwner *owner, + bool nullForced = false, + QWidget *parent = 0); + virtual void addActions(); + +private: + void addFolderActions(); + void addBookmarkActions(); + void addSeparatorActions(); + void addNullActions(); + + BookmarkOwner *m_bmOwner; + bool m_nullForced; +}; + +#endif // BOOKMARKS_CONTEXT_MENU_H diff --git a/src/bookmarks/bookmarkstoolbar.cpp b/src/bookmarks/bookmarkstoolbar.cpp new file mode 100644 index 00000000..cb3fe382 --- /dev/null +++ b/src/bookmarks/bookmarkstoolbar.cpp @@ -0,0 +1,609 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2012 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +// Self Includes +#include "bookmarkstoolbar.h" +#include "bookmarkstoolbar.moc" + +// Local Includes +#include "bookmarkscontextmenu.h" +#include "bookmarkmanager.h" +#include "bookmarkowner.h" + +#include "webwindow.h" + +// Qt Includes +#include <QFrame> +#include <QActionEvent> +#include <QApplication> + + +BookmarkMenu::BookmarkMenu(KBookmarkManager *manager, + KBookmarkOwner *owner, + KMenu *menu, + KActionCollection* actionCollection) + : KBookmarkMenu(manager, owner, menu, actionCollection) +{ +} + + +BookmarkMenu::BookmarkMenu(KBookmarkManager *manager, + KBookmarkOwner *owner, + KMenu *parentMenu, + const QString &parentAddress) + : KBookmarkMenu(manager, owner, parentMenu, parentAddress) +{ +} + + +BookmarkMenu::~BookmarkMenu() +{ + kDebug() << "Deleting BookmarkMenu.. See http://svn.reviewboard.kde.org/r/5606/ about."; +} + + +KMenu * BookmarkMenu::contextMenu(QAction *act) +{ + KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(act); + if (!action) + return 0; + return new BookmarksContextMenu(action->bookmark(), manager(), static_cast<BookmarkOwner*>(owner())); +} + + +QAction * BookmarkMenu::actionForBookmark(const KBookmark &bookmark) +{ + if (bookmark.isGroup()) + { + KBookmarkActionMenu *actionMenu = new KBookmarkActionMenu(bookmark, this); + BookmarkMenu *menu = new BookmarkMenu(manager(), owner(), actionMenu->menu(), bookmark.address()); + // An hack to get rid of bug 219274 + connect(actionMenu, SIGNAL(hovered()), menu, SLOT(slotAboutToShow())); + return actionMenu; + } + else if (bookmark.isSeparator()) + { + return KBookmarkMenu::actionForBookmark(bookmark); + } + else + { + KBookmarkAction *action = new KBookmarkAction(bookmark, owner(), this); +// FIXME action->setIcon(rApp->iconManager()->iconForUrl(KUrl(bookmark.url()))); + connect(action, SIGNAL(hovered()), this, SLOT(actionHovered())); + return action; + } +} + + +void BookmarkMenu::refill() +{ + clear(); + fillBookmarks(); + + if (parentMenu()->actions().count() > 0) + parentMenu()->addSeparator(); + + if (isRoot()) + { + addAddBookmarksList(); + addEditBookmarks(); + } + else + { + addOpenFolderInTabs(); + addAddBookmarksList(); + } +} + + +void BookmarkMenu::addOpenFolderInTabs() +{ + KBookmarkGroup group = manager()->findByAddress(parentAddress()).toGroup(); + + if (!group.first().isNull()) + { + KBookmark bookmark = group.first(); + + while (bookmark.isGroup() || bookmark.isSeparator()) + { + bookmark = group.next(bookmark); + } + + if (!bookmark.isNull()) + { + parentMenu()->addAction(BookmarkManager::self()->owner()->createAction(group, BookmarkOwner::OPEN_FOLDER)); + } + } +} + + +// ------------------------------------------------------------------------------------------------------ + + +BookmarkToolBar::BookmarkToolBar(KToolBar *toolBar, QObject *parent) + : QObject(parent) + , m_toolBar(toolBar) + , m_currentMenu(0) + , m_dragAction(0) + , m_dropAction(0) + , m_checkedAction(0) + , m_filled(false) +{ + toolBar->setContextMenuPolicy(Qt::CustomContextMenu); + connect(toolBar, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenu(QPoint))); + connect(BookmarkManager::self()->manager(), SIGNAL(changed(QString, QString)), this, SLOT(hideMenu())); + toolBar->setAcceptDrops(true); + toolBar->installEventFilter(this); + toolBar->setShortcutEnabled(false); + + if (toolBar->isVisible()) + { + BookmarkManager::self()->fillBookmarkBar(this); + m_filled = true; + } +} + + +KToolBar* BookmarkToolBar::toolBar() +{ + return m_toolBar; +} + + +void BookmarkToolBar::contextMenu(const QPoint &point) +{ + KBookmarkActionInterface *action = dynamic_cast<KBookmarkActionInterface*>(toolBar()->actionAt(point)); + KBookmark bookmark = BookmarkManager::self()->manager()->toolbar(); + bool nullAction = true; + if (action) + { + bookmark = action->bookmark(); + nullAction = false; + } + + BookmarksContextMenu menu(bookmark, + BookmarkManager::self()->manager(), + BookmarkManager::self()->owner(), + nullAction); + menu.exec(toolBar()->mapToGlobal(point)); +} + + +void BookmarkToolBar::menuDisplayed() +{ + qApp->installEventFilter(this); + m_currentMenu = qobject_cast<KMenu*>(sender()); +} + + +void BookmarkToolBar::menuHidden() +{ + qApp->removeEventFilter(this); + m_currentMenu = 0; +} + + +void BookmarkToolBar::hideMenu() +{ + if (m_currentMenu) + m_currentMenu->hide(); +} + + +bool BookmarkToolBar::eventFilter(QObject *watched, QEvent *event) +{ + if (m_currentMenu && m_currentMenu->isVisible() + && !m_currentMenu->rect().contains(m_currentMenu->mapFromGlobal(QCursor::pos()))) + { + // To switch root folders as in a menubar + + KBookmarkActionMenu* act = dynamic_cast<KBookmarkActionMenu *>(toolBar()->actionAt(toolBar()->mapFromGlobal(QCursor::pos()))); + + if (event->type() == QEvent::MouseMove && act && act->menu() != m_currentMenu) + { + m_currentMenu->hide(); + QPoint pos = toolBar()->mapToGlobal(toolBar()->widgetForAction(act)->pos()); + act->menu()->popup(QPoint(pos.x(), pos.y() + toolBar()->widgetForAction(act)->height())); + } + else if (event->type() == QEvent::MouseButtonPress && act) + { + m_currentMenu->hide(); + } + + return QObject::eventFilter(watched, event); + } + + switch (event->type()) + { + case QEvent::Show: + { + if (!m_filled) + { + BookmarkManager::self()->fillBookmarkBar(this); + m_filled = true; + } + } + break; + + case QEvent::ActionRemoved: + { + QActionEvent *actionEvent = static_cast<QActionEvent*>(event); + if (actionEvent && actionEvent->action() != m_dropAction) + { + QWidget *widget = toolBar()->widgetForAction(actionEvent->action()); + if (widget) + { + widget->removeEventFilter(this); + } + } + } + break; + + case QEvent::ParentChange: + { + QActionEvent *actionEvent = static_cast<QActionEvent*>(event); + if (actionEvent && actionEvent->action() != m_dropAction) + { + QWidget *widget = toolBar()->widgetForAction(actionEvent->action()); + if (widget) + { + widget->removeEventFilter(this); + } + } + } + break; + + case QEvent::DragEnter: + { + QDragEnterEvent *dragEvent = static_cast<QDragEnterEvent*>(event); + if (dragEvent->mimeData()->hasFormat(BookmarkManager::bookmark_mime_type()) + || dragEvent->mimeData()->hasFormat("text/uri-list") + || dragEvent->mimeData()->hasFormat("text/plain")) + { + QFrame* dropIndicatorWidget = new QFrame(toolBar()); + dropIndicatorWidget->setFrameShape(QFrame::VLine); + m_dropAction = toolBar()->insertWidget(toolBar()->actionAt(dragEvent->pos()), dropIndicatorWidget); + + dragEvent->accept(); + } + } + break; + + case QEvent::DragLeave: + { + QDragLeaveEvent *dragEvent = static_cast<QDragLeaveEvent*>(event); + + if (m_checkedAction) + { + m_checkedAction->setCheckable(false); + m_checkedAction->setChecked(false); + } + + delete m_dropAction; + m_dropAction = 0; + dragEvent->accept(); + } + break; + + case QEvent::DragMove: + { + QDragMoveEvent *dragEvent = static_cast<QDragMoveEvent*>(event); + if (dragEvent->mimeData()->hasFormat(BookmarkManager::bookmark_mime_type()) + || dragEvent->mimeData()->hasFormat("text/uri-list") + || dragEvent->mimeData()->hasFormat("text/plain")) + { + QAction *overAction = toolBar()->actionAt(dragEvent->pos()); + KBookmarkActionInterface *overActionBK = dynamic_cast<KBookmarkActionInterface*>(overAction); + QWidget *widgetAction = toolBar()->widgetForAction(overAction); + + if (overAction != m_dropAction && overActionBK && widgetAction && m_dropAction) + { + toolBar()->removeAction(m_dropAction); + if (m_checkedAction) + { + m_checkedAction->setCheckable(false); + m_checkedAction->setChecked(false); + } + + if (!overActionBK->bookmark().isGroup()) + { + if ((dragEvent->pos().x() - widgetAction->pos().x()) > (widgetAction->width() / 2)) + { + if (toolBar()->actions().count() > toolBar()->actions().indexOf(overAction) + 1) + { + toolBar()->insertAction(toolBar()->actions().at(toolBar()->actions().indexOf(overAction) + 1), m_dropAction); + } + else + { + toolBar()->addAction(m_dropAction); + } + } + else + { + toolBar()->insertAction(overAction, m_dropAction); + } + } + else + { + if ((dragEvent->pos().x() - widgetAction->pos().x()) >= (widgetAction->width() * 0.75)) + { + if (toolBar()->actions().count() > toolBar()->actions().indexOf(overAction) + 1) + { + toolBar()->insertAction(toolBar()->actions().at(toolBar()->actions().indexOf(overAction) + 1), m_dropAction); + } + else + { + toolBar()->addAction(m_dropAction); + } + } + else if ((dragEvent->pos().x() - widgetAction->pos().x()) <= (widgetAction->width() * 0.25)) + { + toolBar()->insertAction(overAction, m_dropAction); + } + else + { + overAction->setCheckable(true); + overAction->setChecked(true); + m_checkedAction = overAction; + } + } + + dragEvent->accept(); + } + } + } + break; + + + case QEvent::Drop: + { + QDropEvent *dropEvent = static_cast<QDropEvent*>(event); + KBookmark bookmark; + KBookmarkGroup root = BookmarkManager::self()->manager()->toolbar(); + + if (m_checkedAction) + { + m_checkedAction->setCheckable(false); + m_checkedAction->setChecked(false); + } + + if (dropEvent->mimeData()->hasFormat(BookmarkManager::bookmark_mime_type())) + { + QByteArray addresses = dropEvent->mimeData()->data(BookmarkManager::bookmark_mime_type()); + bookmark = BookmarkManager::self()->findByAddress(QString::fromLatin1(addresses.data())); + if (bookmark.isNull()) + return false; + } + else if (dropEvent->mimeData()->hasFormat("text/uri-list")) + { + // DROP is URL + QString url = dropEvent->mimeData()->urls().at(0).toString(); + WebWindow *w = qobject_cast<WebWindow *>(parent()); + QString title = url.contains(w->url().toString()) + ? w->title() + : url; + bookmark = root.addBookmark(title, url); + } + else if (dropEvent->mimeData()->hasFormat("text/plain")) + { + // DROP is TEXT + QString url = dropEvent->mimeData()->text(); + KUrl u(url); + if (u.isValid()) + { + WebWindow *w = qobject_cast<WebWindow *>(parent()); + QString title = url.contains(w->url().toString()) + ? w->title() + : url; + bookmark = root.addBookmark(title, url); + } + } + else + { + return false; + } + + QAction *destAction = toolBar()->actionAt(dropEvent->pos()); + if (destAction && destAction == m_dropAction) + { + if (toolBar()->actions().indexOf(m_dropAction) > 0) + { + destAction = toolBar()->actions().at(toolBar()->actions().indexOf(m_dropAction) - 1); + } + else + { + destAction = toolBar()->actions().at(1); + } + } + + if (destAction) + { + KBookmarkActionInterface *destBookmarkAction = dynamic_cast<KBookmarkActionInterface *>(destAction); + QWidget *widgetAction = toolBar()->widgetForAction(destAction); + + if (destBookmarkAction && !destBookmarkAction->bookmark().isNull() && widgetAction + && bookmark.address() != destBookmarkAction->bookmark().address()) + { + KBookmark destBookmark = destBookmarkAction->bookmark(); + + if (!destBookmark.isGroup()) + { + if ((dropEvent->pos().x() - widgetAction->pos().x()) >= (widgetAction->width() / 2)) + { + root.moveBookmark(bookmark, destBookmark); + } + else + { + root.moveBookmark(bookmark, destBookmark.parentGroup().previous(destBookmark)); + } + } + else + { + if ((dropEvent->pos().x() - widgetAction->pos().x()) >= (widgetAction->width() * 0.75)) + { + root.moveBookmark(bookmark, destBookmark); + } + else if ((dropEvent->pos().x() - widgetAction->pos().x()) <= (widgetAction->width() * 0.25)) + { + root.moveBookmark(bookmark, destBookmark.parentGroup().previous(destBookmark)); + } + else + { + destBookmark.toGroup().addBookmark(bookmark); + } + } + + + BookmarkManager::self()->emitChanged(); + } + } + else + { + root.deleteBookmark(bookmark); + bookmark = root.addBookmark(bookmark); + if (dropEvent->pos().x() < toolBar()->widgetForAction(toolBar()->actions().first())->pos().x()) + { + root.moveBookmark(bookmark, KBookmark()); + } + + BookmarkManager::self()->emitChanged(); + } + dropEvent->accept(); + } + break; + + default: + break; + } + + QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); + + // These events need to be handled only for Bookmark actions and not the bar + if (watched != toolBar() && mouseEvent) + { + switch (event->type()) + { + case QEvent::MouseButtonPress: // drag handling + { + QPoint pos = toolBar()->mapFromGlobal(QCursor::pos()); + KBookmarkActionInterface *action = dynamic_cast<KBookmarkActionInterface *>(toolBar()->actionAt(pos)); + + if (action && mouseEvent->button() != Qt::MidButton) + { + m_dragAction = toolBar()->actionAt(pos); + m_startDragPos = pos; + + // The menu is displayed only when the mouse button is released + if (action->bookmark().isGroup()) + return true; + } + } + break; + + case QEvent::MouseMove: + { + int distance = (toolBar()->mapFromGlobal(QCursor::pos()) - m_startDragPos).manhattanLength(); + if (!m_currentMenu && distance >= QApplication::startDragDistance()) + { + startDrag(); + } + } + break; + + case QEvent::MouseButtonRelease: + { + QPoint destPos = toolBar()->mapFromGlobal(QCursor::pos()); + int distance = (destPos - m_startDragPos).manhattanLength(); + KBookmarkActionInterface *action = dynamic_cast<KBookmarkActionInterface *>(toolBar()->actionAt(destPos)); + + if (action && action->bookmark().isGroup()) + { + if (mouseEvent->button() == Qt::MidButton) + { + BookmarkManager::self()->owner()->openBookmarkFolder(action->bookmark()); + } + else if (distance < QApplication::startDragDistance()) + { + KBookmarkActionMenu *menu = dynamic_cast<KBookmarkActionMenu *>(toolBar()->actionAt(m_startDragPos)); + QPoint actionPos = toolBar()->mapToGlobal(toolBar()->widgetForAction(menu)->pos()); + menu->menu()->popup(QPoint(actionPos.x(), actionPos.y() + toolBar()->widgetForAction(menu)->height())); + } + } + } + break; + + default: + break; + } + } + + return QObject::eventFilter(watched, event); +} + + +void BookmarkToolBar::startDrag() +{ + KBookmarkActionInterface *action = dynamic_cast<KBookmarkActionInterface *>(m_dragAction); + if (action) + { + QMimeData *mimeData = new QMimeData; + KBookmark bookmark = action->bookmark(); + + QByteArray address = bookmark.address().toLatin1(); + mimeData->setData(BookmarkManager::bookmark_mime_type(), address); + bookmark.populateMimeData(mimeData); + + QDrag *drag = new QDrag(toolBar()); + drag->setMimeData(mimeData); + + if (bookmark.isGroup()) + { + drag->setPixmap(KIcon(bookmark.icon()).pixmap(24, 24)); + } +// else +// { +// drag->setPixmap(rApp->iconManager()->iconForUrl(action->bookmark().url()).pixmap(24, 24)); +// } + + drag->start(Qt::MoveAction); + connect(drag, SIGNAL(destroyed()), this, SLOT(dragDestroyed())); + } +} + + +void BookmarkToolBar::dragDestroyed() +{ + // A workaround to get rid of the checked state of the dragged action + if (m_dragAction) + { + m_dragAction->setVisible(false); + m_dragAction->setVisible(true); + m_dragAction = 0; + } + delete m_dropAction; + m_dropAction = 0; +} diff --git a/src/bookmarks/bookmarkstoolbar.h b/src/bookmarks/bookmarkstoolbar.h new file mode 100644 index 00000000..e2ed6e3a --- /dev/null +++ b/src/bookmarks/bookmarkstoolbar.h @@ -0,0 +1,111 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2012 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + +#ifndef BOOKMARKSTOOLBAR_H +#define BOOKMARKSTOOLBAR_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// KDE Includes +#include <KBookmarkMenu> + +/** + * This class represent the rekonq bookmarks menu. + * It's just a simple class inherited from KBookmarkMenu + * + */ +class BookmarkMenu : public KBookmarkMenu +{ + Q_OBJECT + +public: + BookmarkMenu(KBookmarkManager* manager, + KBookmarkOwner* owner, + KMenu* menu, + KActionCollection* actionCollection); + BookmarkMenu(KBookmarkManager *manager, + KBookmarkOwner *owner, + KMenu *parentMenu, + const QString &parentAddress); + ~BookmarkMenu(); + +protected: + virtual KMenu * contextMenu(QAction * act); + virtual void refill(); + virtual QAction* actionForBookmark(const KBookmark &bookmark); + +private: + void addOpenFolderInTabs(); + +}; + + +// ------------------------------------------------------------------------------ + + +// KDE Includes +#include <KToolBar> + + +/** + * This class manage the bookmark toolbar. + * Some events from the toolbar are handled to allow the drag and drop + */ + +class BookmarkToolBar : public QObject +{ + Q_OBJECT + +public: + BookmarkToolBar(KToolBar *toolBar, QObject *parent); + + KToolBar* toolBar(); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private Q_SLOTS: + void contextMenu(const QPoint &); + void menuDisplayed(); + void menuHidden(); + void hideMenu(); + void dragDestroyed(); + +private: + void startDrag(); + + KToolBar *m_toolBar; + KMenu *m_currentMenu; + QPoint m_startDragPos; + QAction *m_dragAction; + QAction *m_dropAction; + QAction *m_checkedAction; + bool m_filled; +}; + +#endif // BOOKMARKSTOOLBAR_H |