From e9670c51fef2c8447a04a30778a24646df4ef915 Mon Sep 17 00:00:00 2001 From: Yoann Laissus Date: Tue, 23 Mar 2010 22:56:26 +0100 Subject: A lot of fix and improvements for the bookmark and the history panels --- src/CMakeLists.txt | 1 + src/bookmarks/bookmarksmanager.cpp | 4 +- src/bookmarks/bookmarksmanager.h | 4 +- src/bookmarks/bookmarkspanel.cpp | 441 +++++++++++++++++++++++++++++++++-- src/bookmarks/bookmarkspanel.h | 36 ++- src/bookmarks/bookmarkstreemodel.cpp | 265 ++++++++++++++------- src/bookmarks/bookmarkstreemodel.h | 51 ++-- src/history/historymodels.cpp | 8 + src/history/historypanel.cpp | 89 +++++-- src/history/historypanel.h | 10 +- src/mainwindow.cpp | 6 +- 11 files changed, 774 insertions(+), 141 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bc4e91c8..0cab993c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,6 +19,7 @@ SET( rekonq_KDEINIT_SRCS protocolhandler.cpp sessionmanager.cpp tabbar.cpp + urltreeview.cpp walletbar.cpp webinspectorpanel.cpp webpage.cpp diff --git a/src/bookmarks/bookmarksmanager.cpp b/src/bookmarks/bookmarksmanager.cpp index cfe26a55..9feed63a 100644 --- a/src/bookmarks/bookmarksmanager.cpp +++ b/src/bookmarks/bookmarksmanager.cpp @@ -178,7 +178,9 @@ BookmarkProvider::BookmarkProvider(QObject *parent) bookfile = KUrl(bookmarksPath); } } - m_manager = KBookmarkManager::managerForExternalFile(bookfile.path()); + // A workaround to avoid a long delay between the two changed signals of the bookmark manager + m_manager = KBookmarkManager::managerForFile(bookfile.path(), "rekonq"); + connect(m_manager, SIGNAL(changed(const QString &, const QString &)), this, SLOT(slotBookmarksChanged(const QString &, const QString &))); diff --git a/src/bookmarks/bookmarksmanager.h b/src/bookmarks/bookmarksmanager.h index d4afb997..e50148e4 100644 --- a/src/bookmarks/bookmarksmanager.h +++ b/src/bookmarks/bookmarksmanager.h @@ -210,7 +210,9 @@ public: */ KBookmarkGroup rootGroup(); - KBookmarkManager *bookmarkManager() { return m_manager; } + KBookmarkManager *bookmarkManager() { return m_manager; } + BookmarkOwner *bookmarkOwner() { return m_owner; } + signals: /** * @short This signal is emitted when an url has to be loaded diff --git a/src/bookmarks/bookmarkspanel.cpp b/src/bookmarks/bookmarkspanel.cpp index 48ca6537..c50ebcdb 100644 --- a/src/bookmarks/bookmarkspanel.cpp +++ b/src/bookmarks/bookmarkspanel.cpp @@ -29,6 +29,7 @@ #include "bookmarkspanel.moc" // Local Includes +#include "bookmarksmanager.h" #include "bookmarkstreemodel.h" #include "bookmarksproxy.h" @@ -44,12 +45,21 @@ // KDE includes #include #include +#include +#include +#include +#include BookmarksPanel::BookmarksPanel(const QString &title, QWidget *parent, Qt::WindowFlags flags) - : QDockWidget(title, parent, flags) + : QDockWidget(title, parent, flags), + m_treeView(new UrlTreeView(this)), + m_ac(new KActionCollection(this)), + menu(new KMenu(this)), + expandLock(false) { setup(); + setupActions(); setShown(ReKonfig::showBookmarksPanel()); } @@ -60,13 +70,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"); @@ -85,19 +88,20 @@ void BookmarksPanel::setup() 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); @@ -106,8 +110,407 @@ void BookmarksPanel::setup() BookmarksTreeModel *model = new BookmarksTreeModel( this ); BookmarksProxy *proxy = new BookmarksProxy(ui); proxy->setSourceModel( model ); - treeView->setModel( proxy ); + m_treeView->setModel( proxy ); + + connect(m_treeView, SIGNAL(contextMenuItemRequested(const QPoint &)), this, SLOT(contextMenuBk(const QPoint &))); + connect(m_treeView, SIGNAL(contextMenuGroupRequested(const QPoint &)), this, SLOT(contextMenuBkGroup(const QPoint &))); + connect(m_treeView, SIGNAL(contextMenuEmptyRequested(const QPoint &)), this, SLOT(contextMenuBlank(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 &))); + callAutoExpand(); +} + + +void BookmarksPanel::onCollapse(const QModelIndex &index) +{ + if(expandLock) + return; + + KBookmark bookmark = bookmarkForIndex(index); + bookmark.internalElement().setAttribute("folded", "yes"); + Application::bookmarkProvider()->bookmarkManager()->emitChanged(); +} + + +void BookmarksPanel::onExpand(const QModelIndex &index) +{ + if(expandLock) + return; + + KBookmark bookmark = bookmarkForIndex(index); + bookmark.internalElement().setAttribute("folded", "no"); + Application::bookmarkProvider()->bookmarkManager()->emitChanged(); +} + + +void BookmarksPanel::callAutoExpand() +{ + expandLock = true; + autoExpand(); + expandLock = false; +} + + +void BookmarksPanel::autoExpand(const QModelIndex &root) +{ + + int count = m_treeView->model()->rowCount(root); + QModelIndex temp; + + for(int i = 0; i < count; i++) + { + temp = m_treeView->model()->index(i,0,root); + m_treeView->setExpanded(temp, bookmarkForIndex(temp).toGroup().isOpen()); + autoExpand(temp); + } +} + + +void BookmarksPanel::setupActions() +{ + KAction* action; + + action = new KAction(KIcon("tab-new"), i18n("Open"), this); + connect(action, SIGNAL(triggered()), m_treeView, SLOT(openInCurrentTab())); + m_ac.addAction("open", action); + + action = new KAction(KIcon("tab-new"), i18n("Open in New Tab"), this); + connect(action, SIGNAL(triggered()), m_treeView, SLOT(openInNewTab())); + m_ac.addAction("open_tab", action); + + action = new KAction(KIcon("window-new"), i18n("Open in New Window"), this); + connect(action, SIGNAL(triggered()), m_treeView, SLOT(openInNewWindow())); + m_ac.addAction("open_window", action); + + action = new KAction(KIcon("rating"), i18n("Bookmark Page"), this); + connect(action, SIGNAL(triggered()), this, SLOT(bookmarkPage())); + m_ac.addAction("bookmark_page", action); + + action = new KAction(KIcon("bookmark-new"), i18n("New Bookmark"), this); + connect(action, SIGNAL(triggered()), this, SLOT(newBookmark())); + m_ac.addAction("bookmark_new", 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"), this); + connect(action, SIGNAL(triggered()), m_treeView, SLOT(copyToClipboard())); + m_ac.addAction("copy", action); + + action = new KAction(KIcon("edit-delete"), i18n("Delete"), 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 all Bookmarks"), this); + connect(action, SIGNAL(triggered()), this, SLOT(openAll())); + m_ac.addAction("open_all", action); +} + + +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); + + BtmItem *node = static_cast< BtmItem* >( originalIndex.internalPointer() ); + return node->getBkm(); +} + + +void BookmarksPanel::contextMenuBk(const QPoint &pos) +{ + QPoint position = m_treeView->mapToGlobal(pos); + QModelIndex index = m_treeView->indexAt(pos); + if(!index.isValid() || expandLock) + return; + + KBookmark selected = bookmarkForIndex(index); + + if(selected.isGroup()) + { + contextMenuBkGroup(pos, true); + return; + } + + if(selected.isSeparator()) + { + contextMenuSeparator(pos); + return; + } + + menu = new KMenu(this); + + menu->addAction(m_ac.action("open")); + menu->addAction(m_ac.action("open_tab")); + menu->addAction(m_ac.action("open_window")); + + menu->addSeparator(); + + menu->addAction(m_ac.action("bookmark_page")); + menu->addAction(m_ac.action("bookmark_new")); + menu->addAction(m_ac.action("folder_new")); + menu->addAction(m_ac.action("separator_new")); + + menu->addSeparator(); + + menu->addAction(m_ac.action("copy")); + + menu->addSeparator(); + + menu->addAction(m_ac.action("delete")); + menu->addAction(m_ac.action("properties")); + + menu->popup(position); +} + + +void BookmarksPanel::contextMenuBkGroup(const QPoint &pos, bool emptyGroup) +{ + if(expandLock) + return; + + QPoint position = m_treeView->mapToGlobal(pos); + menu = new KMenu(this); + + if(!emptyGroup) + { + menu->addAction(m_ac.action("open_all")); + menu->addSeparator(); + } + + menu->addAction(m_ac.action("bookmark_page")); + menu->addAction(m_ac.action("bookmark_new")); + menu->addAction(m_ac.action("folder_new")); + menu->addAction(m_ac.action("separator_new")); + + menu->addSeparator(); + + menu->addAction(m_ac.action("delete")); + menu->addAction(m_ac.action("properties")); + + menu->popup(position); +} + + +void BookmarksPanel::contextMenuSeparator(const QPoint &pos) +{ + QPoint position = m_treeView->mapToGlobal(pos); + menu = new KMenu(this); + + menu->addAction(m_ac.action("bookmark_page")); + menu->addAction(m_ac.action("bookmark_new")); + menu->addAction(m_ac.action("folder_new")); + menu->addAction(m_ac.action("separator_new")); + + menu->addSeparator(); + + menu->addAction(m_ac.action("delete")); + + menu->popup(position); +} + + +void BookmarksPanel::contextMenuBlank(const QPoint &pos) +{ + QPoint position = m_treeView->mapToGlobal(pos); + menu = new KMenu(this); + + menu->addAction(m_ac.action("bookmark_page")); + menu->addAction(m_ac.action("bookmark_new")); + menu->addAction(m_ac.action("folder_new")); + menu->addAction(m_ac.action("separator_new")); + + menu->popup(position); +} + + +void BookmarksPanel::deleteBookmark() +{ + QModelIndex index = m_treeView->currentIndex(); + if(!index.isValid()) + return; + + KBookmark selected = bookmarkForIndex(index); + KBookmarkGroup parent = selected.parentGroup(); + + parent.deleteBookmark(selected); + Application::instance()->bookmarkProvider()->bookmarkManager()->emitChanged(); +} + + +void BookmarksPanel::editBookmark() +{ + QModelIndex index = m_treeView->currentIndex(); + if(!index.isValid()) + return; + + KBookmark selected = bookmarkForIndex(index); + + KBookmarkDialog *dialog = Application::bookmarkProvider()->bookmarkOwner()->bookmarkDialog(Application::bookmarkProvider()->bookmarkManager(), QApplication::activeWindow()); + dialog->editBookmark(selected); + delete dialog; +} + + +void BookmarksPanel::openAll() +{ + QModelIndex index = m_treeView->currentIndex(); + if(!index.isValid()) + return; + + QList allChild = bookmarkForIndex(index).toGroup().groupUrlList(); + + if(allChild.length() > 8) // 8, a good choice ? + { + if(!(KMessageBox::warningContinueCancel(this, i18n("You are about to open a lot of tabs : %1\nAre you sure ?", QString::number(allChild.length()))) == KMessageBox::Continue)) + return; + } + + for(int i = 0; i < allChild.length(); i++) + emit openUrl(allChild.at(i).url(), Rekonq::SettingOpenTab); +} + + +void BookmarksPanel::newBookmark() +{ + QModelIndex index = m_treeView->currentIndex(); + + KBookmark selected; + KBookmark newBk; + + KBookmarkDialog *dialog = Application::bookmarkProvider()->bookmarkOwner()->bookmarkDialog(Application::bookmarkProvider()->bookmarkManager(), QApplication::activeWindow()); + + if(index.isValid()) + { + selected = bookmarkForIndex(index); + + if(selected.isGroup()) + newBk = dialog->addBookmark("New bookmark", KUrl("www.kde.org"), selected); + else + newBk = dialog->addBookmark("New bookmark", KUrl("www.kde.org"), selected.parentGroup()); + } + + else + { + newBk = dialog->addBookmark("New bookmark", KUrl("www.kde.org")); + } + + delete dialog; + + // addBookmark already added the bookmark, but without the default favicon + KBookmarkGroup parent = newBk.parentGroup(); + parent.deleteBookmark(newBk); + newBk.setIcon(("text-html")); + parent.addBookmark(newBk); + + if(index.isValid()) + parent.moveBookmark(newBk, selected); + + Application::bookmarkProvider()->bookmarkManager()->emitChanged(); +} + + +void BookmarksPanel::newBookmarkGroup() +{ + QModelIndex index = m_treeView->currentIndex(); + KBookmark newBk; + + KBookmarkDialog *dialog = Application::bookmarkProvider()->bookmarkOwner()->bookmarkDialog(Application::bookmarkProvider()->bookmarkManager(), QApplication::activeWindow()); + + if(index.isValid()) + { + KBookmark selected = bookmarkForIndex(index); + + if(selected.isGroup()) + { + newBk = dialog->createNewFolder("New folder", selected); + } + + else + { + newBk = dialog->createNewFolder("New folder", selected.parentGroup()); + selected.parentGroup().moveBookmark(newBk, selected); + Application::bookmarkProvider()->bookmarkManager()->emitChanged(); + } + } + + else + { + dialog->createNewFolder("New folder"); + } + + delete dialog; +} + + +void BookmarksPanel::newSeparator() +{ + QModelIndex index = m_treeView->currentIndex(); + + KBookmark selected; + KBookmark newBk; + + if(index.isValid()) + { + selected = bookmarkForIndex(index); + + 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(index.isValid()) + parent.moveBookmark(newBk, selected); + + Application::bookmarkProvider()->bookmarkManager()->emitChanged(); +} + + +void BookmarksPanel::bookmarkPage() +{ + QModelIndex index = m_treeView->currentIndex(); + KBookmarkGroup parent = Application::bookmarkProvider()->rootGroup(); + + if(index.isValid()) + { + KBookmark selected = bookmarkForIndex(index); + parent = selected.parentGroup(); + + if(selected.isGroup()) + parent = selected.toGroup(); + + KBookmark newBk = parent.addBookmark(Application::bookmarkProvider()->bookmarkOwner()->currentTitle(), KUrl(Application::bookmarkProvider()->bookmarkOwner()->currentUrl()), "text-html"); + parent.moveBookmark(newBk, selected); + } + + else + { + parent.addBookmark(Application::bookmarkProvider()->bookmarkOwner()->currentTitle(), KUrl(Application::bookmarkProvider()->bookmarkOwner()->currentUrl()), "text-html"); + } - connect(search, SIGNAL(textChanged(QString)), proxy, SLOT(setFilterFixedString(QString))); - connect(treeView, SIGNAL( activated(QModelIndex) ), this, SLOT( bookmarkActivated(QModelIndex) ) ); + Application::bookmarkProvider()->bookmarkManager()->emitChanged(); } diff --git a/src/bookmarks/bookmarkspanel.h b/src/bookmarks/bookmarkspanel.h index f5376d98..ea33e265 100644 --- a/src/bookmarks/bookmarkspanel.h +++ b/src/bookmarks/bookmarkspanel.h @@ -31,10 +31,17 @@ // Local Includes #include "rekonqprivate_export.h" +#include "application.h" +#include "urltreeview.h" // Qt Includes #include +// KDE Includes +#include +#include +#include + // Forward Declarations class KUrl; class QModelIndex; @@ -49,13 +56,38 @@ public: ~BookmarksPanel(); signals: - void openUrl(const KUrl &); + void openUrl(const KUrl &, const Rekonq::OpenType &); + void itemHovered(const QString &); + void saveExpFinished(const QString &); + void saveRequested(); private slots: - void bookmarkActivated( const QModelIndex &index ); + void contextMenuBk(const QPoint &pos); + void contextMenuBkGroup(const QPoint &pos, const bool emptyGroup = false); + void contextMenuBlank(const QPoint &pos); + void deleteBookmark(); + void openAll(); + void editBookmark(); + void newBookmark(); + void newBookmarkGroup(); + void newSeparator(); + void bookmarkPage(); + void autoExpand(const QModelIndex &root = QModelIndex()); + void onCollapse(const QModelIndex &index); + void onExpand(const QModelIndex &index); + void callAutoExpand(); private: void setup(); + void setupActions(); + void contextMenuSeparator(const QPoint &pos); + KBookmark bookmarkForIndex(const QModelIndex &index); + + UrlTreeView *m_treeView; + QStringList m_expList; + KActionCollection m_ac; + KMenu *menu; + bool expandLock; }; #endif // BOOKMARKSPANEL_H diff --git a/src/bookmarks/bookmarkstreemodel.cpp b/src/bookmarks/bookmarkstreemodel.cpp index 95e5ad41..d63c92d3 100644 --- a/src/bookmarks/bookmarkstreemodel.cpp +++ b/src/bookmarks/bookmarkstreemodel.cpp @@ -33,94 +33,112 @@ #include "application.h" #include "bookmarksmanager.h" +// Qt Includes +#include + // KDE includes #include #include -class BookmarksTreeModel::BtmItem +BtmItem::BtmItem(const KBookmark &bm) + : m_parent(0) + , m_kbm(bm) { -public: - 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=0); + Q_ASSERT(nm_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; +} // ------------------------------------------------------------------------------------- @@ -130,8 +148,8 @@ BookmarksTreeModel::BookmarksTreeModel(QObject *parent) , m_root(0) { resetModel(); + connect( this, SIGNAL(bookmarkChangedFinished()), parent, SLOT(callAutoExpand())); connect( Application::bookmarkProvider()->bookmarkManager(), SIGNAL( changed(QString,QString) ), this, SLOT( bookmarksChanged(QString) ) ); - connect( Application::bookmarkProvider()->bookmarkManager(), SIGNAL( bookmarksChanged(QString) ), this, SLOT( bookmarksChanged(QString) ) ); } @@ -179,8 +197,17 @@ 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; } @@ -258,30 +285,9 @@ QVariant BookmarksTreeModel::data(const QModelIndex &index, int role) const void BookmarksTreeModel::bookmarksChanged( const QString &groupAddress ) { - if( groupAddress.isEmpty() ) - { - resetModel(); - return; - } - - BtmItem *node = m_root; - QModelIndex nodeIndex; - - QStringList indexChain( groupAddress.split( '/', QString::SkipEmptyParts) ); - foreach( const 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 ) ); + Q_UNUSED(groupAddress); + resetModel(); + emit bookmarkChangedFinished(); } @@ -322,3 +328,86 @@ void BookmarksTreeModel::populate( BtmItem *node, KBookmarkGroup bmg) bm = bmg.next( bm ); } } + + +KBookmark BookmarksTreeModel::bookmarkForIndex(const QModelIndex index) const +{ + return static_cast(index.internalPointer())->getBkm(); +} + + +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); + + 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 dfad52ba..4ff19e5f 100644 --- a/src/bookmarks/bookmarkstreemodel.h +++ b/src/bookmarks/bookmarkstreemodel.h @@ -38,6 +38,26 @@ // Qt Includes #include +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 { @@ -48,28 +68,33 @@ 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; -private slots: - void bookmarksChanged( const QString &groupAddress ); + 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: - class BtmItem; - BtmItem *m_root; +private slots: + void bookmarksChanged( const QString &groupAddress ); - void resetModel(); +signals: + void bookmarkChangedFinished(); +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 diff --git a/src/history/historymodels.cpp b/src/history/historymodels.cpp index 709d0523..736dbcd7 100644 --- a/src/history/historymodels.cpp +++ b/src/history/historymodels.cpp @@ -118,6 +118,8 @@ QVariant HistoryModel::data(const QModelIndex &index, int role) const return item.dateTime.date(); case UrlRole: return QUrl(item.url); + case Qt::UserRole: + return KUrl(item.url); case UrlStringRole: return item.url; case Qt::DisplayRole: @@ -144,6 +146,12 @@ QVariant HistoryModel::data(const QModelIndex &index, int role) const { return Application::icon(item.url); } + case Qt::ToolTipRole: + QString tooltip = ""; + if(!item.title.isEmpty()) + tooltip = item.title + "\n"; + tooltip += item.dateTime.toString(Qt::SystemLocaleShortDate) + "\n" + item.url; + return tooltip; } return QVariant(); } diff --git a/src/history/historypanel.cpp b/src/history/historypanel.cpp index 8c8eae75..c67594ff 100644 --- a/src/history/historypanel.cpp +++ b/src/history/historypanel.cpp @@ -46,6 +46,9 @@ // KDE Includes #include #include +#include +#include +#include HistoryPanel::HistoryPanel(const QString &title, QWidget *parent, Qt::WindowFlags flags) @@ -70,11 +73,12 @@ void HistoryPanel::setup() QWidget *ui = new QWidget(this); - QTreeView *historyTreeView = new QTreeView(this); - historyTreeView->setUniformRowHeights(true); - historyTreeView->setSelectionBehavior(QAbstractItemView::SelectRows); - historyTreeView->setTextElideMode(Qt::ElideMiddle); - historyTreeView->setAlternatingRowColors(true); + m_treeView = new UrlTreeView(this); + m_treeView->setUniformRowHeights(true); + m_treeView->setSelectionBehavior(QAbstractItemView::SelectRows); + m_treeView->setTextElideMode(Qt::ElideMiddle); + m_treeView->setAlternatingRowColors(true); + m_treeView->header()->hide(); // add search bar QHBoxLayout *hBoxLayout = new QHBoxLayout; @@ -91,7 +95,7 @@ void HistoryPanel::setup() QVBoxLayout *vBoxLayout = new QVBoxLayout; vBoxLayout->setContentsMargins(0, 0, 0, 0); vBoxLayout->addWidget(searchBar); - vBoxLayout->addWidget(historyTreeView); + vBoxLayout->addWidget(m_treeView); // add it to the UI ui->setLayout(vBoxLayout); @@ -103,19 +107,78 @@ void HistoryPanel::setup() TreeProxyModel *treeProxyModel = new TreeProxyModel(this); treeProxyModel->setSourceModel(model); - historyTreeView->setModel(treeProxyModel); - historyTreeView->setExpanded(treeProxyModel->index(0, 0), true); - historyTreeView->header()->hideSection(1); + m_treeView->setModel(treeProxyModel); + m_treeView->setExpanded(treeProxyModel->index(0, 0), true); + m_treeView->header()->hideSection(1); QFontMetrics fm(font()); int header = fm.width(QLatin1Char('m')) * 40; - historyTreeView->header()->resizeSection(0, header); + m_treeView->header()->resizeSection(0, header); connect(search, SIGNAL(textChanged(QString)), treeProxyModel, SLOT(setFilterFixedString(QString))); - connect(historyTreeView, SIGNAL(activated(const QModelIndex &)), this, SLOT(itemActivated(const QModelIndex &))); + connect(m_treeView, SIGNAL(contextMenuItemRequested(const QPoint &)), this, SLOT(contextMenuItem(const QPoint &))); + connect(m_treeView, SIGNAL(contextMenuGroupRequested(const QPoint &)), this, SLOT(contextMenuGroup(const QPoint &))); } +void HistoryPanel::contextMenuItem(const QPoint &pos) +{ + QPoint position = m_treeView->mapToGlobal(pos); + KMenu *menu = new KMenu(this); + KAction* action; + + action = new KAction(KIcon("tab-new"), i18n("Open"), this); + connect(action, SIGNAL(triggered()), m_treeView, SLOT(openInCurrentTab())); + menu->addAction(action); + + action = new KAction(KIcon("tab-new"), i18n("Open in new tab"), this); + connect(action, SIGNAL(triggered()), m_treeView, SLOT(openInNewTab())); + menu->addAction(action); + + action = new KAction(KIcon("window-new"), i18n("Open in new window"), this); + connect(action, SIGNAL(triggered()), m_treeView, SLOT(openInNewWindow())); + menu->addAction(action); + + action = new KAction(KIcon("edit-copy"), i18n("Copy link"), this); + connect(action, SIGNAL(triggered()), m_treeView, SLOT(copyToClipboard())); + menu->addAction(action); -void HistoryPanel::itemActivated(const QModelIndex &item) + if (!menu) + return; + menu->popup(position); +} + +void HistoryPanel::contextMenuGroup(const QPoint &pos) { - emit openUrl( item.data(HistoryModel::UrlRole).toUrl() ); + QPoint position = m_treeView->mapToGlobal(pos); + KMenu *menu = new KMenu(this); + KAction* action; + + action = new KAction(KIcon("tab-new"), i18n("Open all Bookmarks"), this); + connect(action, SIGNAL(triggered()), this, SLOT(openAll())); + + menu->addAction(action); + + if (!menu) + return; + menu->popup(position); +} + +void HistoryPanel::openAll() +{ + QModelIndex index = m_treeView->currentIndex(); + if(!index.isValid()) + return; + + QList allChild; + + for(int i = 0; i < index.model()->rowCount(index); i++) + allChild << qVariantValue(index.child(i, 0).data(Qt::UserRole)); + + if(allChild.length() > 8) // 8, a good choice ? + { + if(!(KMessageBox::warningContinueCancel(this, i18n("You are about to open a lot of tabs : %1\nAre you sure ?", QString::number(allChild.length()))) == KMessageBox::Continue)) + return; + } + + for(int i = 0; i < allChild.length(); i++) + emit openUrl(allChild.at(i).url(), Rekonq::SettingOpenTab); } diff --git a/src/history/historypanel.h b/src/history/historypanel.h index 6e6a9162..0c01189c 100644 --- a/src/history/historypanel.h +++ b/src/history/historypanel.h @@ -31,6 +31,8 @@ // Local Includes #include "rekonqprivate_export.h" +#include "application.h" +#include "urltreeview.h" // Qt Includes #include @@ -50,13 +52,17 @@ public: ~HistoryPanel(); signals: - void openUrl(const KUrl &); + void openUrl(const KUrl &, const Rekonq::OpenType &); + void itemHovered(const QString &); private slots: - void itemActivated(const QModelIndex &); + void contextMenuItem(const QPoint &pos); + void contextMenuGroup(const QPoint &pos); + void openAll(); private: void setup(); + UrlTreeView *m_treeView; }; #endif // HISTORYPANEL_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d15ce0c4..93273dc9 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -500,7 +500,8 @@ void MainWindow::setupPanels() // STEP 1 // Setup history panel m_historyPanel = new HistoryPanel(i18n("History Panel"), this); - connect(m_historyPanel, SIGNAL(openUrl(const KUrl&)), Application::instance(), SLOT(loadUrl(const KUrl&))); + connect(m_historyPanel, SIGNAL(openUrl(const KUrl&, const Rekonq::OpenType &)), Application::instance(), SLOT(loadUrl(const KUrl&, const Rekonq::OpenType &))); + connect(m_historyPanel, SIGNAL(itemHovered(QString)), this, SLOT(notifyMessage(QString))); connect(m_historyPanel, SIGNAL(destroyed()), Application::instance(), SLOT(saveConfiguration())); addDockWidget(Qt::LeftDockWidgetArea, m_historyPanel); @@ -514,7 +515,8 @@ void MainWindow::setupPanels() // STEP 2 // Setup bookmarks panel m_bookmarksPanel = new BookmarksPanel(i18n("Bookmarks Panel"), this); - connect(m_bookmarksPanel, SIGNAL(openUrl(const KUrl&)), Application::instance(), SLOT(loadUrl(const KUrl&))); + connect(m_bookmarksPanel, SIGNAL(openUrl(const KUrl&, const Rekonq::OpenType &)), Application::instance(), SLOT(loadUrl(const KUrl&, const Rekonq::OpenType &))); + connect(m_bookmarksPanel, SIGNAL(itemHovered(QString)), this, SLOT(notifyMessage(QString))); connect(m_bookmarksPanel, SIGNAL(destroyed()), Application::instance(), SLOT(saveConfiguration())); addDockWidget(Qt::LeftDockWidgetArea, m_bookmarksPanel); -- cgit v1.2.1 From c3a78d70b23ff4bdc2faec12c97b982a06c96986 Mon Sep 17 00:00:00 2001 From: Yoann Laissus Date: Tue, 23 Mar 2010 23:54:50 +0100 Subject: Add missing files --- src/urltreeview.cpp | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/urltreeview.h | 69 +++++++++++++++++++ 2 files changed, 264 insertions(+) create mode 100644 src/urltreeview.cpp create mode 100644 src/urltreeview.h diff --git a/src/urltreeview.cpp b/src/urltreeview.cpp new file mode 100644 index 00000000..b88dc971 --- /dev/null +++ b/src/urltreeview.cpp @@ -0,0 +1,195 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Yoann Laissus +* +* +* 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 . +* +* ============================================================ */ + + +// Self Includes +#include "urltreeview.h" + +// Local Includes +#include "application.h" + +// Qt Includes +#include +#include + + +UrlTreeView::UrlTreeView(QWidget *parent) + : QTreeView(parent) +{ + connect(this, SIGNAL(itemHovered(const QString &)), parent, SIGNAL(itemHovered(const QString &))); + connect(this, SIGNAL(openUrl(const KUrl &, Rekonq::OpenType)), parent, SIGNAL(openUrl(const KUrl &, Rekonq::OpenType))); + setMouseTracking(true); + setExpandsOnDoubleClick(false); +} + + +UrlTreeView::~UrlTreeView() +{ +} + + +void UrlTreeView::mousePressEvent(QMouseEvent *event) +{ + const QModelIndex index = indexAt(event->pos()); + bool expanded = isExpanded(index); + + QTreeView::mousePressEvent(event); + + // A change of an item expansion is handle by mouseReleaseEvent() + // So toggle again the item + if(expanded != isExpanded(index)) + setExpanded(index, !isExpanded(index)); + + if(!index.isValid()) + { + clearSelection(); + setCurrentIndex(QModelIndex()); + + if(event->button() == Qt::RightButton) + emit contextMenuEmptyRequested(event->pos()); + return; + } + + if(event->button() == Qt::RightButton) + { + if(index.model()->rowCount(index) == 0) + { + // An empty group needs to be handle by the panels + emit contextMenuItemRequested(event->pos()); + } + else + { + emit contextMenuGroupRequested(event->pos()); + } + } +} + + +void UrlTreeView::mouseReleaseEvent(QMouseEvent *event) +{ + QTreeView::mouseReleaseEvent(event); + + const QModelIndex index = indexAt(event->pos()); + if(!index.isValid()) + return; + + if(event->button() == Qt::MidButton) + validOpenUrl(qVariantValue< KUrl >(index.data(Qt::UserRole)), Rekonq::NewCurrentTab); + + else if(event->button() == Qt::LeftButton) + { + if(index.model()->rowCount(index) == 0) + validOpenUrl(qVariantValue< KUrl >(index.data(Qt::UserRole))); + else + setExpanded(index, !isExpanded(index)); + } +} + + +void UrlTreeView::keyPressEvent(QKeyEvent *event) +{ + QTreeView::keyPressEvent(event); + QModelIndex index = currentIndex(); + + if(!index.isValid()) + return; + + if(event->key() == Qt::Key_Return) + { + if(index.model()->rowCount(index) == 0) + validOpenUrl(qVariantValue< KUrl >(index.data(Qt::UserRole))); + else + setExpanded(index, !isExpanded(index)); + } + + else if(event->key() == Qt::Key_Delete) + { + emit delKeyPressed(); + } +} + + +void UrlTreeView::validOpenUrl(const KUrl &url, Rekonq::OpenType openType) +{ + // To workaround a crash when the url is about:blank + if(url.url() == "about:blank") + emit openUrl(KUrl("about:home"), openType); + else + emit openUrl(url, openType); +} + + +void UrlTreeView::mouseMoveEvent(QMouseEvent *event) +{ + QTreeView::mouseMoveEvent(event); + const QModelIndex index = indexAt(event->pos()); + if(!index.isValid()) + { + emit itemHovered(""); + return; + } + emit itemHovered(qVariantValue< KUrl >(index.data(Qt::UserRole)).url()); +} + + +void UrlTreeView::openInCurrentTab() +{ + QModelIndex index = currentIndex(); + if(!index.isValid()) + return; + + validOpenUrl(qVariantValue< KUrl >(index.data(Qt::UserRole))); +} + + +void UrlTreeView::copyToClipboard() +{ + QModelIndex index = currentIndex(); + if(!index.isValid()) + return; + + QClipboard *cb = QApplication::clipboard(); + cb->setText(qVariantValue< KUrl >(index.data(Qt::UserRole)).url()); +} + + +void UrlTreeView::openInNewTab() +{ + QModelIndex index = currentIndex(); + if(!index.isValid()) + return; + + validOpenUrl(qVariantValue< KUrl >(index.data(Qt::UserRole)), Rekonq::SettingOpenTab); +} + + +void UrlTreeView::openInNewWindow() +{ + QModelIndex index = currentIndex(); + if(!index.isValid()) + return; + + validOpenUrl( qVariantValue< KUrl >(index.data(Qt::UserRole)), Rekonq::NewWindow); +} diff --git a/src/urltreeview.h b/src/urltreeview.h new file mode 100644 index 00000000..cce7a257 --- /dev/null +++ b/src/urltreeview.h @@ -0,0 +1,69 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Yoann Laissus +* +* +* 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 . +* +* ============================================================ */ + + +#ifndef URLTREEVIEW_H +#define URLTREEVIEW_H + +// Local Includes +#include "application.h" + +// Qt Includes +#include + + +class UrlTreeView : public QTreeView +{ + Q_OBJECT + +public: + UrlTreeView(QWidget *parent = 0); + ~UrlTreeView(); + +signals: + void openUrl(const KUrl &, const Rekonq::OpenType &); + void itemHovered(const QString &); + void delKeyPressed(); + void contextMenuItemRequested(const QPoint &pos); + void contextMenuGroupRequested(const QPoint &pos); + void contextMenuEmptyRequested(const QPoint &pos); + +public slots: + void copyToClipboard(); + void openInCurrentTab(); + void openInNewTab(); + void openInNewWindow(); + +protected: + void mouseReleaseEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void keyPressEvent(QKeyEvent *event); + +private: + void validOpenUrl(const KUrl &url, Rekonq::OpenType openType = Rekonq::CurrentTab); +}; + +#endif // URLTREEVIEW_H -- cgit v1.2.1 From 9ede70edadea14f3a1ee4d66ca03ec20a6133f72 Mon Sep 17 00:00:00 2001 From: Yoann Laissus Date: Thu, 25 Mar 2010 12:22:04 +0100 Subject: Add tests for the bookmark before toGroup() --- src/bookmarks/bookmarkspanel.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/bookmarks/bookmarkspanel.cpp b/src/bookmarks/bookmarkspanel.cpp index c50ebcdb..fdf1b3d8 100644 --- a/src/bookmarks/bookmarkspanel.cpp +++ b/src/bookmarks/bookmarkspanel.cpp @@ -157,13 +157,16 @@ void BookmarksPanel::autoExpand(const QModelIndex &root) { int count = m_treeView->model()->rowCount(root); - QModelIndex temp; + QModelIndex index; for(int i = 0; i < count; i++) { - temp = m_treeView->model()->index(i,0,root); - m_treeView->setExpanded(temp, bookmarkForIndex(temp).toGroup().isOpen()); - autoExpand(temp); + index = m_treeView->model()->index(i, 0, root); + if(index.isValid() && bookmarkForIndex(index).isGroup()) + { + m_treeView->setExpanded(index, bookmarkForIndex(index).toGroup().isOpen()); + autoExpand(index); + } } } @@ -369,7 +372,7 @@ void BookmarksPanel::editBookmark() void BookmarksPanel::openAll() { QModelIndex index = m_treeView->currentIndex(); - if(!index.isValid()) + if(!index.isValid() || !bookmarkForIndex(index).isGroup()) return; QList allChild = bookmarkForIndex(index).toGroup().groupUrlList(); -- cgit v1.2.1 From 632389517ca496031bb1cbe468d904884961bf57 Mon Sep 17 00:00:00 2001 From: Yoann Laissus Date: Sat, 27 Mar 2010 19:04:11 +0100 Subject: - Fix a crash when the cancel button of the add bookmark menu is clicked - Use the same behaviour for delete bookmark as the toolbar - Some strings changed - Keep the selection of a folder when it's expanded/collapsed - Fix the name of some methods and properties - Code cleaned a bit --- src/bookmarks/bookmarkspanel.cpp | 153 +++++++++++++++++++---------------- src/bookmarks/bookmarkspanel.h | 19 ++--- src/bookmarks/bookmarkstreemodel.cpp | 24 ++++-- src/bookmarks/bookmarkstreemodel.h | 7 +- src/urltreeview.cpp | 6 +- 5 files changed, 119 insertions(+), 90 deletions(-) diff --git a/src/bookmarks/bookmarkspanel.cpp b/src/bookmarks/bookmarkspanel.cpp index fdf1b3d8..c5c2f548 100644 --- a/src/bookmarks/bookmarkspanel.cpp +++ b/src/bookmarks/bookmarkspanel.cpp @@ -55,8 +55,7 @@ BookmarksPanel::BookmarksPanel(const QString &title, QWidget *parent, Qt::Window : QDockWidget(title, parent, flags), m_treeView(new UrlTreeView(this)), m_ac(new KActionCollection(this)), - menu(new KMenu(this)), - expandLock(false) + m_loadingState(false) { setup(); setupActions(); @@ -119,41 +118,41 @@ void BookmarksPanel::setup() 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 &))); - callAutoExpand(); + loadFoldedState(); } void BookmarksPanel::onCollapse(const QModelIndex &index) { - if(expandLock) + if(m_loadingState) return; KBookmark bookmark = bookmarkForIndex(index); bookmark.internalElement().setAttribute("folded", "yes"); - Application::bookmarkProvider()->bookmarkManager()->emitChanged(); + emit saveOnlyRequested(); } void BookmarksPanel::onExpand(const QModelIndex &index) { - if(expandLock) + if(m_loadingState) return; KBookmark bookmark = bookmarkForIndex(index); bookmark.internalElement().setAttribute("folded", "no"); - Application::bookmarkProvider()->bookmarkManager()->emitChanged(); + emit saveOnlyRequested(); } -void BookmarksPanel::callAutoExpand() +void BookmarksPanel::loadFoldedState() { - expandLock = true; - autoExpand(); - expandLock = false; + m_loadingState = true; + loadFoldedState(QModelIndex()); + m_loadingState = false; } -void BookmarksPanel::autoExpand(const QModelIndex &root) +void BookmarksPanel::loadFoldedState(const QModelIndex &root) { int count = m_treeView->model()->rowCount(root); @@ -165,7 +164,7 @@ void BookmarksPanel::autoExpand(const QModelIndex &root) if(index.isValid() && bookmarkForIndex(index).isGroup()) { m_treeView->setExpanded(index, bookmarkForIndex(index).toGroup().isOpen()); - autoExpand(index); + loadFoldedState(index); } } } @@ -177,47 +176,47 @@ void BookmarksPanel::setupActions() action = new KAction(KIcon("tab-new"), i18n("Open"), this); connect(action, SIGNAL(triggered()), m_treeView, SLOT(openInCurrentTab())); - m_ac.addAction("open", action); + m_ac->addAction("open", action); action = new KAction(KIcon("tab-new"), i18n("Open in New Tab"), this); connect(action, SIGNAL(triggered()), m_treeView, SLOT(openInNewTab())); - m_ac.addAction("open_tab", action); + m_ac->addAction("open_tab", action); action = new KAction(KIcon("window-new"), i18n("Open in New Window"), this); connect(action, SIGNAL(triggered()), m_treeView, SLOT(openInNewWindow())); - m_ac.addAction("open_window", action); + m_ac->addAction("open_window", action); - action = new KAction(KIcon("rating"), i18n("Bookmark Page"), this); + action = new KAction(KIcon("rating"), i18n("Bookmark Current Page"), this); connect(action, SIGNAL(triggered()), this, SLOT(bookmarkPage())); - m_ac.addAction("bookmark_page", action); + m_ac->addAction("bookmark_page", action); action = new KAction(KIcon("bookmark-new"), i18n("New Bookmark"), this); connect(action, SIGNAL(triggered()), this, SLOT(newBookmark())); - m_ac.addAction("bookmark_new", action); + m_ac->addAction("bookmark_new", 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); + 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); + m_ac->addAction("separator_new", action); - action = new KAction(KIcon("edit-copy"), i18n("Copy Link"), this); + action = new KAction(KIcon("edit-copy"), i18n("Copy Link Adress"), this); connect(action, SIGNAL(triggered()), m_treeView, SLOT(copyToClipboard())); - m_ac.addAction("copy", action); + m_ac->addAction("copy", action); - action = new KAction(KIcon("edit-delete"), i18n("Delete"), this); + action = new KAction(KIcon("edit-delete"), i18n("Delete Bookmark"), this); connect(action, SIGNAL(triggered()), this, SLOT(deleteBookmark())); - m_ac.addAction("delete", action); + 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); + m_ac->addAction("properties", action); - action = new KAction(KIcon("tab-new"), i18n("Open all Bookmarks"), this); - connect(action, SIGNAL(triggered()), this, SLOT(openAll())); - m_ac.addAction("open_all", 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); } @@ -238,7 +237,7 @@ void BookmarksPanel::contextMenuBk(const QPoint &pos) { QPoint position = m_treeView->mapToGlobal(pos); QModelIndex index = m_treeView->indexAt(pos); - if(!index.isValid() || expandLock) + if(!index.isValid() || m_loadingState) return; KBookmark selected = bookmarkForIndex(index); @@ -255,27 +254,27 @@ void BookmarksPanel::contextMenuBk(const QPoint &pos) return; } - menu = new KMenu(this); + KMenu *menu = new KMenu(this); - menu->addAction(m_ac.action("open")); - menu->addAction(m_ac.action("open_tab")); - menu->addAction(m_ac.action("open_window")); + menu->addAction(m_ac->action("open")); + menu->addAction(m_ac->action("open_tab")); + menu->addAction(m_ac->action("open_window")); menu->addSeparator(); - menu->addAction(m_ac.action("bookmark_page")); - menu->addAction(m_ac.action("bookmark_new")); - menu->addAction(m_ac.action("folder_new")); - menu->addAction(m_ac.action("separator_new")); + menu->addAction(m_ac->action("bookmark_page")); + menu->addAction(m_ac->action("bookmark_new")); + menu->addAction(m_ac->action("folder_new")); + menu->addAction(m_ac->action("separator_new")); menu->addSeparator(); - menu->addAction(m_ac.action("copy")); + menu->addAction(m_ac->action("copy")); menu->addSeparator(); - menu->addAction(m_ac.action("delete")); - menu->addAction(m_ac.action("properties")); + menu->addAction(m_ac->action("delete")); + menu->addAction(m_ac->action("properties")); menu->popup(position); } @@ -283,27 +282,27 @@ void BookmarksPanel::contextMenuBk(const QPoint &pos) void BookmarksPanel::contextMenuBkGroup(const QPoint &pos, bool emptyGroup) { - if(expandLock) + if(m_loadingState) return; QPoint position = m_treeView->mapToGlobal(pos); - menu = new KMenu(this); + KMenu *menu = new KMenu(this); if(!emptyGroup) { - menu->addAction(m_ac.action("open_all")); + menu->addAction(m_ac->action("open_all")); menu->addSeparator(); } - menu->addAction(m_ac.action("bookmark_page")); - menu->addAction(m_ac.action("bookmark_new")); - menu->addAction(m_ac.action("folder_new")); - menu->addAction(m_ac.action("separator_new")); + menu->addAction(m_ac->action("bookmark_page")); + menu->addAction(m_ac->action("bookmark_new")); + menu->addAction(m_ac->action("folder_new")); + menu->addAction(m_ac->action("separator_new")); menu->addSeparator(); - menu->addAction(m_ac.action("delete")); - menu->addAction(m_ac.action("properties")); + menu->addAction(m_ac->action("delete")); + menu->addAction(m_ac->action("properties")); menu->popup(position); } @@ -312,16 +311,16 @@ void BookmarksPanel::contextMenuBkGroup(const QPoint &pos, bool emptyGroup) void BookmarksPanel::contextMenuSeparator(const QPoint &pos) { QPoint position = m_treeView->mapToGlobal(pos); - menu = new KMenu(this); + KMenu *menu = new KMenu(this); - menu->addAction(m_ac.action("bookmark_page")); - menu->addAction(m_ac.action("bookmark_new")); - menu->addAction(m_ac.action("folder_new")); - menu->addAction(m_ac.action("separator_new")); + menu->addAction(m_ac->action("bookmark_page")); + menu->addAction(m_ac->action("bookmark_new")); + menu->addAction(m_ac->action("folder_new")); + menu->addAction(m_ac->action("separator_new")); menu->addSeparator(); - menu->addAction(m_ac.action("delete")); + menu->addAction(m_ac->action("delete")); menu->popup(position); } @@ -330,12 +329,12 @@ void BookmarksPanel::contextMenuSeparator(const QPoint &pos) void BookmarksPanel::contextMenuBlank(const QPoint &pos) { QPoint position = m_treeView->mapToGlobal(pos); - menu = new KMenu(this); + KMenu *menu = new KMenu(this); - menu->addAction(m_ac.action("bookmark_page")); - menu->addAction(m_ac.action("bookmark_new")); - menu->addAction(m_ac.action("folder_new")); - menu->addAction(m_ac.action("separator_new")); + menu->addAction(m_ac->action("bookmark_page")); + menu->addAction(m_ac->action("bookmark_new")); + menu->addAction(m_ac->action("folder_new")); + menu->addAction(m_ac->action("separator_new")); menu->popup(position); } @@ -347,10 +346,22 @@ void BookmarksPanel::deleteBookmark() if(!index.isValid()) return; - KBookmark selected = bookmarkForIndex(index); - KBookmarkGroup parent = selected.parentGroup(); + 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; - parent.deleteBookmark(selected); + + bm.parentGroup().deleteBookmark(bm); Application::instance()->bookmarkProvider()->bookmarkManager()->emitChanged(); } @@ -369,7 +380,7 @@ void BookmarksPanel::editBookmark() } -void BookmarksPanel::openAll() +void BookmarksPanel::openFolderInTabs() { QModelIndex index = m_treeView->currentIndex(); if(!index.isValid() || !bookmarkForIndex(index).isGroup()) @@ -402,18 +413,22 @@ void BookmarksPanel::newBookmark() selected = bookmarkForIndex(index); if(selected.isGroup()) - newBk = dialog->addBookmark("New bookmark", KUrl("www.kde.org"), selected); + newBk = dialog->addBookmark("New bookmark", KUrl(), selected); else - newBk = dialog->addBookmark("New bookmark", KUrl("www.kde.org"), selected.parentGroup()); + newBk = dialog->addBookmark("New bookmark", KUrl(), selected.parentGroup()); } else { - newBk = dialog->addBookmark("New bookmark", KUrl("www.kde.org")); + newBk = dialog->addBookmark("New bookmark", KUrl()); } delete dialog; + // a click on cancel + if(newBk.isNull()) + return; + // addBookmark already added the bookmark, but without the default favicon KBookmarkGroup parent = newBk.parentGroup(); parent.deleteBookmark(newBk); @@ -493,7 +508,7 @@ void BookmarksPanel::newSeparator() } -void BookmarksPanel::bookmarkPage() +void BookmarksPanel::bookmarkCurrentPage() { QModelIndex index = m_treeView->currentIndex(); KBookmarkGroup parent = Application::bookmarkProvider()->rootGroup(); diff --git a/src/bookmarks/bookmarkspanel.h b/src/bookmarks/bookmarkspanel.h index ea33e265..be52804f 100644 --- a/src/bookmarks/bookmarkspanel.h +++ b/src/bookmarks/bookmarkspanel.h @@ -40,7 +40,6 @@ // KDE Includes #include #include -#include // Forward Declarations class KUrl; @@ -58,24 +57,24 @@ public: signals: void openUrl(const KUrl &, const Rekonq::OpenType &); void itemHovered(const QString &); - void saveExpFinished(const QString &); - void saveRequested(); + void saveOnlyRequested(); private slots: void contextMenuBk(const QPoint &pos); void contextMenuBkGroup(const QPoint &pos, const bool emptyGroup = false); void contextMenuBlank(const QPoint &pos); void deleteBookmark(); - void openAll(); + void openFolderInTabs(); void editBookmark(); void newBookmark(); void newBookmarkGroup(); void newSeparator(); - void bookmarkPage(); - void autoExpand(const QModelIndex &root = QModelIndex()); void onCollapse(const QModelIndex &index); void onExpand(const QModelIndex &index); - void callAutoExpand(); + void bookmarkCurrentPage(); + void loadFoldedState(const QModelIndex &root); + void loadFoldedState(); + private: void setup(); @@ -84,10 +83,8 @@ private: KBookmark bookmarkForIndex(const QModelIndex &index); UrlTreeView *m_treeView; - QStringList m_expList; - KActionCollection m_ac; - KMenu *menu; - bool expandLock; + KActionCollection *m_ac; + bool m_loadingState; }; #endif // BOOKMARKSPANEL_H diff --git a/src/bookmarks/bookmarkstreemodel.cpp b/src/bookmarks/bookmarkstreemodel.cpp index d63c92d3..836401a6 100644 --- a/src/bookmarks/bookmarkstreemodel.cpp +++ b/src/bookmarks/bookmarkstreemodel.cpp @@ -148,8 +148,9 @@ BookmarksTreeModel::BookmarksTreeModel(QObject *parent) , m_root(0) { resetModel(); - connect( this, SIGNAL(bookmarkChangedFinished()), parent, SLOT(callAutoExpand())); - connect( Application::bookmarkProvider()->bookmarkManager(), SIGNAL( changed(QString,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()) ); } @@ -283,11 +284,10 @@ QVariant BookmarksTreeModel::data(const QModelIndex &index, int role) const } -void BookmarksTreeModel::bookmarksChanged( const QString &groupAddress ) +void BookmarksTreeModel::bookmarksChanged() { - Q_UNUSED(groupAddress); resetModel(); - emit bookmarkChangedFinished(); + emit bookmarksUpdated(); } @@ -336,6 +336,20 @@ KBookmark BookmarksTreeModel::bookmarkForIndex(const QModelIndex index) const } +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; diff --git a/src/bookmarks/bookmarkstreemodel.h b/src/bookmarks/bookmarkstreemodel.h index 4ff19e5f..b312ab2d 100644 --- a/src/bookmarks/bookmarkstreemodel.h +++ b/src/bookmarks/bookmarkstreemodel.h @@ -84,13 +84,16 @@ public: virtual QMimeData *mimeData( const QModelIndexList & indexes ) const; private slots: - void bookmarksChanged( const QString &groupAddress ); + void bookmarksChanged(); + void saveOnly(); + void reconnectManager(); signals: - void bookmarkChangedFinished(); + void bookmarksUpdated(); private: BtmItem *m_root; + void resetModel(); void setRoot(KBookmarkGroup bmg); void populate( BtmItem *node, KBookmarkGroup bmg); diff --git a/src/urltreeview.cpp b/src/urltreeview.cpp index b88dc971..507a7973 100644 --- a/src/urltreeview.cpp +++ b/src/urltreeview.cpp @@ -74,7 +74,7 @@ void UrlTreeView::mousePressEvent(QMouseEvent *event) if(event->button() == Qt::RightButton) { - if(index.model()->rowCount(index) == 0) + if(model()->rowCount(index) == 0) { // An empty group needs to be handle by the panels emit contextMenuItemRequested(event->pos()); @@ -100,7 +100,7 @@ void UrlTreeView::mouseReleaseEvent(QMouseEvent *event) else if(event->button() == Qt::LeftButton) { - if(index.model()->rowCount(index) == 0) + if(model()->rowCount(index) == 0) validOpenUrl(qVariantValue< KUrl >(index.data(Qt::UserRole))); else setExpanded(index, !isExpanded(index)); @@ -118,7 +118,7 @@ void UrlTreeView::keyPressEvent(QKeyEvent *event) if(event->key() == Qt::Key_Return) { - if(index.model()->rowCount(index) == 0) + if(model()->rowCount(index) == 0) validOpenUrl(qVariantValue< KUrl >(index.data(Qt::UserRole))); else setExpanded(index, !isExpanded(index)); -- cgit v1.2.1 From f5a40919219ef5210598a87054af34b331ebe31e Mon Sep 17 00:00:00 2001 From: Yoann Laissus Date: Sat, 27 Mar 2010 20:08:59 +0100 Subject: Fix the bookmarkCurrentPage slot name --- src/bookmarks/bookmarkspanel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bookmarks/bookmarkspanel.cpp b/src/bookmarks/bookmarkspanel.cpp index c5c2f548..a1bc4f51 100644 --- a/src/bookmarks/bookmarkspanel.cpp +++ b/src/bookmarks/bookmarkspanel.cpp @@ -187,7 +187,7 @@ void BookmarksPanel::setupActions() m_ac->addAction("open_window", action); action = new KAction(KIcon("rating"), i18n("Bookmark Current Page"), this); - connect(action, SIGNAL(triggered()), this, SLOT(bookmarkPage())); + connect(action, SIGNAL(triggered()), this, SLOT(bookmarkCurrentPage())); m_ac->addAction("bookmark_page", action); action = new KAction(KIcon("bookmark-new"), i18n("New Bookmark"), this); -- cgit v1.2.1 From a3020fb4be790a79af806b4d22b5d9bdc790ee7f Mon Sep 17 00:00:00 2001 From: Yoann Laissus Date: Sat, 27 Mar 2010 20:20:12 +0100 Subject: Fix missing strings on the history panel --- src/bookmarks/bookmarkspanel.cpp | 2 +- src/history/historypanel.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/bookmarks/bookmarkspanel.cpp b/src/bookmarks/bookmarkspanel.cpp index a1bc4f51..c249566d 100644 --- a/src/bookmarks/bookmarkspanel.cpp +++ b/src/bookmarks/bookmarkspanel.cpp @@ -202,7 +202,7 @@ void BookmarksPanel::setupActions() connect(action, SIGNAL(triggered()), this, SLOT(newSeparator())); m_ac->addAction("separator_new", action); - action = new KAction(KIcon("edit-copy"), i18n("Copy Link Adress"), this); + action = new KAction(KIcon("edit-copy"), i18n("Copy Link Address"), this); connect(action, SIGNAL(triggered()), m_treeView, SLOT(copyToClipboard())); m_ac->addAction("copy", action); diff --git a/src/history/historypanel.cpp b/src/history/historypanel.cpp index c67594ff..a45e3508 100644 --- a/src/history/historypanel.cpp +++ b/src/history/historypanel.cpp @@ -129,15 +129,15 @@ void HistoryPanel::contextMenuItem(const QPoint &pos) connect(action, SIGNAL(triggered()), m_treeView, SLOT(openInCurrentTab())); menu->addAction(action); - action = new KAction(KIcon("tab-new"), i18n("Open in new tab"), this); + action = new KAction(KIcon("tab-new"), i18n("Open in New Tab"), this); connect(action, SIGNAL(triggered()), m_treeView, SLOT(openInNewTab())); menu->addAction(action); - action = new KAction(KIcon("window-new"), i18n("Open in new window"), this); + action = new KAction(KIcon("window-new"), i18n("Open in New Window"), this); connect(action, SIGNAL(triggered()), m_treeView, SLOT(openInNewWindow())); menu->addAction(action); - action = new KAction(KIcon("edit-copy"), i18n("Copy link"), this); + action = new KAction(KIcon("edit-copy"), i18n("Copy Link Address"), this); connect(action, SIGNAL(triggered()), m_treeView, SLOT(copyToClipboard())); menu->addAction(action); @@ -152,7 +152,7 @@ void HistoryPanel::contextMenuGroup(const QPoint &pos) KMenu *menu = new KMenu(this); KAction* action; - action = new KAction(KIcon("tab-new"), i18n("Open all Bookmarks"), this); + action = new KAction(KIcon("tab-new"), i18n("Open Folder in Tabs"), this); connect(action, SIGNAL(triggered()), this, SLOT(openAll())); menu->addAction(action); -- cgit v1.2.1 From 6183e8e1c21807299f04f4e84c43486cf684f140 Mon Sep 17 00:00:00 2001 From: Yoann Laissus Date: Sat, 27 Mar 2010 22:17:20 +0100 Subject: - Remove the Add Bookmark action from the different context menus - Add Bookmark Here now add the bookmark on top of the selected item - ctor initialisation for the UrlTreeView of the history panel --- src/bookmarks/bookmarkspanel.cpp | 55 ++-------------------------------------- src/bookmarks/bookmarkspanel.h | 1 - src/history/historypanel.cpp | 4 +-- 3 files changed, 4 insertions(+), 56 deletions(-) diff --git a/src/bookmarks/bookmarkspanel.cpp b/src/bookmarks/bookmarkspanel.cpp index c249566d..2f530c6c 100644 --- a/src/bookmarks/bookmarkspanel.cpp +++ b/src/bookmarks/bookmarkspanel.cpp @@ -186,14 +186,10 @@ void BookmarksPanel::setupActions() connect(action, SIGNAL(triggered()), m_treeView, SLOT(openInNewWindow())); m_ac->addAction("open_window", action); - action = new KAction(KIcon("rating"), i18n("Bookmark Current Page"), this); + 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("bookmark-new"), i18n("New Bookmark"), this); - connect(action, SIGNAL(triggered()), this, SLOT(newBookmark())); - m_ac->addAction("bookmark_new", 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); @@ -263,7 +259,6 @@ void BookmarksPanel::contextMenuBk(const QPoint &pos) menu->addSeparator(); menu->addAction(m_ac->action("bookmark_page")); - menu->addAction(m_ac->action("bookmark_new")); menu->addAction(m_ac->action("folder_new")); menu->addAction(m_ac->action("separator_new")); @@ -295,7 +290,6 @@ void BookmarksPanel::contextMenuBkGroup(const QPoint &pos, bool emptyGroup) } menu->addAction(m_ac->action("bookmark_page")); - menu->addAction(m_ac->action("bookmark_new")); menu->addAction(m_ac->action("folder_new")); menu->addAction(m_ac->action("separator_new")); @@ -314,7 +308,6 @@ void BookmarksPanel::contextMenuSeparator(const QPoint &pos) KMenu *menu = new KMenu(this); menu->addAction(m_ac->action("bookmark_page")); - menu->addAction(m_ac->action("bookmark_new")); menu->addAction(m_ac->action("folder_new")); menu->addAction(m_ac->action("separator_new")); @@ -332,7 +325,6 @@ void BookmarksPanel::contextMenuBlank(const QPoint &pos) KMenu *menu = new KMenu(this); menu->addAction(m_ac->action("bookmark_page")); - menu->addAction(m_ac->action("bookmark_new")); menu->addAction(m_ac->action("folder_new")); menu->addAction(m_ac->action("separator_new")); @@ -399,49 +391,6 @@ void BookmarksPanel::openFolderInTabs() } -void BookmarksPanel::newBookmark() -{ - QModelIndex index = m_treeView->currentIndex(); - - KBookmark selected; - KBookmark newBk; - - KBookmarkDialog *dialog = Application::bookmarkProvider()->bookmarkOwner()->bookmarkDialog(Application::bookmarkProvider()->bookmarkManager(), QApplication::activeWindow()); - - if(index.isValid()) - { - selected = bookmarkForIndex(index); - - if(selected.isGroup()) - newBk = dialog->addBookmark("New bookmark", KUrl(), selected); - else - newBk = dialog->addBookmark("New bookmark", KUrl(), selected.parentGroup()); - } - - else - { - newBk = dialog->addBookmark("New bookmark", KUrl()); - } - - delete dialog; - - // a click on cancel - if(newBk.isNull()) - return; - - // addBookmark already added the bookmark, but without the default favicon - KBookmarkGroup parent = newBk.parentGroup(); - parent.deleteBookmark(newBk); - newBk.setIcon(("text-html")); - parent.addBookmark(newBk); - - if(index.isValid()) - parent.moveBookmark(newBk, selected); - - Application::bookmarkProvider()->bookmarkManager()->emitChanged(); -} - - void BookmarksPanel::newBookmarkGroup() { QModelIndex index = m_treeView->currentIndex(); @@ -522,7 +471,7 @@ void BookmarksPanel::bookmarkCurrentPage() parent = selected.toGroup(); KBookmark newBk = parent.addBookmark(Application::bookmarkProvider()->bookmarkOwner()->currentTitle(), KUrl(Application::bookmarkProvider()->bookmarkOwner()->currentUrl()), "text-html"); - parent.moveBookmark(newBk, selected); + parent.moveBookmark(newBk, selected.parentGroup().previous(selected)); } else diff --git a/src/bookmarks/bookmarkspanel.h b/src/bookmarks/bookmarkspanel.h index be52804f..f8528b71 100644 --- a/src/bookmarks/bookmarkspanel.h +++ b/src/bookmarks/bookmarkspanel.h @@ -66,7 +66,6 @@ private slots: void deleteBookmark(); void openFolderInTabs(); void editBookmark(); - void newBookmark(); void newBookmarkGroup(); void newSeparator(); void onCollapse(const QModelIndex &index); diff --git a/src/history/historypanel.cpp b/src/history/historypanel.cpp index a45e3508..03f2b880 100644 --- a/src/history/historypanel.cpp +++ b/src/history/historypanel.cpp @@ -52,7 +52,8 @@ HistoryPanel::HistoryPanel(const QString &title, QWidget *parent, Qt::WindowFlags flags) - : QDockWidget(title, parent, flags) + : QDockWidget(title, parent, flags), + m_treeView(new UrlTreeView(this)) { setup(); setShown(ReKonfig::showHistoryPanel()); @@ -73,7 +74,6 @@ void HistoryPanel::setup() QWidget *ui = new QWidget(this); - m_treeView = new UrlTreeView(this); m_treeView->setUniformRowHeights(true); m_treeView->setSelectionBehavior(QAbstractItemView::SelectRows); m_treeView->setTextElideMode(Qt::ElideMiddle); -- cgit v1.2.1 From 638dbe31c97695f6713475bb50c02fad3383615c Mon Sep 17 00:00:00 2001 From: Andrea Diamantini Date: Sun, 28 Mar 2010 00:07:52 +0100 Subject: rekonq 0.4.56 History & Bookmark panels improvements --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d41552a4..51393fc8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ PROJECT( rekonq ) # Informations to update before to release this package. # rekonq info -SET(REKONQ_VERSION "0.4.55" ) +SET(REKONQ_VERSION "0.4.56" ) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/version.h ) -- cgit v1.2.1 From 64408ad486db25f0124f934aed55af72f2cd6d39 Mon Sep 17 00:00:00 2001 From: Andrea Diamantini Date: Sun, 28 Mar 2010 10:12:45 +0200 Subject: update is better than repaint :) --- src/urlbar/urlbar.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/urlbar/urlbar.cpp b/src/urlbar/urlbar.cpp index 718d9f67..189d19fe 100644 --- a/src/urlbar/urlbar.cpp +++ b/src/urlbar/urlbar.cpp @@ -155,7 +155,7 @@ void UrlBar::setUrl(const QUrl& url) void UrlBar::setProgress(int progress) { m_progress = progress; - repaint(); + update(); } @@ -225,14 +225,14 @@ void UrlBar::loadFinished(bool) { // reset progress bar after small delay m_progress = 0; - QTimer::singleShot(200, this, SLOT(repaint())); + QTimer::singleShot(200, this, SLOT(update())); } void UrlBar::updateProgress(int progress) { m_progress = progress; - repaint(); + update(); } @@ -295,7 +295,7 @@ QLinearGradient UrlBar::generateGradient(const QColor &color, int height) void UrlBar::setBackgroundColor(QColor c) { s_defaultBaseColor = c; - repaint(); + update(); } -- cgit v1.2.1 From 942c55b945443a2e6dd9a2d3660347fc2176630a Mon Sep 17 00:00:00 2001 From: Andrea Diamantini Date: Mon, 29 Mar 2010 11:47:42 +0200 Subject: This commit merge all our work about new UrlBar. DISCLAIMER: this is far from perfect, but we finally have a good starting point to work on.. :) Jonas Gastal started working on it in the 0.3 times, startin from CompletionBase code .. .. I did some work on another idea, proposing (in code) a new "suggest engine" created from scratch... Lionel Chauvin finally merged our ideas and implemented what you are seeing (and improved it, too!).. - New suggestion items (Firefox style) - a mockup on the known urls (rekonq style) - for now, automatic Google and Wikipedia searches (more coming).. - a beautiful animation :) - quite all rough edges smoothed -------------------------------------------------------- Squashed commit of the following: commit d9cf43da421c7f6c71f78444ff1935c414468b98 commit 9dcb6e18f8a3e9ae8ef1cd1299d47d37393aa6e5 commit 6c4bf2b2040ea20c78c5703f20c6bc88b7e40169 commit 8488df67115d186489f34210b638c150c66f62d3 commit 066ab907661282b1ffa4cf640739c20b4c7b6556 commit c23e23cbca7ab3197c570651a95d3f8fea270d78 commit 60655b0a8685a76e2b8b7a457bfded974bc98b4c commit 9a8817db124b55f501c9e5d3415a975ee6f92d68 commit 61312b6b577a535a4d56758b3bd3ea38812d5139 commit b6a3f4ea12423a063eafa641cedd13b890b9d392 commit 5e8e2f851edb42bc2deed296c26c58c3d7570381 commit 2904d828f71ac8ff46a53e58da8f45b5aa16e7ef --------------------------------------------------------- --- src/CMakeLists.txt | 3 + src/bookmarks/bookmarksmanager.cpp | 14 ++- src/bookmarks/bookmarksmanager.h | 7 ++ src/mainview.cpp | 3 +- src/urlbar/completionwidget.cpp | 242 +++++++++++++++++++++++++++++++++++++ src/urlbar/completionwidget.h | 77 ++++++++++++ src/urlbar/lineedit.cpp | 4 +- src/urlbar/lineedit.h | 12 +- src/urlbar/listitem.cpp | 173 ++++++++++++++++++++++++++ src/urlbar/listitem.h | 59 +++++++++ src/urlbar/urlbar.cpp | 200 +++++++++++++++--------------- src/urlbar/urlbar.h | 28 ++--- src/urlbar/urlresolver.cpp | 177 +++++++++++++++++++++++++++ src/urlbar/urlresolver.h | 72 +++++++++++ 14 files changed, 939 insertions(+), 132 deletions(-) create mode 100644 src/urlbar/completionwidget.cpp create mode 100644 src/urlbar/completionwidget.h create mode 100644 src/urlbar/listitem.cpp create mode 100644 src/urlbar/listitem.h create mode 100644 src/urlbar/urlresolver.cpp create mode 100644 src/urlbar/urlresolver.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0cab993c..a68faa59 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -49,6 +49,9 @@ SET( rekonq_KDEINIT_SRCS #---------------------------------------- urlbar/urlbar.cpp urlbar/lineedit.cpp + urlbar/completionwidget.cpp + urlbar/urlresolver.cpp + urlbar/listitem.cpp ) diff --git a/src/bookmarks/bookmarksmanager.cpp b/src/bookmarks/bookmarksmanager.cpp index 9feed63a..89e39ef8 100644 --- a/src/bookmarks/bookmarksmanager.cpp +++ b/src/bookmarks/bookmarksmanager.cpp @@ -161,7 +161,12 @@ BookmarkProvider::BookmarkProvider(QObject *parent) , 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())) @@ -222,6 +227,7 @@ void BookmarkProvider::slotBookmarksChanged(const QString &group, const QString return; m_bookmarkToolBar->clear(); // FIXME CRASH + m_completion->clear(); KBookmark bookmark = toolBarGroup.first(); while (!bookmark.isNull()) @@ -287,7 +293,8 @@ KAction *BookmarkProvider::fillBookmarkBar(const KBookmark &bookmark) return a; } else - { + { + m_completion->addItem(bookmark.url().path()); return new KBookmarkAction(bookmark, m_owner, this); } } @@ -297,3 +304,8 @@ KBookmarkGroup BookmarkProvider::rootGroup() { return m_manager->root(); } + +KCompletion *BookmarkProvider::completionObject() const +{ + return m_completion; +} diff --git a/src/bookmarks/bookmarksmanager.h b/src/bookmarks/bookmarksmanager.h index e50148e4..18ff3ef0 100644 --- a/src/bookmarks/bookmarksmanager.h +++ b/src/bookmarks/bookmarksmanager.h @@ -39,6 +39,7 @@ // KDE Includes #include +#include // Forward Declarations class BookmarkProvider; @@ -213,6 +214,11 @@ public: KBookmarkManager *bookmarkManager() { return m_manager; } BookmarkOwner *bookmarkOwner() { return m_owner; } + /** + * @returns the KCompletion object. + */ + KCompletion *completionObject() const; + signals: /** * @short This signal is emitted when an url has to be loaded @@ -247,6 +253,7 @@ private: KActionCollection *m_actionCollection; BookmarkMenu *m_bookmarkMenu; KToolBar *m_bookmarkToolBar; + KCompletion *m_completion; }; #endif diff --git a/src/mainview.cpp b/src/mainview.cpp index f2152364..6643becb 100644 --- a/src/mainview.cpp +++ b/src/mainview.cpp @@ -242,8 +242,7 @@ void MainView::clear() { // FIXME (the programmer, not the code) // What exactly do we need to clear here? - m_urlBar->clearHistory(); - m_urlBar->clear(); + m_urlBar->clear(); m_recentlyClosedTabs.clear(); } diff --git a/src/urlbar/completionwidget.cpp b/src/urlbar/completionwidget.cpp new file mode 100644 index 00000000..42abcb73 --- /dev/null +++ b/src/urlbar/completionwidget.cpp @@ -0,0 +1,242 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Andrea Diamantini +* +* +* 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 . +* +* ============================================================ */ + + +// Self Includes +#include "completionwidget.h" +#include "completionwidget.moc" + +// KDE Includes +#include +#include +#include + +// Qt Includes +#include +#include +#include +#include +#include +#include + +#define MAX_ELEMENTS 9 +#include "application.h" + +CompletionWidget::CompletionWidget( QWidget *parent) +:QFrame( parent, Qt::ToolTip) + , _parent(parent) + , _currentIndex(-1) +{ + QPalette p(palette()); + p.setColor(QPalette::Background, Qt::white); //todo: choose the correct color + setPalette(p); + setFrameStyle(QFrame::Panel); + setLayoutDirection(Qt::LeftToRight); + QVBoxLayout *layout = new QVBoxLayout; + layout->setMargin(0); + setLayout(layout); + +} + + +void CompletionWidget::insertSearchList(const UrlSearchList &list) +{ + _list = list; + int min = MAX_ELEMENTS; + if(list.count() < min) + min = list.count(); + + for(int i = 0; isetObjectName( QString::number(i) ); + layout()->addWidget( suggestion ); + } +} + + +void CompletionWidget::sizeAndPosition() +{ + // size + setFixedHeight(layout()->count() * 44 ); + setFixedWidth( _parent->width() ); + + // position + QPoint p = _parent->mapToGlobal( QPoint(0,0) ); + move(p.x(), p.y() + _parent->height()); +} + + +void CompletionWidget::popup() +{ + down(); + sizeAndPosition(); + if (!isVisible()) + show(); +} + + +void CompletionWidget::up() +{ + // deactivate previous + if(_currentIndex != -1) + { + ListItem *widget = findChild( QString::number(_currentIndex) ); + widget->deactivate(); + } + + if(_currentIndex > 0) + _currentIndex--; + else + _currentIndex=layout()->count()-1; + + // activate "new" current + ListItem *widget = findChild( QString::number(_currentIndex) ); + widget->activate(); +} + +KUrl CompletionWidget::currentUrl() +{ + return _list.at(_currentIndex).url; +} + +void CompletionWidget::down() +{ + // deactivate previous + if(_currentIndex != -1) + { + ListItem *widget = findChild( QString::number(_currentIndex) ); + widget->deactivate(); + } + + if(_currentIndex < _list.count() -1) + _currentIndex++; + else + _currentIndex=0; + + // activate "new" current + ListItem *widget = findChild( QString::number(_currentIndex) ); + widget->activate(); +} + +void CompletionWidget::clear() +{ + QLayoutItem *child; + while ((child = layout()->takeAt(0)) != 0) + { + delete child->widget(); + delete child; + } + _currentIndex = -1; +} + + +bool CompletionWidget::eventFilter( QObject *o, QEvent *e ) +{ + int type = e->type(); + QWidget *wid = qobject_cast(o); + + if (o == this) + { + return false; + } + + //hide conditions of the CompletionWidget + if (wid + && ((wid == _parent && (type == QEvent::Move || type == QEvent::Resize)) + || ((wid->windowFlags() & Qt::Window) + && (type == QEvent::Move || type == QEvent::Hide || type == QEvent::WindowDeactivate) + && wid == _parent->window()) + || (type == QEvent::MouseButtonPress && !isAncestorOf(wid))) + ) + { + hide(); + return false; + } + + //actions on the CompletionWidget + if (wid && wid->isAncestorOf(_parent) && isVisible()) + { + if ( type == QEvent::KeyPress ) + { + QKeyEvent *ev = static_cast( e ); + switch ( ev->key() ) + { + case Qt::Key_Up: + case Qt::Key_Backtab: + if (ev->modifiers() == Qt::NoButton || (ev->modifiers() & Qt::ShiftModifier)) + { + up(); + ev->accept(); + return true; + } + break; + + case Qt::Key_Down: + case Qt::Key_Tab: + if (ev->modifiers() == Qt::NoButton) + { + down(); + ev->accept(); + return true; + } + break; + + case Qt::Key_Return: + hide(); + emit chosenUrl(currentUrl().url()); + ev->accept(); + return true; + break; + } + } + } + + return QFrame::eventFilter(o,e); +} + + +void CompletionWidget::setVisible( bool visible ) +{ + if (visible) + { + Application::instance()->installEventFilter(this); + } + else + { + Application::instance()->removeEventFilter(this); + } + + QFrame::setVisible(visible); +} + + +void CompletionWidget::itemChosen(ListItem *item) +{ + emit chosenUrl(_list.at(layout()->indexOf(item)).url); + hide(); +} \ No newline at end of file diff --git a/src/urlbar/completionwidget.h b/src/urlbar/completionwidget.h new file mode 100644 index 00000000..7b474bd8 --- /dev/null +++ b/src/urlbar/completionwidget.h @@ -0,0 +1,77 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Andrea Diamantini +* +* +* 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 . +* +* ============================================================ */ + + +#ifndef COMPLETION_WIDGET_H +#define COMPLETION_WIDGET_H + + +// Local Includes +#include "urlresolver.h" +#include "listitem.h" + +// Qt Includes +#include + +// KDE Includes +#include + +// Forward Declarations +class KUrl; + + +class CompletionWidget : public QFrame +{ +Q_OBJECT + +public: + CompletionWidget(QWidget *parent); + + void insertSearchList(const UrlSearchList &list); + void popup(); + + void up(); + void down(); + void clear(); + virtual bool eventFilter(QObject *obj, QEvent *ev); + void setVisible(bool visible); + KUrl currentUrl(); + +private slots: + void itemChosen(ListItem *item); + +signals: + void chosenUrl(const QString&); + +private: + void sizeAndPosition(); + + QWidget *_parent; + + UrlSearchList _list; + int _currentIndex; +}; + +#endif // COMPLETION_WIDGET_H diff --git a/src/urlbar/lineedit.cpp b/src/urlbar/lineedit.cpp index db36bd0c..f3c93e8e 100644 --- a/src/urlbar/lineedit.cpp +++ b/src/urlbar/lineedit.cpp @@ -2,9 +2,9 @@ * * This file is a part of the rekonq project * -* Copyright (C) 2009-2010 by Andrea Diamantini +* Copyright (C) 2009 by Andrea Diamantini * Copyright (C) 2009 by Paweł Prażak -* Copyright (C) 2009-2010 by Lionel Chauvin +* Copyright (C) 2009 by Lionel Chauvin * * * This program is free software; you can redistribute it and/or diff --git a/src/urlbar/lineedit.h b/src/urlbar/lineedit.h index 1ac3af2e..d76a5fcb 100644 --- a/src/urlbar/lineedit.h +++ b/src/urlbar/lineedit.h @@ -2,9 +2,9 @@ * * This file is a part of the rekonq project * -* Copyright (C) 2009-2010 by Andrea Diamantini +* Copyright (C) 2009 by Andrea Diamantini * Copyright (C) 2009 by Paweł Prażak -* Copyright (C) 2009-2010 by Lionel Chauvin +* Copyright (C) 2009 by Lionel Chauvin * * * This program is free software; you can redistribute it and/or @@ -30,9 +30,6 @@ #define LINEEDIT_H -// Local Includes -#include "rekonqprivate_export.h" - // KDE Includes #include @@ -42,7 +39,7 @@ class QFocusEvent; class QKeyEvent; -class REKONQ_TESTS_EXPORT LineEdit : public KLineEdit +class LineEdit : public KLineEdit { Q_OBJECT @@ -50,9 +47,12 @@ public: explicit LineEdit(QWidget *parent = 0); virtual ~LineEdit(); + protected: virtual void keyPressEvent(QKeyEvent*); virtual void mouseDoubleClickEvent(QMouseEvent *); + + }; #endif // LINEEDIT_H diff --git a/src/urlbar/listitem.cpp b/src/urlbar/listitem.cpp new file mode 100644 index 00000000..92951cb7 --- /dev/null +++ b/src/urlbar/listitem.cpp @@ -0,0 +1,173 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Andrea Diamantini +* +* +* 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 . +* +* ============================================================ */ + + +// Self Includes +#include "listitem.h" + +// Local Includes +#include "urlresolver.h" +#include "application.h" + +// KDE Includes +#include +#include +#include + +// Qt Includes +#include +#include +#include +#include +#include +#include +#include + +ListItem::ListItem(const UrlSearchItem &item, QWidget *parent) + : QWidget(parent), + m_option() +{ + QHBoxLayout *hLayout = new QHBoxLayout; + QVBoxLayout *vLayout = new QVBoxLayout; + + QLabel *previewLabel = new QLabel; + previewLabel->setFixedSize(40,30); + QPixmap preview; + QString path = KStandardDirs::locateLocal("cache", QString("thumbs/") + guessNameFromUrl(item.url) + ".png", true); + if(QFile::exists(path)) + { + preview.load(path); + previewLabel->setPixmap(preview.scaled(40,30)); + } + else + { + if(item.icon.startsWith( QLatin1String("http://") ) ) + preview = Application::icon( item.icon ).pixmap(22); + } + previewLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); + + hLayout->addWidget(previewLabel); + hLayout->addLayout(vLayout); + + QLabel *titleLabel = new QLabel("" + item.title + ""); + titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + QLabel *urlLabel = new QLabel("" + item.url + ""); + urlLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + vLayout->addWidget(titleLabel); + vLayout->addWidget(urlLabel); + + + QLabel *iconLabel = new QLabel; + QPixmap pixmap; + if(item.icon.startsWith( QLatin1String("http://") ) ) + pixmap = Application::icon( item.icon ).pixmap(18); + else + pixmap = KIcon(item.icon).pixmap(18); + + iconLabel->setPixmap(pixmap); + iconLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); + hLayout->addWidget(iconLabel); + + setLayout(hLayout); + + m_option.initFrom(this); + m_option.direction = Qt::LeftToRight; + + deactivate(); +} + +ListItem::~ListItem() +{ + disconnect(); +} + + +//TODO: REMOVE DUPLICATE CODE WITH PREVIEWIMAGE +QString ListItem::guessNameFromUrl(QUrl url) +{ + QString name = url.toString( QUrl::RemoveScheme | QUrl::RemoveUserInfo | QUrl::StripTrailingSlash ); + + // TODO learn Regular Expressions :) + // and implement something better here.. + name.remove('/'); + name.remove('&'); + name.remove('.'); + name.remove('-'); + name.remove('_'); + name.remove('?'); + name.remove('='); + name.remove('+'); + + return name; +} + + +void ListItem::activate() +{ + m_option.state |= QStyle::State_Selected; + repaint(); +} + + +void ListItem::deactivate() +{ + m_option.state &= ~QStyle::State_Selected; + repaint(); +} + +void ListItem::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + if( m_option.state.testFlag(QStyle::State_Selected) || m_option.state.testFlag(QStyle::State_MouseOver)) + { + QPainter painter(this); + m_option.rect=QRect(QPoint(),size()); + style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &m_option, &painter, this); + } +} + +void ListItem::enterEvent(QEvent *e) +{ + m_option.state |= QStyle::State_MouseOver; + repaint(); + QWidget::enterEvent(e); +} + +void ListItem::leaveEvent(QEvent *e) +{ + m_option.state &= ~QStyle::State_MouseOver; + repaint(); + QWidget::enterEvent(e); +} + +void ListItem::mousePressEvent(QMouseEvent *e) +{ + emit itemClicked(this); + QWidget::mousePressEvent(e); +} + diff --git a/src/urlbar/listitem.h b/src/urlbar/listitem.h new file mode 100644 index 00000000..6aa3f1e9 --- /dev/null +++ b/src/urlbar/listitem.h @@ -0,0 +1,59 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Andrea Diamantini +* +* +* 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 . +* +* ============================================================ */ + + +// Qt Includes +#include +#include + +// Forward Declarations +class UrlSearchItem; + + +class ListItem : public QWidget +{ +Q_OBJECT + +public: + ListItem(const UrlSearchItem &item, QWidget *parent = 0); + ~ListItem(); + + void activate(); + void deactivate(); + +signals: + void itemClicked(ListItem *item); + +protected: + virtual void paintEvent(QPaintEvent *event); + virtual void enterEvent(QEvent *); + virtual void leaveEvent(QEvent *); + virtual void mousePressEvent(QMouseEvent *e); + +private: + QStyleOptionViewItemV4 m_option; + QString guessNameFromUrl(QUrl url); + +}; diff --git a/src/urlbar/urlbar.cpp b/src/urlbar/urlbar.cpp index 189d19fe..54a0a02d 100644 --- a/src/urlbar/urlbar.cpp +++ b/src/urlbar/urlbar.cpp @@ -2,10 +2,10 @@ * * This file is a part of the rekonq project * -* Copyright (C) 2008-2010 by Andrea Diamantini +* Copyright (C) 2008-2009 by Andrea Diamantini * Copyright (C) 2009 by Domrachev Alexandr * Copyright (C) 2009 by Paweł Prażak -* Copyright (C) 2009-2010 by Lionel Chauvin +* Copyright (C) 2009 by Lionel Chauvin * * * This program is free software; you can redistribute it and/or @@ -36,8 +36,7 @@ #include "lineedit.h" #include "mainwindow.h" #include "webview.h" -#include "historymanager.h" -#include "webtab.h" +#include "urlresolver.h" // KDE Includes #include @@ -49,43 +48,44 @@ #include #include #include - +#include QColor UrlBar::s_defaultBaseColor; UrlBar::UrlBar(QWidget *parent) - : KHistoryComboBox(true, parent) - , m_lineEdit(new LineEdit) - , m_progress(0) + : KComboBox(true, parent) + , m_lineEdit(new LineEdit) + , m_progress(0) + , m_box(new CompletionWidget(this)) { - setUrlDropsEnabled(true); - setAutoDeleteCompletionObject(true); - //cosmetic setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); setMinimumWidth(180); - - setTrapReturnKey(true); - - setupLineEdit(); - // add every item to history - connect(this, SIGNAL(returnPressed(const QString&)), SLOT(activated(const QString&))); - connect(completionBox(), SIGNAL(activated(const QString&)), SLOT(activated(const QString&))); + // signal handlings + setTrapReturnKey(true); + setUrlDropsEnabled(true); + + // Make m_lineEdit background transparent + QPalette p = m_lineEdit->palette(); + p.setColor(QPalette::Base, Qt::transparent); + m_lineEdit->setPalette(p); - connect(this, SIGNAL(cleared()), SLOT(cleared())); + if (!s_defaultBaseColor.isValid()) + { + s_defaultBaseColor = palette().color(QPalette::Base); + } - // setup completion box - setCompletionObject( Application::historyManager()->completionObject() ); - - // set dropdown list background - QPalette p = view()->palette(); - p.setColor(QPalette::Base, palette().color(QPalette::Base)); - view()->setPalette(p); + setLineEdit(m_lineEdit); + // clear the URL bar + m_lineEdit->clear(); // load urls on activated urlbar signal - connect(this, SIGNAL(activated(const KUrl&)), Application::instance(), SLOT(loadUrl(const KUrl&))); + connect(this, SIGNAL(returnPressed(const QString&)), SLOT(activated(const QString&))); + + installEventFilter(m_box); + connect(m_box, SIGNAL(chosenUrl(const QString&)), SLOT(activated(const QString&))); } @@ -96,7 +96,7 @@ UrlBar::~UrlBar() void UrlBar::selectAll() const { - lineEdit()->selectAll(); + m_lineEdit->selectAll(); } @@ -106,42 +106,12 @@ KUrl UrlBar::url() const } -KLineEdit *UrlBar::lineEdit() const -{ - return m_lineEdit; -} - - -void UrlBar::setupLineEdit() -{ - // Make m_lineEdit background transparent - QPalette p = m_lineEdit->palette(); - p.setColor(QPalette::Base, Qt::transparent); - m_lineEdit->setPalette(p); - - if (!s_defaultBaseColor.isValid()) - { - s_defaultBaseColor = palette().color(QPalette::Base); - } - - setLineEdit(m_lineEdit); - - // Make the lineedit consume the Qt::Key_Enter event... - lineEdit()->setTrapReturnKey(true); - - lineEdit()->setHandleSignals(true); - - // clear the URL bar - lineEdit()->clear(); -} - - void UrlBar::setUrl(const QUrl& url) { if(url.scheme() == "about") { m_currentUrl = KUrl(); - updateUrl(); // updateUrl before setFocus + updateUrl(); setFocus(); } else @@ -149,6 +119,7 @@ void UrlBar::setUrl(const QUrl& url) m_currentUrl = KUrl(url); updateUrl(); } + } @@ -195,29 +166,21 @@ void UrlBar::updateUrl() // Must be AFTER setCurrentIndex if (!hasFocus()) { - lineEdit()->setCursorPosition(0); + m_lineEdit->setCursorPosition(0); } } void UrlBar::activated(const QString& urlString) { + disconnect(this, SIGNAL(editTextChanged(const QString &)), this, SLOT(suggestUrls(const QString &))); + if (urlString.isEmpty()) return; - // this fix urlbar behaviour, removing focus from there and enabling - // loading animation. Temporary fix?? - Application::instance()->mainWindow()->currentTab()->setFocus(); - - setUrl( KUrl(urlString) ); - emit activated( KUrl(urlString) ); -} - - -void UrlBar::cleared() -{ - // clear the history on user's request from context menu - clear(); + clearFocus(); + setUrl(urlString); + Application::instance()->loadUrl(m_currentUrl); } @@ -243,7 +206,7 @@ void UrlBar::paintEvent(QPaintEvent *event) p.setColor(QPalette::Base, s_defaultBaseColor); setPalette(p); - KHistoryComboBox::paintEvent(event); + KComboBox::paintEvent(event); if (!hasFocus()) { @@ -261,7 +224,7 @@ void UrlBar::paintEvent(QPaintEvent *event) painter.setBrush(generateGradient(loadingColor, height())); painter.setPen(Qt::transparent); - QRect backgroundRect = lineEdit()->frameGeometry(); + QRect backgroundRect = m_lineEdit->frameGeometry(); int mid = backgroundRect.width() * m_progress / 100; QRect progressRect(backgroundRect.x(), backgroundRect.y(), mid, backgroundRect.height()); painter.drawRect(progressRect); @@ -272,7 +235,7 @@ void UrlBar::paintEvent(QPaintEvent *event) QSize UrlBar::sizeHint() const { - return lineEdit()->sizeHint(); + return m_lineEdit->sizeHint(); } @@ -308,43 +271,70 @@ bool UrlBar::isLoading() return true; } - void UrlBar::keyPressEvent(QKeyEvent *event) { + + // this handles the Modifiers + Return key combinations QString currentText = m_lineEdit->text().trimmed(); - if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) + if ((event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) + && !currentText.startsWith(QLatin1String("http://"), Qt::CaseInsensitive)) { - if( !currentText.startsWith(QLatin1String("http://"), Qt::CaseInsensitive) ) + QString append; + if (event->modifiers() == Qt::ControlModifier) { - QString append; - if (event->modifiers() == Qt::ControlModifier) - { - append = QLatin1String(".com"); - } - else if (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) - { - append = QLatin1String(".org"); - } - else if (event->modifiers() == Qt::ShiftModifier) - { - append = QLatin1String(".net"); - } - - QUrl url(QLatin1String("http://www.") + currentText); - QString host = url.host(); - if (!host.endsWith(append, Qt::CaseInsensitive)) - { - host += append; - url.setHost(host); - m_lineEdit->setText(url.toString()); - } + append = QLatin1String(".com"); } - else + else if (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) + { + append = QLatin1String(".org"); + } + else if (event->modifiers() == Qt::ShiftModifier) + { + append = QLatin1String(".net"); + } + + QUrl url(QLatin1String("http://www.") + currentText); + QString host = url.host(); + if (!host.endsWith(append, Qt::CaseInsensitive)) { - // fill lineEdit with its stripped contents to remove trailing spaces - m_lineEdit->setText(currentText); + host += append; + url.setHost(host); + m_lineEdit->setText(url.toString()); } } + + KComboBox::keyPressEvent(event); +} + + +void UrlBar::suggestUrls(const QString &text) +{ + if (!hasFocus()) + { + return; + } + + if(text.isEmpty()) + { + m_box->hide(); + return; + } + + UrlResolver res(text); + UrlSearchList list = res.orderedSearchItems(); + + if(list.count() > 0) + { + m_box->clear(); + m_box->insertSearchList(list); + m_box->popup(); + } +} - KHistoryComboBox::keyPressEvent(event); +void UrlBar::focusInEvent(QFocusEvent *event) +{ + // activate suggestions on edit text + connect(this, SIGNAL(editTextChanged(const QString &)), this, SLOT(suggestUrls(const QString &))); + + KComboBox::focusInEvent(event); } diff --git a/src/urlbar/urlbar.h b/src/urlbar/urlbar.h index 39911bb2..ef53d63a 100644 --- a/src/urlbar/urlbar.h +++ b/src/urlbar/urlbar.h @@ -2,10 +2,10 @@ * * This file is a part of the rekonq project * -* Copyright (C) 2008-2010 by Andrea Diamantini +* Copyright (C) 2008-2009 by Andrea Diamantini * Copyright (C) 2009 by Domrachev Alexandr * Copyright (C) 2009 by Paweł Prażak -* Copyright (C) 2009-2010 by Lionel Chauvin +* Copyright (C) 2009 by Lionel Chauvin * * * This program is free software; you can redistribute it and/or @@ -32,23 +32,23 @@ // Local Includes -#include "rekonqprivate_export.h" #include "lineedit.h" +#include "completionwidget.h" // KDE Includes #include -#include +#include // Qt Includes #include +#include // Forward Declarations class QLinearGradient; class QWidget; -class KCompletion; -class REKONQ_TESTS_EXPORT UrlBar : public KHistoryComboBox +class UrlBar : public KComboBox { Q_OBJECT @@ -61,31 +61,24 @@ public: QSize sizeHint() const; void setBackgroundColor(QColor); bool isLoading(); - void setProgress(int progress); -signals: - void activated(const KUrl&); - public slots: void setUrl(const QUrl &url); void updateProgress(int progress); void updateUrl(); - + private slots: void activated(const QString& url); void loadFinished(bool); - void cleared(); + void suggestUrls(const QString &editedText); protected: virtual void paintEvent(QPaintEvent *event); virtual void keyPressEvent(QKeyEvent *event); + virtual void focusInEvent(QFocusEvent *event); private: - void setupLineEdit(); - - KLineEdit *lineEdit() const; - static QLinearGradient generateGradient(const QColor &color, int height); static QColor s_defaultBaseColor; @@ -94,6 +87,9 @@ private: KUrl m_currentUrl; int m_progress; + + CompletionWidget *m_box; + KUrl m_suggestedUrl; }; #endif diff --git a/src/urlbar/urlresolver.cpp b/src/urlbar/urlresolver.cpp new file mode 100644 index 00000000..b2bf50af --- /dev/null +++ b/src/urlbar/urlresolver.cpp @@ -0,0 +1,177 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Andrea Diamantini +* +* +* 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 . +* +* ============================================================ */ + + +// Self Includes +#include "urlresolver.h" + +// Local Includes +#include "application.h" +#include "historymanager.h" +#include "bookmarksmanager.h" + +// KDE Includes +#include +#include +#include +#include +#include +#include + +// Qt Includes +#include +#include +#include + + +// NOTE default kurifilter plugin list (at least in my box) +// 1. "kshorturifilter" +// 2. "kurisearchfilter" +// 3. "localdomainurifilter" +// 4 ."kuriikwsfilter" +// 5. "fixhosturifilter" + + +UrlResolver::UrlResolver(const QString &typedUrl) + : _urlString(typedUrl) +{ +} + + +UrlSearchList UrlResolver::orderedSearchItems() +{ + // NOTE: the logic here is : "we wanna suggest (at least) 9 elements" + // so we have (more or less) 3 from first results (1 from QUrl Resolutions, 2 from + // default search engines). + // There are 6 remaining: if bookmarkResults + historyResults <= 6, catch all, else + // catch first 3 results from the two resulting lists :) + + UrlSearchList list; + + list << qurlFromUserInputResolution(); + list << webSearchesResolution(); + int firstResults = list.count(); + int checkPoint = 9 - firstResults; + + UrlSearchList historyList = historyResolution(); + int historyResults = historyList.count(); + + UrlSearchList bookmarksList = bookmarksResolution(); + int bookmarkResults = bookmarksList.count(); + + if(historyResults + bookmarkResults > checkPoint) + { + historyList = historyList.mid(0,3); + bookmarksList = bookmarksList.mid(0,3); + } + list << historyList; + list << bookmarksList; + + return list; +} + + +////////////////////////////////////////////////////////////////////////// +// PRIVATE ENGINES + + +// STEP 1 = QUrl from User Input (easily the best solution... ) +UrlSearchList UrlResolver::qurlFromUserInputResolution() +{ + UrlSearchList list; + + QString url2 = _urlString; + QUrl urlFromUserInput = QUrl::fromUserInput(url2); + if(urlFromUserInput.isValid()) + { + QByteArray ba = urlFromUserInput.toEncoded(); + if(!ba.isEmpty()) + { + QString str(ba); + UrlSearchItem it(str); + list << it; + } + } + + return list; +} + + +// STEP 2 = Web Searches +UrlSearchList UrlResolver::webSearchesResolution() +{ + UrlSearchList list; + + QString url1 = _urlString; + if(KUrl(url1).isRelative() && !url1.contains('.')) + { + // KUriFilter has the worst performance possible here and let this trick unusable + QString gUrl = QString("http://www.google.com/search?q=%1&ie=UTF-8&oe=UTF-8").arg(url1); + QString gTitle = i18n("Search Google for ") + url1; + UrlSearchItem gItem(gUrl, gTitle, QString("http://www.google.com") ); + list << gItem; + + QString wUrl = QString("http://en.wikipedia.org/wiki/Special:Search?search=%1&go=Go").arg(url1); + QString wTitle = i18n("Search Wikipedia for ") + url1; + UrlSearchItem wItem(wUrl, wTitle, QString("http://wikipedia.org") ); + list << wItem; + } + + return list; +} + + +// STEP 3 = history completion +UrlSearchList UrlResolver::historyResolution() +{ + UrlSearchList list; + + KCompletion *historyCompletion = Application::historyManager()->completionObject(); + QStringList historyResults = historyCompletion->substringCompletion(_urlString); + Q_FOREACH(const QString &s, historyResults) + { + UrlSearchItem it(s, s, QString("view-history")); + list << it; + } + + return list; +} + + +// STEP 4 = bookmarks completion +UrlSearchList UrlResolver::bookmarksResolution() +{ + UrlSearchList list; + + KCompletion *bookmarkCompletion = Application::bookmarkProvider()->completionObject(); + QStringList bookmarkResults = bookmarkCompletion->substringCompletion(_urlString); + Q_FOREACH(const QString &s, bookmarkResults) + { + UrlSearchItem it( s, QString(), QString("rating") ); + list << it; + } + + return list; +} diff --git a/src/urlbar/urlresolver.h b/src/urlbar/urlresolver.h new file mode 100644 index 00000000..0a880150 --- /dev/null +++ b/src/urlbar/urlresolver.h @@ -0,0 +1,72 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Andrea Diamantini +* +* +* 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 . +* +* ============================================================ */ + + +#ifndef URL_RESOLVER_H +#define URL_RESOLVER_H + + +// Qt Includes +#include +#include + +// Forward Declarations +class KUrl; + +class UrlSearchItem +{ +public: + QString url; + QString title; + QString icon; + + UrlSearchItem(const QString &_url, const QString &_title = QString(), const QString &_icon = QString()) + : url(_url), title(_title), icon(_icon) + {}; +}; + +typedef QList UrlSearchList; + + +// ---------------------------------------------------------------------- + + +class UrlResolver +{ +public: + UrlResolver(const QString &typedUrl); + + UrlSearchList orderedSearchItems(); + +private: + QString _urlString; + + UrlSearchList webSearchesResolution(); + UrlSearchList historyResolution(); + UrlSearchList qurlFromUserInputResolution(); + UrlSearchList bookmarksResolution(); +}; + +#endif // URL_RESOLVER_H -- cgit v1.2.1 From f06dd6129cc716dd34381ae7633e52f35a267d05 Mon Sep 17 00:00:00 2001 From: Andrea Diamantini Date: Mon, 29 Mar 2010 11:57:08 +0200 Subject: rekonq 0.4.57 The AWESOME bar!! (not ready yet, but enough awesome to merge..) Thanks Jonas Gastal (initial work on it) and Lionel Chauvin (he let things really work and improve them, too) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 51393fc8..5fa7cf4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ PROJECT( rekonq ) # Informations to update before to release this package. # rekonq info -SET(REKONQ_VERSION "0.4.56" ) +SET(REKONQ_VERSION "0.4.57" ) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/version.h ) -- cgit v1.2.1