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(-) (limited to 'src') 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 (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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 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(-) (limited to 'src') 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 (limited to 'src') 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