diff options
Diffstat (limited to 'src/bookmarks')
| -rw-r--r-- | src/bookmarks/bookmarkcontextmenu.cpp | 331 | ||||
| -rw-r--r-- | src/bookmarks/bookmarkcontextmenu.h | 68 | ||||
| -rw-r--r-- | src/bookmarks/bookmarksmanager.cpp | 296 | ||||
| -rw-r--r-- | src/bookmarks/bookmarksmanager.h | 54 | ||||
| -rw-r--r-- | src/bookmarks/bookmarkspanel.cpp | 159 | ||||
| -rw-r--r-- | src/bookmarks/bookmarkspanel.h | 32 | ||||
| -rw-r--r-- | src/bookmarks/bookmarksproxy.cpp | 19 | ||||
| -rw-r--r-- | src/bookmarks/bookmarksproxy.h | 16 | ||||
| -rw-r--r-- | src/bookmarks/bookmarkstreemodel.cpp | 364 | ||||
| -rw-r--r-- | src/bookmarks/bookmarkstreemodel.h | 64 | 
10 files changed, 1145 insertions, 258 deletions
diff --git a/src/bookmarks/bookmarkcontextmenu.cpp b/src/bookmarks/bookmarkcontextmenu.cpp new file mode 100644 index 00000000..47608710 --- /dev/null +++ b/src/bookmarks/bookmarkcontextmenu.cpp @@ -0,0 +1,331 @@ +/* ============================================================ +* +* 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/>. +* +* ============================================================ */ + + +// Self Includes +#include "bookmarkcontextmenu.h" +#include "bookmarkcontextmenu.moc" + +// Local Includes +#include "application.h" +#include "bookmarksmanager.h" + +// KDE Includes +#include <KMessageBox> +#include <KActionCollection> +#include <KBookmarkDialog> + +// Qt Includes +#include <QClipboard> + + +BookmarkContextMenu::BookmarkContextMenu(const KBookmark & bookmark, KBookmarkManager *manager, KBookmarkOwner *owner, QWidget *parent) +        : KBookmarkContextMenu(bookmark, manager, owner, parent) +        , m_ac(new KActionCollection(this)) +{ +    setupActions(); +} + + +BookmarkContextMenu::~BookmarkContextMenu() +{ +    delete m_ac; +} + + +void BookmarkContextMenu::setupActions() +{ +    KAction* action; + +    action = new KAction(KIcon("tab-new"), i18n("Open"), this); +    connect(action, SIGNAL(triggered()), this, SLOT(openInCurrentTab())); +    m_ac->addAction("open", action); + +    action = new KAction(KIcon("tab-new"), i18n("Open in New Tab"), this); +    connect(action, SIGNAL(triggered()), this, SLOT(openInNewTab())); +    m_ac->addAction("open_tab", action); + +    action = new KAction(KIcon("window-new"), i18n("Open in New Window"), this); +    connect(action, SIGNAL(triggered()), this, SLOT(openInNewWindow())); +    m_ac->addAction("open_window", action); + +    action = new KAction(KIcon("bookmark-new"), i18n("Add Bookmark Here"), this); +    connect(action, SIGNAL(triggered()), this, SLOT(bookmarkCurrentPage())); +    m_ac->addAction("bookmark_page", action); + +    action = new KAction(KIcon("folder-new"), i18n("New Bookmark Folder"), this); +    connect(action, SIGNAL(triggered()), this, SLOT(newBookmarkGroup())); +    m_ac->addAction("folder_new", action); + +    action = new KAction(KIcon("edit-clear"), i18n("New Separator"), this); +    connect(action, SIGNAL(triggered()), this, SLOT(newSeparator())); +    m_ac->addAction("separator_new", action); + +    action = new KAction(KIcon("edit-copy"), i18n("Copy Link Address"), this); +    connect(action, SIGNAL(triggered()), this, SLOT(copyToClipboard())); +    m_ac->addAction("copy", action); + +    action = new KAction(KIcon("edit-delete"), i18n("Delete Bookmark"), this); +    connect(action, SIGNAL(triggered()), this, SLOT(deleteBookmark())); +    m_ac->addAction("delete", action); + +    action = new KAction(KIcon("configure"), i18n("Properties"), this); +    connect(action, SIGNAL(triggered()), this, SLOT(editBookmark())); +    m_ac->addAction("properties", action); + +    action = new KAction(KIcon("tab-new"), i18n("Open Folder in Tabs"), this); +    connect(action, SIGNAL(triggered()), this, SLOT(openFolderInTabs())); +    m_ac->addAction("open_all", action); +} + + +void BookmarkContextMenu::addBookmarkActions() +{ +    addAction(m_ac->action("open")); +    addAction(m_ac->action("open_tab")); +    addAction(m_ac->action("open_window")); + +    addSeparator(); + +    addAction(m_ac->action("bookmark_page")); +    addAction(m_ac->action("folder_new")); +    addAction(m_ac->action("separator_new")); + +    addSeparator(); + +    addAction(m_ac->action("copy")); + +    addSeparator(); + +    addAction(m_ac->action("delete")); +    addAction(m_ac->action("properties")); +} + + +void BookmarkContextMenu::addFolderActions() +{ +    if (!bookmark().toGroup().first().isNull()) +    { +        addAction(m_ac->action("open_all")); +        addSeparator(); +    } + +    addAction(m_ac->action("bookmark_page")); +    addAction(m_ac->action("folder_new")); +    addAction(m_ac->action("separator_new")); + +    addSeparator(); + +    addAction(m_ac->action("delete")); +    addAction(m_ac->action("properties")); +} + + +void BookmarkContextMenu::addSeparatorActions() +{ +    addAction(m_ac->action("bookmark_page")); +    addAction(m_ac->action("folder_new")); +    addAction(m_ac->action("separator_new")); + +    addSeparator(); + +    addAction(m_ac->action("delete")); +} + + +void BookmarkContextMenu::addActions() +{ +    if (bookmark().isGroup()) +    { +        addFolderActions(); +    } + +    else if (bookmark().isSeparator()) +    { +        addSeparatorActions(); +    } + +    else if (bookmark().isNull()) +    { +        addAction(m_ac->action("bookmark_page")); +        addAction(m_ac->action("folder_new")); +        addAction(m_ac->action("separator_new")); +    } + +    else +    { +        addBookmarkActions(); +    } +} + + +void BookmarkContextMenu::openInCurrentTab() +{ +    Application::instance()->loadUrl(bookmark().url()); +} + + +void BookmarkContextMenu::openInNewTab() +{ +    Application::instance()->loadUrl(bookmark().url(), Rekonq::SettingOpenTab); +} + + +void BookmarkContextMenu::openInNewWindow() +{ +    Application::instance()->loadUrl(bookmark().url(), Rekonq::NewWindow); +} + + +void BookmarkContextMenu::copyToClipboard() +{ +    if (bookmark().isNull()) +        return; + +    QClipboard *cb = QApplication::clipboard(); +    cb->setText(bookmark().url().url()); +} + + +void BookmarkContextMenu::deleteBookmark() +{ +    KBookmark bm = bookmark(); +    bool folder = bm.isGroup(); + +    if (KMessageBox::warningContinueCancel( +                QApplication::activeWindow(), +                folder ? i18n("Are you sure you wish to remove the bookmark folder\n\"%1\"?", bm.text()) +                : i18n("Are you sure you wish to remove the bookmark\n\"%1\"?", bm.text()), +                folder ? i18n("Bookmark Folder Deletion") +                : i18n("Bookmark Deletion"), +                KStandardGuiItem::del()) +            != KMessageBox::Continue +       ) +        return; + +    bm.parentGroup().deleteBookmark(bm); +    manager()->emitChanged(); +} + + +void BookmarkContextMenu::editBookmark() +{ +    KBookmark selected = bookmark(); + +    KBookmarkDialog *dialog = owner()->bookmarkDialog(manager(), QApplication::activeWindow()); +    dialog->editBookmark(selected); +    delete dialog; +} + + +void BookmarkContextMenu::openFolderInTabs() +{ +    if (bookmark().isGroup()) +        owner()->openFolderinTabs(bookmark().toGroup()); +} + + +void BookmarkContextMenu::newBookmarkGroup() +{ +    KBookmark selected = bookmark(); +    KBookmarkDialog *dialog = owner()->bookmarkDialog(manager(), QApplication::activeWindow()); + +    if (!selected.isNull()) +    { +        if (selected.isGroup()) +        { +            dialog->createNewFolder("New folder", selected); +        } + +        else +        { +            KBookmark newBk; +            newBk = dialog->createNewFolder("New folder", selected.parentGroup()); +            selected.parentGroup().moveBookmark(newBk, selected); +            manager()->emitChanged(); +        } +    } +    else +    { +        dialog->createNewFolder("New folder"); +    } + +    delete dialog; +} + + +void BookmarkContextMenu::newSeparator() +{ +    KBookmark selected = bookmark(); +    KBookmark newBk; + +    if (!selected.isNull()) +    { +        if (selected.isGroup()) +            newBk = selected.toGroup().createNewSeparator(); +        else +            newBk = selected.parentGroup().createNewSeparator(); +    } + +    else +    { +        newBk = Application::bookmarkProvider()->rootGroup().createNewSeparator(); +    } + +    KBookmarkGroup parent = newBk.parentGroup(); +    newBk.setIcon(("edit-clear")); +    parent.addBookmark(newBk); + +    if (!selected.isNull()) +        parent.moveBookmark(newBk, selected); + +    manager()->emitChanged(); +} + + +void BookmarkContextMenu::bookmarkCurrentPage() +{ +    KBookmarkGroup parent = Application::bookmarkProvider()->rootGroup(); +    KBookmark selected = bookmark(); + +    if (!selected.isNull()) +    { +        parent = selected.parentGroup(); + +        if (selected.isGroup()) +            parent = selected.toGroup(); + +        KBookmark newBk = parent.addBookmark(owner()->currentTitle(), KUrl(owner()->currentUrl()), "text-html"); +        parent.moveBookmark(newBk, selected.parentGroup().previous(selected)); +    } + +    else +    { +        parent.addBookmark(owner()->currentTitle(), KUrl(owner()->currentUrl()), "text-html"); +    } + +    manager()->emitChanged(); +} + diff --git a/src/bookmarks/bookmarkcontextmenu.h b/src/bookmarks/bookmarkcontextmenu.h new file mode 100644 index 00000000..ebbfd6e8 --- /dev/null +++ b/src/bookmarks/bookmarkcontextmenu.h @@ -0,0 +1,68 @@ +/* ============================================================ +* +* 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 BOOKMARKCONTEXTMENU_H +#define BOOKMARKCONTEXTMENU_H + +// Local Includes +#include "application.h" + +// Qt Includes +#include <KBookmarkMenu> + + +class BookmarkContextMenu : public KBookmarkContextMenu +{ +    Q_OBJECT + +public: +    BookmarkContextMenu(const KBookmark & bk, KBookmarkManager * manager, KBookmarkOwner *owner, QWidget * parent = 0); +    ~BookmarkContextMenu(); +     +    virtual void addActions(); + +private slots: +    void openInCurrentTab(); +    void openInNewTab(); +    void openInNewWindow(); +    void copyToClipboard(); +    void deleteBookmark(); +    void openFolderInTabs(); +    void editBookmark(); +    void newBookmarkGroup(); +    void newSeparator(); +    void bookmarkCurrentPage(); + +private: +    void setupActions(); +    void addFolderActions(); +    void addBookmarkActions(); +    void addSeparatorActions(); + +    KActionCollection *m_ac; +}; + +#endif // BOOKMARKCONTEXTMENU_H diff --git a/src/bookmarks/bookmarksmanager.cpp b/src/bookmarks/bookmarksmanager.cpp index 6442192a..bfa8d238 100644 --- a/src/bookmarks/bookmarksmanager.cpp +++ b/src/bookmarks/bookmarksmanager.cpp @@ -2,9 +2,10 @@  *  * This file is a part of the rekonq project  * -* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>  * Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com> -* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr> +* 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 @@ -12,9 +13,9 @@  * 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  +* 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 @@ -34,25 +35,24 @@  #include "mainwindow.h"  #include "webtab.h"  #include "webview.h" +#include "mainview.h" +#include "bookmarkcontextmenu.h"  // KDE Includes  #include <KActionCollection> -#include <KBookmark>  #include <KBookmarkAction>  #include <KBookmarkGroup> -#include <KBookmarkMenu>  #include <KToolBar> -#include <KDebug>  #include <KMenu>  #include <KStandardDirs>  #include <KUrl> +#include <KMessageBox>  // Qt Includes  #include <QtCore/QFile>  #include <QtGui/QActionGroup> -  BookmarkOwner::BookmarkOwner(QObject *parent)          : QObject(parent)          , KBookmarkOwner() @@ -66,7 +66,7 @@ void BookmarkOwner::openBookmark(const KBookmark & bookmark,  {      if (keyboardModifiers & Qt::ControlModifier || mouseButtons == Qt::MidButton)      { -        emit openUrl(bookmark.url(), Rekonq::NewCurrentTab); +        emit openUrl(bookmark.url(), Rekonq::SettingOpenTab);      }      else      { @@ -93,14 +93,37 @@ QString BookmarkOwner::currentTitle() const  } -void BookmarkOwner::openFolderinTabs(const KBookmarkGroup &bm) +void BookmarkOwner::openFolderinTabs(const KBookmarkGroup &bookmark)  { -    QList<KUrl> urlList = bm.groupUrlList(); +    QList<KUrl> urlList = bookmark.groupUrlList(); + +    if (urlList.length() > 8) +    { +        if (!(KMessageBox::warningContinueCancel(Application::instance()->mainWindow(), i18n("You are about to open %1 tabs.\nAre you sure  ?", QString::number(urlList.length()))) == KMessageBox::Continue)) +            return; +    } +      QList<KUrl>::iterator url;      for (url = urlList.begin(); url != urlList.end(); ++url)      { -        Application::instance()->loadUrl(*url, Rekonq::NewCurrentTab); +        emit openUrl(*url, Rekonq::NewCurrentTab); +    } +} + + +QList< QPair<QString, QString> > BookmarkOwner::currentBookmarkList() const +{ +    QList< QPair<QString, QString> > bkList; +    int tabNumber = Application::instance()->mainWindow()->mainView()->count(); + +    for (int i = 0; i < tabNumber; i++) +    { +        QPair<QString, QString> item; +        item.first = Application::instance()->mainWindow()->mainView()->webTab(i)->view()->title(); +        item.second = Application::instance()->mainWindow()->mainView()->webTab(i)->url().url(); +        bkList += item;      } +    return bkList;  } @@ -112,26 +135,35 @@ BookmarkMenu::BookmarkMenu(KBookmarkManager *manager,                             KMenu *menu,                             KActionCollection* actionCollection)          : KBookmarkMenu(manager, owner, menu, actionCollection) -  {      KAction *a = KStandardAction::addBookmark(this, SLOT(slotAddBookmark()), this); -//     a->setText(i18n("Bookmark this Page")); -    actionCollection->addAction(QLatin1String("rekonq_add_bookmark"),a); +    actionCollection->addAction(QL1S("rekonq_add_bookmark"), a); +    refill();  } + +BookmarkMenu::BookmarkMenu(KBookmarkManager  *manager, +                           KBookmarkOwner  *owner, +                           KMenu  *parentMenu, +                           const QString &parentAddress) +        : KBookmarkMenu(manager, owner, parentMenu, parentAddress) +{ +    refill(); +} + +  BookmarkMenu::~BookmarkMenu()  {  } -KMenu *BookmarkMenu::viewContextMenu(QAction *action) +KMenu * BookmarkMenu::contextMenu(QAction *act)  { -    // contextMenu() returns an invalid  KMenu (seg fault) for the folders in the toolbar -    KMenu *menu = contextMenu(action); -    if(menu) -        return menu; -    return 0;   // new KMenu(); +    KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(act); +    if (!action) +        return 0; +    return new BookmarkContextMenu(action->bookmark(), manager(), owner());  } @@ -151,6 +183,76 @@ void BookmarkMenu::slotAddBookmark()  } +QAction * BookmarkMenu::actionForBookmark(const KBookmark &bookmark) +{ +    if (bookmark.isGroup()) +    { +        KBookmarkActionMenu *actionMenu = new KBookmarkActionMenu(bookmark, this); +        new BookmarkMenu(manager(), owner(), actionMenu->menu(), bookmark.address()); +        return actionMenu; +    } +    else if (bookmark.isSeparator()) +    { +        return KBookmarkMenu::actionForBookmark(bookmark); +    } +    else +    { +        Application::bookmarkProvider()->completionObject()->addItem(bookmark.url().url()); +        return  new KBookmarkAction(bookmark, owner(), this); +    } +} + + +void BookmarkMenu::refill() +{ +    fillBookmarks(); + +    if (parentMenu()->actions().count() > 0) +        parentMenu()->addSeparator(); + +    if (isRoot()) +    { +        addAddBookmark(); +        addAddBookmarksList(); +        addNewFolder(); +        addEditBookmarks(); + +    } +    else +    { +        addOpenFolderInTabs(); +        addAddBookmark(); +        addAddBookmarksList(); +        addNewFolder(); +    } +} + + +void BookmarkMenu::addOpenFolderInTabs() +{ +    KAction *action; +    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()) +        { +            action = new KAction(KIcon("tab-new"), i18n("Open Folder in Tabs"), this); +            action->setHelpText(i18n("Open all bookmarks in this folder as a new tab.")); +            connect(action, SIGNAL(triggered(bool)), this, SLOT(slotOpenFolderInTabs())); +            parentMenu()->addAction(action); +        } +    } +} + +  // ------------------------------------------------------------------------------------------------------ @@ -160,8 +262,12 @@ BookmarkProvider::BookmarkProvider(QObject *parent)          , m_owner(0)          , m_actionCollection(new KActionCollection(this))          , m_bookmarkMenu(0) -        , m_bookmarkToolBar(0) +        , m_completion(0)  { +    // take care of the completion object +    m_completion = new KCompletion; +    m_completion->setOrder(KCompletion::Weighted); +      KUrl bookfile = KUrl("~/.kde/share/apps/konqueror/bookmarks.xml");  // share konqueror bookmarks      if (!QFile::exists(bookfile.path())) @@ -178,7 +284,9 @@ BookmarkProvider::BookmarkProvider(QObject *parent)              bookfile = KUrl(bookmarksPath);          }      } -    m_manager = KBookmarkManager::managerForExternalFile(bookfile.path()); + +    m_manager = KBookmarkManager::managerForFile(bookfile.path(), "rekonq"); +      connect(m_manager, SIGNAL(changed(const QString &, const QString &)),              this, SLOT(slotBookmarksChanged(const QString &, const QString &))); @@ -194,40 +302,42 @@ BookmarkProvider::~BookmarkProvider()      delete m_actionCollection;      delete m_owner;      delete m_manager; + +    delete m_completion;  } -void BookmarkProvider::setupBookmarkBar(KToolBar *t) +void BookmarkProvider::setupBookmarkBar(KToolBar *toolbar)  { -    m_bookmarkToolBar = t; -    connect(m_bookmarkToolBar, SIGNAL(customContextMenuRequested(const QPoint &)), +    KToolBar *bookmarkToolBar = toolbar; +    m_bookmarkToolBars.append(bookmarkToolBar); +    bookmarkToolBar->setContextMenuPolicy(Qt::CustomContextMenu); +    connect(bookmarkToolBar, SIGNAL(customContextMenuRequested(const QPoint &)),              this, SLOT(contextMenu(const QPoint &)));      slotBookmarksChanged("", "");  } +void BookmarkProvider::removeToolBar(KToolBar *toolbar) +{ +    m_bookmarkToolBars.removeOne(toolbar); +} + +  void BookmarkProvider::slotBookmarksChanged(const QString &group, const QString &caller)  {      Q_UNUSED(group)      Q_UNUSED(caller) -    if (!m_bookmarkToolBar) -        return; - -    KBookmarkGroup toolBarGroup = m_manager->toolbar(); -    if (toolBarGroup.isNull()) -        return; +    m_completion->clear(); -    if(m_bookmarkToolBar) +    foreach(KToolBar *bookmarkToolBar, m_bookmarkToolBars)      { -        m_bookmarkToolBar->clear(); // FIXME CRASH - -        KBookmark bookmark = toolBarGroup.first(); -        while (!bookmark.isNull()) +        if (bookmarkToolBar)          { -            m_bookmarkToolBar->addAction(fillBookmarkBar(bookmark)); -            bookmark = toolBarGroup.next(bookmark); +            bookmarkToolBar->clear(); +            fillBookmarkBar(bookmarkToolBar);          }      }  } @@ -244,13 +354,19 @@ QAction *BookmarkProvider::actionByName(const QString &name)  void BookmarkProvider::contextMenu(const QPoint &point)  { -    KAction* action = dynamic_cast<KAction*>(m_bookmarkToolBar->actionAt(point)); -    if (!action) +    if (m_bookmarkToolBars.isEmpty())          return; -    KMenu *menu = m_bookmarkMenu->viewContextMenu(action); -    if (!menu) + +    KToolBar *bookmarkToolBar = m_bookmarkToolBars.at(0); +    if (!bookmarkToolBar)          return; -    menu->popup(m_bookmarkToolBar->mapToGlobal(point)); + +    KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(bookmarkToolBar->actionAt(point)); +    if (!action) +        return; + +    BookmarkContextMenu menu(action->bookmark(), bookmarkManager(), bookmarkOwner()); +    menu.exec(bookmarkToolBar->mapToGlobal(point));  } @@ -265,36 +381,90 @@ KActionMenu* BookmarkProvider::bookmarkActionMenu(QWidget *parent)  } -KAction *BookmarkProvider::fillBookmarkBar(const KBookmark &bookmark) +void BookmarkProvider::fillBookmarkBar(KToolBar *toolBar)  { -    if (bookmark.isGroup()) +    KBookmarkGroup root = m_manager->toolbar(); +    if (root.isNull()) +        return; + +    for (KBookmark bookmark = root.first(); !bookmark.isNull(); bookmark = root.next(bookmark))      { -        KBookmarkGroup group = bookmark.toGroup(); -        KBookmark bm = group.first(); -        KActionMenu *menuAction = new KActionMenu(KIcon(bookmark.icon()), bookmark.text(), this); -        menuAction->setDelayed(false); -        while (!bm.isNull()) +        if (bookmark.isGroup())          { -            menuAction->addAction(fillBookmarkBar(bm)); -            bm = group.next(bm); +            KBookmarkActionMenu *menuAction = new KBookmarkActionMenu(bookmark.toGroup(), this); +            menuAction->setDelayed(false); +            new BookmarkMenu(bookmarkManager(), bookmarkOwner(), menuAction->menu(), bookmark.address()); + +            toolBar->addAction(menuAction);          } -        return menuAction; + +        else if (bookmark.isSeparator()) +        { +            toolBar->addSeparator(); +        } + +        else +        { +            toolBar->addAction(new KBookmarkAction(bookmark, m_owner, this)); +        } +    } +} + + +KBookmarkGroup BookmarkProvider::rootGroup() +{ +    return m_manager->root(); +} + + +KCompletion *BookmarkProvider::completionObject() const +{ +    return m_completion; +} + + +QString BookmarkProvider::titleForBookmarkUrl(QString url) +{ +    QString title = ""; +    KBookmarkGroup bookGroup = Application::bookmarkProvider()->rootGroup(); +    if (bookGroup.isNull()) +    { +        return title;      } -  -    if(bookmark.isSeparator()) + +    KBookmark bookmark = bookGroup.first(); +    while (!bookmark.isNull() && title.isEmpty())      { -        KAction *a = new KAction(this); -        a->setSeparator(true); -        return a; +        title = titleForBookmarkUrl(bookmark, url); +        bookmark = bookGroup.next(bookmark);      } -    else + +    if (title.isEmpty())      { -        return new KBookmarkAction(bookmark, m_owner, this); +        title = url;      } + +    return title;  } -KBookmarkGroup BookmarkProvider::rootGroup() +QString BookmarkProvider::titleForBookmarkUrl(const KBookmark &bookmark, QString url)  { -    return m_manager->root(); +    QString title = ""; +    if (bookmark.isGroup()) +    { +        KBookmarkGroup group = bookmark.toGroup(); +        KBookmark bm = group.first(); +        while (!bm.isNull() && title.isEmpty()) +        { +            title = titleForBookmarkUrl(bm, url); // it is .bookfolder +            bm = group.next(bm); +        } +    } +    else if (!bookmark.isSeparator() && bookmark.url() == url) +    { +        title = bookmark.fullText(); +    } + +    return title;  } diff --git a/src/bookmarks/bookmarksmanager.h b/src/bookmarks/bookmarksmanager.h index febac234..ae12280b 100644 --- a/src/bookmarks/bookmarksmanager.h +++ b/src/bookmarks/bookmarksmanager.h @@ -2,9 +2,10 @@  *  * This file is a part of the rekonq project  * -* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>  * Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com> -* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr> +* 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 @@ -30,6 +31,9 @@  #define BOOKMARKS_H +// Rekonq Includes +#include "rekonq_defines.h" +  // Local Includes  #include "application.h" @@ -38,6 +42,7 @@  // KDE Includes  #include <KBookmarkOwner> +#include <KCompletion>  // Forward Declarations  class BookmarkProvider; @@ -55,7 +60,7 @@ class KBookmarkManager;   * bookmarks as actions   *   */ -class BookmarkOwner : public QObject , public KBookmarkOwner +class REKONQ_TESTS_EXPORT BookmarkOwner : public QObject , public KBookmarkOwner  {      Q_OBJECT @@ -110,7 +115,9 @@ public:      * The default implementation does nothing.      * This is only called if supportsTabs() returns true      */ -    virtual void openFolderinTabs(const KBookmarkGroup &bm); +    virtual void openFolderinTabs(const KBookmarkGroup &bookmark); + +    virtual QList< QPair<QString, QString> > currentBookmarkList() const;  signals:      /** @@ -128,7 +135,6 @@ signals:  // KDE Includes  #include <KBookmarkMenu> -  /**   * This class represent the rekonq bookmarks menu.   * It's just a simple class inherited from KBookmarkMenu @@ -143,13 +149,23 @@ public:                   KBookmarkOwner* owner,                   KMenu* menu,                   KActionCollection* actionCollection); +    BookmarkMenu(KBookmarkManager  *manager, +                 KBookmarkOwner  *owner, +                 KMenu  *parentMenu, +                 const QString &parentAddress);      ~BookmarkMenu(); -    virtual KMenu *viewContextMenu(QAction* action); +protected: +    virtual KMenu * contextMenu(QAction * act); +    virtual void refill(); +    virtual QAction* actionForBookmark(const KBookmark &bookmark);  protected slots:      void slotAddBookmark(); +private: +    void addOpenFolderInTabs(); +  }; @@ -192,6 +208,7 @@ public:      */      void setupBookmarkBar(KToolBar *); +    void removeToolBar(KToolBar*);      /**       * @short Get action by name @@ -209,7 +226,22 @@ public:       */      KBookmarkGroup rootGroup(); -	KBookmarkManager *bookmarkManager() { return m_manager; } +    KBookmarkManager *bookmarkManager() +    { +        return m_manager; +    } +    BookmarkOwner *bookmarkOwner() +    { +        return m_owner; +    } + +    /** +    * @returns the KCompletion object. +    */ +    KCompletion *completionObject() const; + +    QString titleForBookmarkUrl(QString url); +  signals:      /**      * @short This signal is emitted when an url has to be loaded @@ -236,14 +268,18 @@ public slots:       */      void slotBookmarksChanged(const QString &group, const QString &caller); +  private: -    KAction *fillBookmarkBar(const KBookmark &bookmark); +    void fillBookmarkBar(KToolBar *toolBar); +    QString titleForBookmarkUrl(const KBookmark &bookmark, QString url);      KBookmarkManager *m_manager;      BookmarkOwner *m_owner;      KActionCollection *m_actionCollection;      BookmarkMenu *m_bookmarkMenu; -    KToolBar *m_bookmarkToolBar; +    QList<KToolBar*> m_bookmarkToolBars; +    KCompletion *m_completion;  }; +  #endif diff --git a/src/bookmarks/bookmarkspanel.cpp b/src/bookmarks/bookmarkspanel.cpp index 9164dbb6..502af574 100644 --- a/src/bookmarks/bookmarkspanel.cpp +++ b/src/bookmarks/bookmarkspanel.cpp @@ -3,7 +3,8 @@  * This file is a part of the rekonq project  *  * Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com> -* +* Copyright (C) 2010 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 @@ -29,8 +30,10 @@  #include "bookmarkspanel.moc"  // Local Includes +#include "bookmarksmanager.h"  #include "bookmarkstreemodel.h"  #include "bookmarksproxy.h" +#include "bookmarkcontextmenu.h"  // Auto Includes  #include "rekonq.h" @@ -38,16 +41,19 @@  // Qt includes  #include <QHBoxLayout>  #include <QLabel> -#include <QTreeView>  #include <QHeaderView>  // KDE includes  #include <KLineEdit>  #include <KLocalizedString> +#include <KMenu> +#include <KMessageBox>  BookmarksPanel::BookmarksPanel(const QString &title, QWidget *parent, Qt::WindowFlags flags) -    : QDockWidget(title, parent, flags) +        : QDockWidget(title, parent, flags) +        , m_treeView(new PanelTreeView(this)) +        , m_loadingState(false)  {      setup();      setShown(ReKonfig::showBookmarksPanel()); @@ -60,13 +66,6 @@ BookmarksPanel::~BookmarksPanel()  } -void BookmarksPanel::bookmarkActivated( const QModelIndex &index ) -{ -    if( index.isValid() ) -        emit openUrl( qVariantValue< KUrl >( index.data( Qt::UserRole ) ) ); -} - -  void BookmarksPanel::setup()  {      setObjectName("bookmarksPanel"); @@ -82,32 +81,144 @@ void BookmarksPanel::setup()      KLineEdit *search = new KLineEdit;      search->setClearButtonShown(true);      searchLayout->addWidget(search); -    searchLabel->setBuddy( search ); +    searchLabel->setBuddy(search);      // setup tree view -    QTreeView *treeView = new QTreeView(ui); -    treeView->setUniformRowHeights(true); -    treeView->setSelectionBehavior(QAbstractItemView::SelectRows); -    treeView->setTextElideMode(Qt::ElideMiddle); -    treeView->setAlternatingRowColors(true); -    treeView->header()->hide(); -    treeView->setRootIsDecorated( false ); +    m_treeView->setUniformRowHeights(true); +    m_treeView->setTextElideMode(Qt::ElideMiddle); +    m_treeView->setAlternatingRowColors(true); +    m_treeView->header()->hide(); +    m_treeView->setDragEnabled(true); +    m_treeView->setAutoExpandDelay(750); +    m_treeView->setDefaultDropAction(Qt::MoveAction); +    m_treeView->viewport()->setAcceptDrops(true);      // put everything together      QVBoxLayout *vBoxLayout = new QVBoxLayout;      vBoxLayout->setContentsMargins(0, 0, 0, 0);      vBoxLayout->addLayout(searchLayout); -    vBoxLayout->addWidget(treeView); +    vBoxLayout->addWidget(m_treeView);      // add it to the UI      ui->setLayout(vBoxLayout);      setWidget(ui); -    BookmarksTreeModel *model = new BookmarksTreeModel( this ); +    BookmarksTreeModel *model = new BookmarksTreeModel(this);      BookmarksProxy *proxy = new BookmarksProxy(ui); -    proxy->setSourceModel( model ); -    treeView->setModel( proxy ); +    proxy->setSourceModel(model); +    m_treeView->setModel(proxy); + +    connect(m_treeView, SIGNAL(contextMenuItemRequested(const QPoint &)), this, SLOT(contextMenu(const QPoint &))); +    connect(m_treeView, SIGNAL(contextMenuGroupRequested(const QPoint &)), this, SLOT(contextMenu(const QPoint &))); +    connect(m_treeView, SIGNAL(contextMenuEmptyRequested(const QPoint &)), this, SLOT(contextMenu(const QPoint &))); +    connect(m_treeView, SIGNAL(delKeyPressed()), this, SLOT(deleteBookmark())); +    connect(m_treeView, SIGNAL(collapsed(const QModelIndex &)), this, SLOT(onCollapse(const QModelIndex &))); +    connect(m_treeView, SIGNAL(expanded(const QModelIndex &)), this, SLOT(onExpand(const QModelIndex &))); +    connect(search, SIGNAL(textChanged(const QString &)), proxy, SLOT(setFilterFixedString(const QString &))); +    loadFoldedState(); +} + + +KBookmark BookmarksPanel::bookmarkForIndex(const QModelIndex &index) +{ +    if (!index.isValid()) +        return KBookmark(); + +    const QAbstractProxyModel* proxyModel = dynamic_cast< const QAbstractProxyModel* >(index.model()); +    QModelIndex originalIndex = proxyModel->mapToSource(index); -    connect(search, SIGNAL(textChanged(QString)), proxy, SLOT(setFilterFixedString(QString))); -    connect(treeView, SIGNAL( activated(QModelIndex) ), this, SLOT( bookmarkActivated(QModelIndex) ) ); +    BtmItem *node = static_cast< BtmItem* >(originalIndex.internalPointer()); +    return node->getBkm(); +} + + +void BookmarksPanel::onCollapse(const QModelIndex &index) +{ +    if (m_loadingState) +        return; + +    KBookmark bookmark = bookmarkForIndex(index); +    bookmark.internalElement().setAttribute("folded", "yes"); +    emit saveOnlyRequested(); +} + + +void BookmarksPanel::onExpand(const QModelIndex &index) +{ +    if (m_loadingState) +        return; + +    KBookmark bookmark = bookmarkForIndex(index); +    bookmark.internalElement().setAttribute("folded", "no"); +    emit saveOnlyRequested(); +} + + +void BookmarksPanel::loadFoldedState() +{ +    m_loadingState = true; +    loadFoldedState(QModelIndex()); +    m_loadingState = false; +} + + +void BookmarksPanel::loadFoldedState(const QModelIndex &root) +{ + +    int count = m_treeView->model()->rowCount(root); +    QModelIndex index; + +    for (int i = 0; i < count; i++) +    { +        index = m_treeView->model()->index(i, 0, root); +        if (index.isValid() && bookmarkForIndex(index).isGroup()) +        { +            m_treeView->setExpanded(index, bookmarkForIndex(index).toGroup().isOpen()); +            loadFoldedState(index); +        } +    } +} + + +void BookmarksPanel::contextMenu(const QPoint &pos) +{ +    QModelIndex index = m_treeView->indexAt(pos); +    if (m_loadingState) +        return; + +    KBookmark selected = bookmarkForIndex(index); + +    BookmarkContextMenu menu( selected,  +                              Application::bookmarkProvider()->bookmarkManager(),  +                              Application::bookmarkProvider()->bookmarkOwner(),  +                              this +                            ); +                             +    menu.exec(m_treeView->mapToGlobal(pos)); +} + + +void BookmarksPanel::deleteBookmark() +{ +    QModelIndex index = m_treeView->currentIndex(); +    if (!index.isValid()) +        return; + +    KBookmark bm = bookmarkForIndex(index); +    bool folder = bm.isGroup(); + +    if (KMessageBox::warningContinueCancel( +                QApplication::activeWindow(), +                folder ? i18n("Are you sure you wish to remove the bookmark folder\n\"%1\"?", bm.text()) +                : i18n("Are you sure you wish to remove the bookmark\n\"%1\"?", bm.text()), +                folder ? i18n("Bookmark Folder Deletion") +                : i18n("Bookmark Deletion"), +                KStandardGuiItem::del()) +            != KMessageBox::Continue +       ) +        return; + + +    bm.parentGroup().deleteBookmark(bm); +    Application::instance()->bookmarkProvider()->bookmarkManager()->emitChanged();  } diff --git a/src/bookmarks/bookmarkspanel.h b/src/bookmarks/bookmarkspanel.h index 6c0e153f..b2a9f264 100644 --- a/src/bookmarks/bookmarkspanel.h +++ b/src/bookmarks/bookmarkspanel.h @@ -3,6 +3,8 @@  * This file is a part of the rekonq project  *  * Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com> +* Copyright (C) 2010 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 @@ -27,15 +29,26 @@  #ifndef BOOKMARKSPANEL_H  #define BOOKMARKSPANEL_H + +// Rekonq Includes +#include "rekonq_defines.h" + +// Local Includes +#include "application.h" +#include "paneltreeview.h" +  // Qt Includes  #include <QDockWidget> +// KDE Includes +#include <KBookmark> +  // Forward Declarations  class KUrl;  class QModelIndex; -class BookmarksPanel : public QDockWidget +class REKONQ_TESTS_EXPORT BookmarksPanel : public QDockWidget  {      Q_OBJECT @@ -44,13 +57,26 @@ public:      ~BookmarksPanel();  signals: -    void openUrl(const KUrl &); +    void openUrl(const KUrl &, const Rekonq::OpenType &); +    void itemHovered(const QString &); +    void saveOnlyRequested();  private slots: -    void bookmarkActivated( const QModelIndex &index ); +    void contextMenu(const QPoint &pos); + +    void deleteBookmark(); +    void onCollapse(const QModelIndex &index); +    void onExpand(const QModelIndex &index); +    void loadFoldedState(const QModelIndex &root); +    void loadFoldedState(); +  private:      void setup(); +    KBookmark bookmarkForIndex(const QModelIndex &index); + +    PanelTreeView *m_treeView; +    bool m_loadingState;  };  #endif // BOOKMARKSPANEL_H diff --git a/src/bookmarks/bookmarksproxy.cpp b/src/bookmarks/bookmarksproxy.cpp index e94fbeff..4e4b4f06 100644 --- a/src/bookmarks/bookmarksproxy.cpp +++ b/src/bookmarks/bookmarksproxy.cpp @@ -3,6 +3,7 @@  * This file is a part of the rekonq project  *  * Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com> +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>  *  *  * This program is free software; you can redistribute it and/or @@ -29,27 +30,27 @@  #include "bookmarksproxy.moc" -BookmarksProxy::BookmarksProxy( QObject *parent ) -    : QSortFilterProxyModel( parent ) +BookmarksProxy::BookmarksProxy(QObject *parent) +        : QSortFilterProxyModel(parent)  {  } -bool BookmarksProxy::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const +bool BookmarksProxy::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const  { -    QModelIndex idx = sourceModel()->index( source_row, 0, source_parent ); -    return recursiveMatch( idx ); +    QModelIndex idx = sourceModel()->index(source_row, 0, source_parent); +    return recursiveMatch(idx);  } -bool BookmarksProxy::recursiveMatch( const QModelIndex &index ) const +bool BookmarksProxy::recursiveMatch(const QModelIndex &index) const  { -    if( index.data().toString().contains( filterRegExp() ) ) +    if (index.data().toString().contains(filterRegExp()))          return true; -    for( int childRow = 0; childRow < sourceModel()->rowCount( index ); ++childRow )  +    for (int childRow = 0; childRow < sourceModel()->rowCount(index); ++childRow)      { -        if( recursiveMatch( sourceModel()->index( childRow, 0, index ) ) ) +        if (recursiveMatch(sourceModel()->index(childRow, 0, index)))              return true;      }      return false; diff --git a/src/bookmarks/bookmarksproxy.h b/src/bookmarks/bookmarksproxy.h index 99483331..e7b50d8e 100644 --- a/src/bookmarks/bookmarksproxy.h +++ b/src/bookmarks/bookmarksproxy.h @@ -3,6 +3,7 @@  * This file is a part of the rekonq project  *  * Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com> +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>  *  *  * This program is free software; you can redistribute it and/or @@ -27,22 +28,27 @@  #ifndef BOOKMARKSPROXY_H  #define BOOKMARKSPROXY_H + +// Rekonq Includes +#include "rekonq_defines.h" +  // Qt Includes  #include <QSortFilterProxyModel> -class BookmarksProxy : public QSortFilterProxyModel + +class REKONQ_TESTS_EXPORT BookmarksProxy : public QSortFilterProxyModel  {      Q_OBJECT      Q_DISABLE_COPY(BookmarksProxy)  public: -	BookmarksProxy( QObject *parent = 0 ); +    BookmarksProxy(QObject *parent = 0);  protected: -	virtual bool filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const; +    virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; -	// returns true if any child(or childs-child...) matches filter -	bool recursiveMatch( const QModelIndex &index ) const; +    // returns true if any child(or children-child...) matches filter +    bool recursiveMatch(const QModelIndex &index) const;  };  #endif // BOOKMARKSPROXY_H diff --git a/src/bookmarks/bookmarkstreemodel.cpp b/src/bookmarks/bookmarkstreemodel.cpp index 140fa9c8..06732007 100644 --- a/src/bookmarks/bookmarkstreemodel.cpp +++ b/src/bookmarks/bookmarkstreemodel.cpp @@ -3,6 +3,7 @@  * This file is a part of the rekonq project  *  * Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com> +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>  *  *  * This program is free software; you can redistribute it and/or @@ -32,105 +33,124 @@  #include "application.h"  #include "bookmarksmanager.h" +// Qt Includes +#include <QMimeData> +  // KDE includes  #include <KBookmarkGroup>  #include <KLocalizedString> -class BookmarksTreeModel::BtmItem -{ -public: -    BtmItem(const KBookmark &bm) +BtmItem::BtmItem(const KBookmark &bm)          : m_parent(0)          , m_kbm(bm) -    { -    } -     -     -    ~BtmItem() -    { -        qDeleteAll(m_children); -    } +{ +} -    QVariant data( int role = Qt::DisplayRole ) const -    { -        if( m_kbm.isNull() ) -            return QVariant();  // should only happen for root item +BtmItem::~BtmItem() +{ +    qDeleteAll(m_children); +} -        if( role == Qt::DisplayRole ) -            return m_kbm.text(); -        if( role == Qt::DecorationRole ) -            return KIcon( m_kbm.icon() ); -        if( role == Qt::UserRole ) -            return m_kbm.url(); -        return QVariant(); +QVariant BtmItem::data(int role) const +{ +    if (m_kbm.isNull()) +        return QVariant();  // should only happen for root item + +    if (role == Qt::DisplayRole) +        return m_kbm.text(); +    if (role == Qt::DecorationRole) +        return KIcon(m_kbm.icon()); +    if (role == Qt::UserRole) +        return m_kbm.url(); +    if (role == Qt::ToolTipRole) +    { +        QString tooltip = ""; + +        if (!m_kbm.text().isEmpty()) +        { +            tooltip += m_kbm.text(); +        } +        if (m_kbm.isGroup()) +        { +            tooltip += " [" + QString::number(childCount()) + ' ' + i18n("Items") + ']'; +        } +        if (!m_kbm.url().url().isEmpty()) +        { +            if (!tooltip.isEmpty()) +                tooltip += '\n'; +            tooltip += m_kbm.url().url(); +        } +        return tooltip;      } +    return QVariant(); +} -    int row() const -    { -        if(m_parent) -            return m_parent->m_children.indexOf( const_cast< BtmItem* >( this ) ); -        return 0; -    } +int BtmItem::row() const +{ +    if (m_parent) +        return m_parent->m_children.indexOf(const_cast< BtmItem* >(this)); +    return 0; +} -    int childCount() const -    { -        return m_children.count(); -    } +int BtmItem::childCount() const +{ +    return m_children.count(); +} -    BtmItem* child( int n ) -    { -        Q_ASSERT(n>=0); -        Q_ASSERT(n<childCount()); -        return m_children.at(n); -    } +BtmItem* BtmItem::child(int n) +{ +    Q_ASSERT(n >= 0); +    Q_ASSERT(n < childCount()); +    return m_children.at(n); +} -    BtmItem* parent() const -    { -        return m_parent; -    } +BtmItem* BtmItem::parent() const +{ +    return m_parent; +} -    void appendChild(BtmItem *child) -    { -        if( !child ) -            return; -        child->m_parent = this; -        m_children << child; -    } +void BtmItem::appendChild(BtmItem *child) +{ +    if (!child) +        return; +    child->m_parent = this; +    m_children << child; +} -    void clear() -    { -        qDeleteAll(m_children); -        m_children.clear(); -    } -private: -    BtmItem *m_parent; -    QList< BtmItem* > m_children; -    KBookmark m_kbm; -}; +void BtmItem::clear() +{ +    qDeleteAll(m_children); +    m_children.clear(); +} +KBookmark BtmItem::getBkm() const +{ +    return m_kbm; +}  // -------------------------------------------------------------------------------------  BookmarksTreeModel::BookmarksTreeModel(QObject *parent) -    : QAbstractItemModel(parent) -    , m_root(0) +        : QAbstractItemModel(parent) +        , m_root(0)  {      resetModel(); -    connect( Application::bookmarkProvider()->bookmarkManager(), SIGNAL( changed(QString,QString) ), this, SLOT( bookmarksChanged(QString) ) ); -    connect( Application::bookmarkProvider()->bookmarkManager(), SIGNAL( bookmarksChanged(QString) ), this, SLOT( bookmarksChanged(QString) ) ); +    connect(this, SIGNAL(bookmarksUpdated()), parent, SLOT(loadFoldedState())); +    connect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL(changed(QString, QString)), this, SLOT(bookmarksChanged())); +    connect(parent, SIGNAL(saveOnlyRequested()), this, SLOT(saveOnly()));  } @@ -143,13 +163,13 @@ BookmarksTreeModel::~BookmarksTreeModel()  int BookmarksTreeModel::rowCount(const QModelIndex &parent) const  {      BtmItem *parentItem = 0; -    if( !parent.isValid() )  +    if (!parent.isValid())      {          parentItem = m_root;      } -    else  +    else      { -        parentItem = static_cast< BtmItem* >( parent.internalPointer() ); +        parentItem = static_cast< BtmItem* >(parent.internalPointer());      }      return parentItem->childCount(); @@ -166,11 +186,11 @@ int BookmarksTreeModel::columnCount(const QModelIndex &parent) const  QVariant BookmarksTreeModel::headerData(int section, Qt::Orientation orientation, int role) const  { -    if( orientation == Qt::Horizontal  -        && role == Qt::DisplayRole  -        && section == 0  -      ) -        return i18n( "Bookmark" ); +    if (orientation == Qt::Horizontal +            && role == Qt::DisplayRole +            && section == 0 +       ) +        return i18n("Bookmark");      return QVariant();  } @@ -178,33 +198,42 @@ QVariant BookmarksTreeModel::headerData(int section, Qt::Orientation orientation  Qt::ItemFlags BookmarksTreeModel::flags(const QModelIndex &index) const  { -    Q_UNUSED(index) -    return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +    Qt::ItemFlags flags = QAbstractItemModel::flags(index); + +    if (!index.isValid()) +        return flags | Qt::ItemIsDropEnabled; + +    flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled; + +    if (bookmarkForIndex(index).isGroup()) +        flags |= Qt::ItemIsDropEnabled; + +    return flags;  }  QModelIndex BookmarksTreeModel::index(int row, int column, const QModelIndex &parent) const  { -    if( !hasIndex( row, column, parent ) )  +    if (!hasIndex(row, column, parent))      {          return QModelIndex();      }      BtmItem *parentItem; -    if( !parent.isValid() )  +    if (!parent.isValid())      {          parentItem = m_root;      } -    else  +    else      { -        parentItem = static_cast< BtmItem* >( parent.internalPointer() ); +        parentItem = static_cast< BtmItem* >(parent.internalPointer());      } -    BtmItem *childItem = parentItem->child( row ); -    if( childItem )  +    BtmItem *childItem = parentItem->child(row); +    if (childItem)      { -        return createIndex( row, column, childItem ); +        return createIndex(row, column, childItem);      }      return QModelIndex(); @@ -213,74 +242,52 @@ QModelIndex BookmarksTreeModel::index(int row, int column, const QModelIndex &pa  QModelIndex BookmarksTreeModel::parent(const QModelIndex &index) const  { -    if( !index.isValid() )  +    if (!index.isValid())      {          return QModelIndex();      } -    BtmItem *childItem = static_cast< BtmItem* >( index.internalPointer() ); +    BtmItem *childItem = static_cast< BtmItem* >(index.internalPointer());      BtmItem *parentItem = childItem->parent(); -    if( parentItem == m_root )  +    if (parentItem == m_root)      {          return QModelIndex();      } -    return createIndex( parentItem->row(), 0, parentItem ); +    return createIndex(parentItem->row(), 0, parentItem);  }  QVariant BookmarksTreeModel::data(const QModelIndex &index, int role) const  { -    if( !index.isValid() )  +    if (!index.isValid())      {          return QVariant();      } -    BtmItem *node = static_cast< BtmItem* >( index.internalPointer() ); -    if( node && node == m_root )  +    BtmItem *node = static_cast< BtmItem* >(index.internalPointer()); +    if (node && node == m_root)      { -        if( role == Qt::DisplayRole ) -            return i18n( "Bookmarks" ); -        if( role == Qt::DecorationRole ) -            return KIcon( "bookmarks" ); +        if (role == Qt::DisplayRole) +            return i18n("Bookmarks"); +        if (role == Qt::DecorationRole) +            return KIcon("bookmarks");      } -    else  +    else      { -        if( node ) -            return node->data( role ); +        if (node) +            return node->data(role);      }      return QVariant();  } -void BookmarksTreeModel::bookmarksChanged( const QString &groupAddress ) +void BookmarksTreeModel::bookmarksChanged()  { -    if( groupAddress.isEmpty() ) -    { -        resetModel(); -        return; -    } - -    BtmItem *node = m_root; -    QModelIndex nodeIndex; - -    QStringList indexChain( groupAddress.split( '/', QString::SkipEmptyParts) ); -    foreach( QString sIndex, indexChain )  -    { -        bool ok; -        int i = sIndex.toInt( &ok ); -        if( !ok ) -            break; - -        if( i < 0 || i >= node->childCount() ) -            break; - -        node = node->child( i ); -        nodeIndex = index( i, 0, nodeIndex ); -    } -    emit dataChanged( index( 0, 0, nodeIndex ), index( node->childCount(), 0, nodeIndex ) ); +    resetModel(); +    emit bookmarksUpdated();  } @@ -295,29 +302,126 @@ void BookmarksTreeModel::setRoot(KBookmarkGroup bmg)      delete m_root;      m_root = new BtmItem(KBookmark()); -    if( bmg.isNull() ) +    if (bmg.isNull())          return; -    populate( m_root, bmg ); +    populate(m_root, bmg);      reset();  } -void BookmarksTreeModel::populate( BtmItem *node, KBookmarkGroup bmg) +void BookmarksTreeModel::populate(BtmItem *node, KBookmarkGroup bmg)  {      node->clear(); -    if( bmg.isNull() ) +    if (bmg.isNull())          return;      KBookmark bm = bmg.first(); -    while( !bm.isNull() )  +    while (!bm.isNull())      { -        BtmItem *newChild = new BtmItem( bm ); -        if( bm.isGroup() ) -            populate( newChild, bm.toGroup() ); +        BtmItem *newChild = new BtmItem(bm); +        if (bm.isGroup()) +            populate(newChild, bm.toGroup()); + +        node->appendChild(newChild); +        bm = bmg.next(bm); +    } +} + + +KBookmark BookmarksTreeModel::bookmarkForIndex(const QModelIndex &index) const +{ +    return static_cast<BtmItem*>(index.internalPointer())->getBkm(); +} + + +void BookmarksTreeModel::saveOnly() +{ +    disconnect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL(changed(QString, QString)), this, SLOT(bookmarksChanged())); +    connect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL(changed(QString, QString)), this, SLOT(reconnectManager())); +    Application::bookmarkProvider()->bookmarkManager()->emitChanged(); +} + + +void BookmarksTreeModel::reconnectManager() +{ +    connect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL(changed(QString, QString)), this, SLOT(bookmarksChanged())); +} + + +Qt::DropActions BookmarksTreeModel::supportedDropActions() const +{ +    return Qt::MoveAction; +} + + +QStringList BookmarksTreeModel::mimeTypes() const +{ +    return KBookmark::List::mimeDataTypes(); +} + + +QMimeData* BookmarksTreeModel::mimeData(const QModelIndexList & indexes) const +{ +    QMimeData *mimeData = new QMimeData; + +    QByteArray addresse = bookmarkForIndex(indexes.first()).address().toLatin1(); +    mimeData->setData("application/rekonq-bookmark", addresse); +    bookmarkForIndex(indexes.first()).populateMimeData(mimeData); -        node->appendChild( newChild ); -        bm = bmg.next( bm ); +    return mimeData; +} + + +bool BookmarksTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex & parent) +{ +    if (action == Qt::MoveAction) +    { +        if (data->hasFormat("application/rekonq-bookmark")) +        { +            QByteArray addresses = data->data("application/rekonq-bookmark"); +            KBookmark bookmark = Application::bookmarkProvider()->bookmarkManager()->findByAddress(QString::fromLatin1(addresses.data())); + +            QModelIndex destIndex = index(row, column, parent); + +            KBookmark dropDestBookmark; +            if (destIndex.isValid()) +                dropDestBookmark = bookmarkForIndex(destIndex); + +            KBookmarkGroup root = Application::bookmarkProvider()->rootGroup(); +            if (parent.isValid()) +                root = bookmarkForIndex(parent).toGroup(); + +            if (!destIndex.isValid()) +            { +                if (!parent.isValid()) // Drop into a blank area +                { +                    Application::bookmarkProvider()->rootGroup().deleteBookmark(bookmark); +                    Application::bookmarkProvider()->rootGroup().addBookmark(bookmark); +                } +                else // Drop at the last item of the group or directly on the main item of the group +                { +                    root.deleteBookmark(bookmark); +                    root.addBookmark(bookmark); +                } +            } + +            else +            { +                if (row == -1) +                { +                    root.deleteBookmark(bookmark); +                    root.addBookmark(bookmark); +                } +                else // A classic drop +                { +                    root.moveBookmark(bookmark, root.previous(dropDestBookmark)); +                } +            } + +            Application::bookmarkProvider()->bookmarkManager()->emitChanged(root); +        }      } +    return true;  } diff --git a/src/bookmarks/bookmarkstreemodel.h b/src/bookmarks/bookmarkstreemodel.h index 9753999c..8dd0923c 100644 --- a/src/bookmarks/bookmarkstreemodel.h +++ b/src/bookmarks/bookmarkstreemodel.h @@ -3,6 +3,7 @@  * This file is a part of the rekonq project  *  * Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com> +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>  *  *  * This program is free software; you can redistribute it and/or @@ -27,13 +28,38 @@  #ifndef BOOKMARKSTREEMODEL_H  #define BOOKMARKSTREEMODEL_H -// Qt Includes -#include <QAbstractItemModel> + +// Rekonq Includes +#include "rekonq_defines.h"  // KDE includes  #include <KBookmark> -class BookmarksTreeModel : public QAbstractItemModel +// Qt Includes +#include <QAbstractItemModel> + +class BtmItem +{ +public: +    BtmItem(const KBookmark &bm); +    ~BtmItem(); +    QVariant data(int role = Qt::DisplayRole) const; +    int row() const; +    int childCount() const; +    BtmItem* child(int n); +    BtmItem* parent() const; +    void appendChild(BtmItem *child); +    void clear(); +    KBookmark getBkm() const; + +private: +    BtmItem *m_parent; +    QList< BtmItem* > m_children; +    KBookmark m_kbm; +}; + + +class REKONQ_TESTS_EXPORT BookmarksTreeModel : public QAbstractItemModel  {      Q_OBJECT      Q_DISABLE_COPY(BookmarksTreeModel) @@ -42,28 +68,36 @@ public:      explicit BookmarksTreeModel(QObject *parent = 0);      ~BookmarksTreeModel(); -	virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; +    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;      virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; -	virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; -	virtual Qt::ItemFlags flags(const QModelIndex &index) const; +    virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; +    virtual Qt::ItemFlags flags(const QModelIndex &index) const; -	virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; +    virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;      virtual QModelIndex parent(const QModelIndex &index) const; -	virtual QVariant data(const QModelIndex &index, int role) const; -//     virtual bool setData(const QModelIndex &index, const QVariant &value, int role); +    virtual QVariant data(const QModelIndex &index, int role) const; + +    virtual QStringList mimeTypes() const; +    virtual bool dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent); +    virtual Qt::DropActions supportedDropActions() const; +    virtual QMimeData *mimeData(const QModelIndexList & indexes) const;  private slots: -	void bookmarksChanged( const QString &groupAddress ); +    void bookmarksChanged(); +    void saveOnly(); +    void reconnectManager(); -private: -	class BtmItem; -	BtmItem *m_root; +signals: +    void bookmarksUpdated(); -	void resetModel(); +private: +    BtmItem *m_root; +    void resetModel();      void setRoot(KBookmarkGroup bmg); -	void populate( BtmItem *node, KBookmarkGroup bmg); +    void populate(BtmItem *node, KBookmarkGroup bmg); +    KBookmark bookmarkForIndex(const QModelIndex &index) const;  };  #endif // BOOKMARKSTREEMODEL_H  | 
