From 03713b0ab408a42a20c9ce6a51d069b3246d2502 Mon Sep 17 00:00:00 2001 From: Kevin Ottens Date: Mon, 2 Apr 2007 19:20:07 +0000 Subject: Rename all the URL navigator related classes to prepare their migration in kdelibs. svn path=/trunk/KDE/kdebase/apps/; revision=649514 --- src/CMakeLists.txt | 10 +- src/bookmarkselector.cpp | 188 ---------- src/bookmarkselector.h | 98 ------ src/dolphinmainwindow.cpp | 4 +- src/dolphinview.cpp | 4 +- src/dolphinview.h | 26 +- src/kfileplacesselector.cpp | 189 ++++++++++ src/kfileplacesselector_p.h | 99 ++++++ src/kprotocolcombo.cpp | 118 +++++++ src/kprotocolcombo_p.h | 49 +++ src/kurlbutton.cpp | 81 +++++ src/kurlbutton_p.h | 67 ++++ src/kurlnavigator.cpp | 823 ++++++++++++++++++++++++++++++++++++++++++++ src/kurlnavigator.h | 222 ++++++++++++ src/kurlnavigatorbutton.cpp | 361 +++++++++++++++++++ src/kurlnavigatorbutton_p.h | 86 +++++ src/protocolcombo.cpp | 118 ------- src/protocolcombo.h | 49 --- src/urlbutton.cpp | 80 ----- src/urlbutton.h | 67 ---- src/urlnavigator.cpp | 822 ------------------------------------------- src/urlnavigator.h | 221 ------------ src/urlnavigatorbutton.cpp | 361 ------------------- src/urlnavigatorbutton.h | 86 ----- 24 files changed, 2117 insertions(+), 2112 deletions(-) delete mode 100644 src/bookmarkselector.cpp delete mode 100644 src/bookmarkselector.h create mode 100644 src/kfileplacesselector.cpp create mode 100644 src/kfileplacesselector_p.h create mode 100644 src/kprotocolcombo.cpp create mode 100644 src/kprotocolcombo_p.h create mode 100644 src/kurlbutton.cpp create mode 100644 src/kurlbutton_p.h create mode 100644 src/kurlnavigator.cpp create mode 100644 src/kurlnavigator.h create mode 100644 src/kurlnavigatorbutton.cpp create mode 100644 src/kurlnavigatorbutton_p.h delete mode 100644 src/protocolcombo.cpp delete mode 100644 src/protocolcombo.h delete mode 100644 src/urlbutton.cpp delete mode 100644 src/urlbutton.h delete mode 100644 src/urlnavigator.cpp delete mode 100644 src/urlnavigator.h delete mode 100644 src/urlnavigatorbutton.cpp delete mode 100644 src/urlnavigatorbutton.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 15fc3e5b5..988572925 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -40,7 +40,7 @@ set(dolphin_SRCS kfileplacesmodel.cpp kfileplacesitem.cpp kfileplacesview.cpp - bookmarkselector.cpp + kfileplacesselector.cpp bookmarkssettingspage.cpp bookmarkssidebarpage.cpp columnviewsettingspage.cpp @@ -63,7 +63,7 @@ set(dolphin_SRCS infosidebarpage.cpp main.cpp metadatawidget.cpp - protocolcombo.cpp + kprotocolcombo.cpp pixmapviewer.cpp renamedialog.cpp settingspagebase.cpp @@ -73,9 +73,9 @@ set(dolphin_SRCS treeviewcontextmenu.cpp treeviewsidebarpage.cpp sidebartreeview.cpp - urlbutton.cpp - urlnavigator.cpp - urlnavigatorbutton.cpp + kurlbutton.cpp + kurlnavigator.cpp + kurlnavigatorbutton.cpp viewpropertiesdialog.cpp viewsettingspage.cpp viewpropsprogressinfo.cpp ) diff --git a/src/bookmarkselector.cpp b/src/bookmarkselector.cpp deleted file mode 100644 index 10ce0f2b3..000000000 --- a/src/bookmarkselector.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * - * * - * 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) any later version. * - * * - * 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, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - -#include "bookmarkselector.h" - -#include "urlnavigator.h" - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -BookmarkSelector::BookmarkSelector(UrlNavigator* parent, KFilePlacesModel* placesModel) : - UrlButton(parent), - m_selectedItem(-1), - m_urlNavigator(parent), - m_placesModel(placesModel) -{ - setFocusPolicy(Qt::NoFocus); - - m_placesMenu = new KMenu(this); - - updateMenu(); - - connect(m_placesModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), - this, SLOT(updateMenu())); - connect(m_placesModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), - this, SLOT(updateMenu())); - connect(m_placesMenu, SIGNAL(triggered(QAction*)), - this, SLOT(activatePlace(QAction*))); - - setMenu(m_placesMenu); -} - -BookmarkSelector::~BookmarkSelector() -{ -} - -void BookmarkSelector::updateMenu() -{ - m_placesMenu->clear(); - - for (int i=0; irowCount(); ++i) { - QModelIndex index = m_placesModel->index(i, 0); - QAction* action = new QAction(m_placesModel->icon(index), - m_placesModel->text(index), - m_placesMenu); - m_placesMenu->addAction(action); - - action->setData(i); - - if (i == m_selectedItem) { - //QPixmap pixmap = SmallIcon(bookmark.icon()); - setIcon(m_placesModel->icon(index)); - //setIconSize(pixmap.size()); - //setMinimumWidth(pixmap.width() + 2); - } - } -} - -void BookmarkSelector::updateSelection(const KUrl& url) -{ - QModelIndex index = m_placesModel->closestItem(url); - - if (index.isValid()) { - m_selectedItem = index.row(); - setIcon(m_placesModel->icon(index)); - } - else { - m_selectedItem = -1; - // No bookmark has been found which matches to the given Url. Show - // a generic folder icon as pixmap for indication: - setIcon(KIcon("folder")); - } -} - -KUrl BookmarkSelector::selectedPlaceUrl() const -{ - QModelIndex index = m_placesModel->index(m_selectedItem, 0); - - if (index.isValid()) - return m_placesModel->url(index); - else - return KUrl(); -} - -QString BookmarkSelector::selectedPlaceText() const -{ - QModelIndex index = m_placesModel->index(m_selectedItem, 0); - - if (index.isValid()) - return m_placesModel->text(index); - else - return QString(); -} - -QSize BookmarkSelector::sizeHint() const -{ - const int height = UrlButton::sizeHint().height(); - return QSize(height, height); -} - -void BookmarkSelector::paintEvent(QPaintEvent* /*event*/) -{ - QPainter painter(this); - - const int buttonWidth = width(); - const int buttonHeight = height(); - - QColor backgroundColor; - QColor foregroundColor; - const bool isHighlighted = isDisplayHintEnabled(EnteredHint) || - isDisplayHintEnabled(DraggedHint); - if (isHighlighted) { - backgroundColor = KGlobalSettings::highlightColor(); - foregroundColor = KGlobalSettings::highlightedTextColor(); - } - else { - backgroundColor = palette().brush(QPalette::Background).color(); - foregroundColor = KGlobalSettings::buttonTextColor(); - } - - // dimm the colors if the parent view does not have the focus - const bool isActive = m_urlNavigator->isActive(); - if (!isActive) { - QColor dimmColor(palette().brush(QPalette::Background).color()); - foregroundColor = mixColors(foregroundColor, dimmColor); - if (isHighlighted) { - backgroundColor = mixColors(backgroundColor, dimmColor); - } - } - - if (!(isDisplayHintEnabled(ActivatedHint) && isActive) && !isHighlighted) { - // dimm the foreground color by mixing it with the background - foregroundColor = mixColors(foregroundColor, backgroundColor); - painter.setPen(foregroundColor); - } - - // draw button backround - painter.setPen(Qt::NoPen); - painter.setBrush(backgroundColor); - painter.drawRect(0, 0, buttonWidth, buttonHeight); - - // draw icon - const QPixmap pixmap = icon().pixmap(); - const int x = (buttonWidth - pixmap.width()) / 2; - const int y = (buttonHeight - pixmap.height()) / 2; - painter.drawPixmap(x, y, pixmap); -} - -void BookmarkSelector::activatePlace(QAction* action) -{ - assert(action != 0); - m_selectedItem = action->data().toInt(); - - QModelIndex index = m_placesModel->index(m_selectedItem, 0); - - if (index.isValid()) { - setIcon(m_placesModel->icon(index)); - emit placeActivated(m_placesModel->url(index)); - } -} - -#include "bookmarkselector.moc" - diff --git a/src/bookmarkselector.h b/src/bookmarkselector.h deleted file mode 100644 index bedfcb233..000000000 --- a/src/bookmarkselector.h +++ /dev/null @@ -1,98 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * - * * - * 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) any later version. * - * * - * 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, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - -#ifndef BOOKMARKSELECTOR_H -#define BOOKMARKSELECTOR_H - -#include -#include - -class KFilePlacesModel; -class UrlNavigator; -class KMenu; - -/** - * @brief Allows to select a bookmark from a popup menu. - * - * The icon from the current selected bookmark is shown - * inside the bookmark selector. - * - * @see UrlNavigator - */ -class BookmarkSelector : public UrlButton -{ - Q_OBJECT - -public: - /** - * @param parent Parent widget where the bookmark selector - * is embedded into. - */ - BookmarkSelector(UrlNavigator* parent, KFilePlacesModel* placesModel); - - virtual ~BookmarkSelector(); - - /** - * Updates the selection dependent from the given URL \a url. The - * URL must not match exactly to one of the available bookmarks: - * The bookmark which is equal to the URL or at least is a parent URL - * is selected. If there are more than one possible parent URL candidates, - * the bookmark which covers the bigger range of the URL is selected. - */ - void updateSelection(const KUrl& url); - - /** Returns the selected bookmark. */ - KUrl selectedPlaceUrl() const; - /** Returns the selected bookmark. */ - QString selectedPlaceText() const; - - /** @see QWidget::sizeHint() */ - virtual QSize sizeHint() const; - -signals: - /** - * Is send when a bookmark has been activated by the user. - * @param url URL of the selected place. - */ - void placeActivated(const KUrl& url); - -protected: - /** - * Draws the icon of the selected Url as content of the Url - * selector. - */ - virtual void paintEvent(QPaintEvent* event); - -private slots: - /** - * Updates the selected index and the icon to the bookmark - * which is indicated by the triggered action \a action. - */ - void activatePlace(QAction* action); - - void updateMenu(); - -private: - int m_selectedItem; - UrlNavigator* m_urlNavigator; - KMenu* m_placesMenu; - KFilePlacesModel* m_placesModel; -}; - -#endif diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index d5f50c653..f77d45c72 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -32,7 +32,7 @@ #include "metadatawidget.h" #include "mainwindowadaptor.h" #include "treeviewsidebarpage.h" -#include "urlnavigator.h" +#include "kurlnavigator.h" #include "viewpropertiesdialog.h" #include "viewproperties.h" #include "kfileplacesmodel.h" @@ -1506,7 +1506,7 @@ void DolphinMainWindow::connectViewSignals(int viewIndex) connect(view, SIGNAL(urlChanged(KUrl)), this, SLOT(changeUrl(KUrl))); - const UrlNavigator* navigator = view->urlNavigator(); + const KUrlNavigator* navigator = view->urlNavigator(); connect(navigator, SIGNAL(urlChanged(const KUrl&)), this, SLOT(changeUrl(const KUrl&))); connect(navigator, SIGNAL(historyChanged()), diff --git a/src/dolphinview.cpp b/src/dolphinview.cpp index 402a673f0..1aa7e0ff8 100644 --- a/src/dolphinview.cpp +++ b/src/dolphinview.cpp @@ -53,7 +53,7 @@ #include "dolphincontextmenu.h" #include "filterbar.h" #include "renamedialog.h" -#include "urlnavigator.h" +#include "kurlnavigator.h" #include "viewproperties.h" #include "dolphinsettings.h" #include "dolphin_generalsettings.h" @@ -97,7 +97,7 @@ DolphinView::DolphinView(DolphinMainWindow* mainWindow, connect(clipboard, SIGNAL(dataChanged()), this, SLOT(updateCutItems())); - m_urlNavigator = new UrlNavigator(new KFilePlacesModel(this), url, this); + m_urlNavigator = new KUrlNavigator(new KFilePlacesModel(this), url, this); m_urlNavigator->setUrlEditable(DolphinSettings::instance().generalSettings()->editableUrl()); m_urlNavigator->setHomeUrl(DolphinSettings::instance().generalSettings()->homeUrl()); m_urlNavigator->setShowHiddenFiles(showHiddenFiles); diff --git a/src/dolphinview.h b/src/dolphinview.h index d9a241759..2118aaf56 100644 --- a/src/dolphinview.h +++ b/src/dolphinview.h @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include @@ -41,7 +41,7 @@ class FilterBar; class KFileItemDelegate; class KUrl; class KDirModel; -class UrlNavigator; +class KUrlNavigator; class DolphinColumnView; class DolphinDetailsView; class DolphinDirLister; @@ -64,7 +64,7 @@ class ViewProperties; * @see DolphinIconsView * @see DolphinDetailsView * @see DolphinColumnView - * @see UrlNavigator + * @see KUrlNavigator * @see DolphinStatusBar */ class DolphinView : public QWidget @@ -121,7 +121,7 @@ public: /** * Sets the current active URL. - * The signals UrlNavigator::urlChanged() and UrlNavigator::historyChanged() + * The signals KUrlNavigator::urlChanged() and KUrlNavigator::historyChanged() * are emitted. */ void setUrl(const KUrl& url); @@ -185,28 +185,28 @@ public: /** * Goes back one step in the URL history. The signals - * UrlNavigator::urlChanged() and UrlNavigator::historyChanged() + * KUrlNavigator::urlChanged() and KUrlNavigator::historyChanged() * are submitted. */ void goBack(); /** * Goes forward one step in the Url history. The signals - * UrlNavigator::urlChanged() and UrlNavigator::historyChanged() + * KUrlNavigator::urlChanged() and KUrlNavigator::historyChanged() * are submitted. */ void goForward(); /** * Goes up one step of the Url path. The signals - * UrlNavigator::urlChanged() and UrlNavigator::historyChanged() + * KUrlNavigator::urlChanged() and KUrlNavigator::historyChanged() * are submitted. */ void goUp(); /** - * Goes to the home URL. The signals UrlNavigator::urlChanged() - * and UrlNavigator::historyChanged() are submitted. + * Goes to the home URL. The signals KUrlNavigator::urlChanged() + * and KUrlNavigator::historyChanged() are submitted. */ void goHome(); @@ -266,7 +266,7 @@ public: /** * Returns true, if the URL shown by the navigation bar is editable. - * @see UrlNavigator + * @see KUrlNavigator */ bool isUrlEditable() const; @@ -306,8 +306,8 @@ public: /** Returns the additional information which should be shown for the items. */ KFileItemDelegate::AdditionalInformation additionalInfo() const; - /** Returns the UrlNavigator of the view for read access. */ - const UrlNavigator* urlNavigator() const { return m_urlNavigator; } + /** Returns the KUrlNavigator of the view for read access. */ + const KUrlNavigator* urlNavigator() const { return m_urlNavigator; } /** * Triggers to request user information for the item given @@ -572,7 +572,7 @@ private: DolphinMainWindow* m_mainWindow; QVBoxLayout* m_topLayout; - UrlNavigator* m_urlNavigator; + KUrlNavigator* m_urlNavigator; DolphinController* m_controller; DolphinIconsView* m_iconsView; diff --git a/src/kfileplacesselector.cpp b/src/kfileplacesselector.cpp new file mode 100644 index 000000000..0052c3a1e --- /dev/null +++ b/src/kfileplacesselector.cpp @@ -0,0 +1,189 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * + * Copyright (C) 2007 by Kevin Ottens (ervin@kde.org) * + * * + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include "kfileplacesselector_p.h" + +#include "kurlnavigator.h" + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +KFilePlacesSelector::KFilePlacesSelector(KUrlNavigator* parent, KFilePlacesModel* placesModel) : + KUrlButton(parent), + m_selectedItem(-1), + m_urlNavigator(parent), + m_placesModel(placesModel) +{ + setFocusPolicy(Qt::NoFocus); + + m_placesMenu = new KMenu(this); + + updateMenu(); + + connect(m_placesModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), + this, SLOT(updateMenu())); + connect(m_placesModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), + this, SLOT(updateMenu())); + connect(m_placesMenu, SIGNAL(triggered(QAction*)), + this, SLOT(activatePlace(QAction*))); + + setMenu(m_placesMenu); +} + +KFilePlacesSelector::~KFilePlacesSelector() +{ +} + +void KFilePlacesSelector::updateMenu() +{ + m_placesMenu->clear(); + + for (int i=0; irowCount(); ++i) { + QModelIndex index = m_placesModel->index(i, 0); + QAction* action = new QAction(m_placesModel->icon(index), + m_placesModel->text(index), + m_placesMenu); + m_placesMenu->addAction(action); + + action->setData(i); + + if (i == m_selectedItem) { + //QPixmap pixmap = SmallIcon(bookmark.icon()); + setIcon(m_placesModel->icon(index)); + //setIconSize(pixmap.size()); + //setMinimumWidth(pixmap.width() + 2); + } + } +} + +void KFilePlacesSelector::updateSelection(const KUrl& url) +{ + QModelIndex index = m_placesModel->closestItem(url); + + if (index.isValid()) { + m_selectedItem = index.row(); + setIcon(m_placesModel->icon(index)); + } + else { + m_selectedItem = -1; + // No bookmark has been found which matches to the given Url. Show + // a generic folder icon as pixmap for indication: + setIcon(KIcon("folder")); + } +} + +KUrl KFilePlacesSelector::selectedPlaceUrl() const +{ + QModelIndex index = m_placesModel->index(m_selectedItem, 0); + + if (index.isValid()) + return m_placesModel->url(index); + else + return KUrl(); +} + +QString KFilePlacesSelector::selectedPlaceText() const +{ + QModelIndex index = m_placesModel->index(m_selectedItem, 0); + + if (index.isValid()) + return m_placesModel->text(index); + else + return QString(); +} + +QSize KFilePlacesSelector::sizeHint() const +{ + const int height = KUrlButton::sizeHint().height(); + return QSize(height, height); +} + +void KFilePlacesSelector::paintEvent(QPaintEvent* /*event*/) +{ + QPainter painter(this); + + const int buttonWidth = width(); + const int buttonHeight = height(); + + QColor backgroundColor; + QColor foregroundColor; + const bool isHighlighted = isDisplayHintEnabled(EnteredHint) || + isDisplayHintEnabled(DraggedHint); + if (isHighlighted) { + backgroundColor = KGlobalSettings::highlightColor(); + foregroundColor = KGlobalSettings::highlightedTextColor(); + } + else { + backgroundColor = palette().brush(QPalette::Background).color(); + foregroundColor = KGlobalSettings::buttonTextColor(); + } + + // dimm the colors if the parent view does not have the focus + const bool isActive = m_urlNavigator->isActive(); + if (!isActive) { + QColor dimmColor(palette().brush(QPalette::Background).color()); + foregroundColor = mixColors(foregroundColor, dimmColor); + if (isHighlighted) { + backgroundColor = mixColors(backgroundColor, dimmColor); + } + } + + if (!(isDisplayHintEnabled(ActivatedHint) && isActive) && !isHighlighted) { + // dimm the foreground color by mixing it with the background + foregroundColor = mixColors(foregroundColor, backgroundColor); + painter.setPen(foregroundColor); + } + + // draw button backround + painter.setPen(Qt::NoPen); + painter.setBrush(backgroundColor); + painter.drawRect(0, 0, buttonWidth, buttonHeight); + + // draw icon + const QPixmap pixmap = icon().pixmap(); + const int x = (buttonWidth - pixmap.width()) / 2; + const int y = (buttonHeight - pixmap.height()) / 2; + painter.drawPixmap(x, y, pixmap); +} + +void KFilePlacesSelector::activatePlace(QAction* action) +{ + assert(action != 0); + m_selectedItem = action->data().toInt(); + + QModelIndex index = m_placesModel->index(m_selectedItem, 0); + + if (index.isValid()) { + setIcon(m_placesModel->icon(index)); + emit placeActivated(m_placesModel->url(index)); + } +} + +#include "kfileplacesselector_p.moc" + diff --git a/src/kfileplacesselector_p.h b/src/kfileplacesselector_p.h new file mode 100644 index 000000000..1efe9bb4e --- /dev/null +++ b/src/kfileplacesselector_p.h @@ -0,0 +1,99 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * + * Copyright (C) 2007 by Kevin Ottens (ervin@kde.org) * + * * + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef KFILEPLACESSELECTOR_P_H +#define KFILEPLACESSELECTOR_P_H + +#include "kurlbutton_p.h" +#include + +class KFilePlacesModel; +class KUrlNavigator; +class KMenu; + +/** + * @brief Allows to select a bookmark from a popup menu. + * + * The icon from the current selected bookmark is shown + * inside the bookmark selector. + * + * @see UrlNavigator + */ +class KFilePlacesSelector : public KUrlButton +{ + Q_OBJECT + +public: + /** + * @param parent Parent widget where the bookmark selector + * is embedded into. + */ + KFilePlacesSelector(KUrlNavigator* parent, KFilePlacesModel* placesModel); + + virtual ~KFilePlacesSelector(); + + /** + * Updates the selection dependent from the given URL \a url. The + * URL must not match exactly to one of the available bookmarks: + * The bookmark which is equal to the URL or at least is a parent URL + * is selected. If there are more than one possible parent URL candidates, + * the bookmark which covers the bigger range of the URL is selected. + */ + void updateSelection(const KUrl& url); + + /** Returns the selected bookmark. */ + KUrl selectedPlaceUrl() const; + /** Returns the selected bookmark. */ + QString selectedPlaceText() const; + + /** @see QWidget::sizeHint() */ + virtual QSize sizeHint() const; + +signals: + /** + * Is send when a bookmark has been activated by the user. + * @param url URL of the selected place. + */ + void placeActivated(const KUrl& url); + +protected: + /** + * Draws the icon of the selected Url as content of the Url + * selector. + */ + virtual void paintEvent(QPaintEvent* event); + +private slots: + /** + * Updates the selected index and the icon to the bookmark + * which is indicated by the triggered action \a action. + */ + void activatePlace(QAction* action); + + void updateMenu(); + +private: + int m_selectedItem; + KUrlNavigator* m_urlNavigator; + KMenu* m_placesMenu; + KFilePlacesModel* m_placesModel; +}; + +#endif diff --git a/src/kprotocolcombo.cpp b/src/kprotocolcombo.cpp new file mode 100644 index 000000000..abe8825f1 --- /dev/null +++ b/src/kprotocolcombo.cpp @@ -0,0 +1,118 @@ +/*************************************************************************** + * Copyright (C) 2006 by Aaron J. Seigo () * + * * + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include + +#include +#include +#include + +#include "kprotocolcombo_p.h" + +const static int customProtocolIndex = 0; + +KProtocolCombo::KProtocolCombo(const QString& protocol, KUrlNavigator* parent) + : KUrlNavigatorButton(-1, parent), + m_protocols(KProtocolInfo::protocols()) +{ + qSort(m_protocols); + QStringList::iterator it = m_protocols.begin(); + QStringList::iterator itEnd = m_protocols.end(); + QMenu* menu = new QMenu(this); + while (it != itEnd) + { + //kDebug() << "info for " << *it << " " + // << KProtocolInfo::protocolClass(*it) << endl; + //TODO: wow this is ugly. or .. is it? ;) we need a way to determine + // if a protocol is appropriate for use in a file manager. hum! + //if (KProtocolInfo::capabilities(*it).findIndex("filemanager") == -1) + + // DF: why not just supportsListing? + + if (KProtocolInfo::protocolClass(*it) == ":" || + !KProtocolManager::supportsWriting(*it)) + { + //kDebug() << "!!! removing " << *it << endl; + QStringList::iterator tempIt = it; + ++tempIt; + m_protocols.erase(it); + it = tempIt; + } + else + { + ++it; + } + } + +// setEditable(true); +// menu->insertItem("", customProtocolIndex); +// menu->insertStringList(m_protocols); + int i = 0; + for (QStringList::const_iterator it = m_protocols.constBegin(); + it != m_protocols.constEnd(); + ++it, ++i) + { + menu->insertItem(*it, i); + } + //menu->insertItems(m_protocols); + connect(menu, SIGNAL(activated(int)), this, SLOT(setProtocol(int))); + setText(protocol); + setMenu(menu); + setFlat(true); +} + + +// #include +// #include "urlnavigator.h" +void KProtocolCombo::setProtocol(const QString& protocol) +{ + setText(protocol); +// if (KProtocolInfo::isKnownProtocol(protocol)) +// int index = m_protocols.findIndex(protocol); +// if (index == -1) +// { +// changeItem(protocol, customProtocolIndex); +// setCurrentItem(customProtocolIndex); +// } +// else +// { +// setCurrentItem(index + 1); +// } +} + +void KProtocolCombo::setProtocol(int index) +{ + if (index < 0 || index > m_protocols.count()) + { + return; + } + + QString protocol = m_protocols[index]; +kDebug() << "setProtocol " << index << " " << protocol << endl; + setText(protocol); + emit activated(protocol); +/* */ +} + +QString KProtocolCombo::currentProtocol() const +{ + return text(); //currentText(); +} + +#include "kprotocolcombo_p.moc" diff --git a/src/kprotocolcombo_p.h b/src/kprotocolcombo_p.h new file mode 100644 index 000000000..da2e4e756 --- /dev/null +++ b/src/kprotocolcombo_p.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2006 by Aaron J. Seigo () * + * * + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ +#ifndef KPROTOCOLCOMBO_P_H +#define KPROTOCOLCOMBO_P_H + +#include "kurlnavigatorbutton_p.h" + +class KUrlNavigator; + +/** + * A combobox listing available protocols + */ +class KProtocolCombo : public KUrlNavigatorButton +{ + Q_OBJECT + + public: + explicit KProtocolCombo(const QString& protocol, KUrlNavigator* parent = 0); + + QString currentProtocol() const; + + public slots: + void setProtocol(const QString& protocol); + void setProtocol(int index); + + signals: + void activated(const QString& protocol); + + private: + QStringList m_protocols; +}; + +#endif diff --git a/src/kurlbutton.cpp b/src/kurlbutton.cpp new file mode 100644 index 000000000..af2d563f1 --- /dev/null +++ b/src/kurlbutton.cpp @@ -0,0 +1,81 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * + * Copyright (C) 2006 by Aaron J. Seigo () * + * * + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include "kurlbutton_p.h" + +#include "kurlnavigator.h" + +KUrlButton::KUrlButton(KUrlNavigator* parent) : + QPushButton(parent), + m_displayHint(0), + m_urlNavigator(parent) +{ + setFocusPolicy(Qt::NoFocus); + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); + setMinimumHeight(parent->minimumHeight()); + + connect(this, SIGNAL(clicked()), parent, SLOT(requestActivation())); +} + +KUrlButton::~KUrlButton() +{ +} + +void KUrlButton::setDisplayHintEnabled(DisplayHint hint, + bool enable) +{ + if (enable) { + m_displayHint = m_displayHint | hint; + } + else { + m_displayHint = m_displayHint & ~hint; + } + update(); +} + +bool KUrlButton::isDisplayHintEnabled(DisplayHint hint) const +{ + return (m_displayHint & hint) > 0; +} + +void KUrlButton::enterEvent(QEvent* event) +{ + QPushButton::enterEvent(event); + setDisplayHintEnabled(EnteredHint, true); + update(); +} + +void KUrlButton::leaveEvent(QEvent* event) +{ + QPushButton::leaveEvent(event); + setDisplayHintEnabled(EnteredHint, false); + update(); +} + +QColor KUrlButton::mixColors(const QColor& c1, + const QColor& c2) const +{ + const int red = (c1.red() + c2.red()) / 2; + const int green = (c1.green() + c2.green()) / 2; + const int blue = (c1.blue() + c2.blue()) / 2; + return QColor(red, green, blue); +} + +#include "kurlbutton_p.moc" diff --git a/src/kurlbutton_p.h b/src/kurlbutton_p.h new file mode 100644 index 000000000..ed0e31423 --- /dev/null +++ b/src/kurlbutton_p.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * + * Copyright (C) 2006 by Aaron J. Seigo () * + * * + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef KURLBUTTON_P_H +#define KURLBUTTON_P_H + +#include + +class KUrl; +class QEvent; +class KUrlNavigator; + +/** + * @brief Base class for buttons of the URL navigator. + * + * Each button of the URL navigator contains an URL, which + * is set as soon as the button has been clicked. + */ +class KUrlButton : public QPushButton +{ + Q_OBJECT + +public: + explicit KUrlButton(KUrlNavigator* parent); + virtual ~KUrlButton(); + + KUrlNavigator* urlNavigator() const { return m_urlNavigator; } + +protected: + enum DisplayHint { + ActivatedHint = 1, + EnteredHint = 2, + DraggedHint = 4, + PopupActiveHint = 8 + }; + + void setDisplayHintEnabled(DisplayHint hint, bool enable); + bool isDisplayHintEnabled(DisplayHint hint) const; + + virtual void enterEvent(QEvent* event); + virtual void leaveEvent(QEvent* event); + + QColor mixColors(const QColor& c1, const QColor& c2) const; + +private: + int m_displayHint; + KUrlNavigator* m_urlNavigator; +}; + +#endif diff --git a/src/kurlnavigator.cpp b/src/kurlnavigator.cpp new file mode 100644 index 000000000..2d2cd8cf2 --- /dev/null +++ b/src/kurlnavigator.cpp @@ -0,0 +1,823 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz () * + * Copyright (C) 2006 by Aaron J. Seigo () * + * Copyright (C) 2006 by Patrice Tremblay * + * Copyright (C) 2007 by Kevin Ottens (ervin@kde.org) * + * * + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include "kurlnavigator.h" + +#include "kfileplacesselector_p.h" +#include "kprotocolcombo_p.h" +#include "kurlnavigatorbutton_p.h" + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * @brief Represents the history element of an URL. + * + * A history element contains the URL, the name of the current file + * (the 'current file' is the file where the cursor is located) and + * the x- and y-position of the content. + */ +class HistoryElem { +public: + HistoryElem(); + HistoryElem(const KUrl& url); + ~HistoryElem(); // non virtual + + const KUrl& url() const { return m_url; } + + void setCurrentFileName(const QString& name) { m_currentFileName = name; } + const QString& currentFileName() const { return m_currentFileName; } + + void setContentsX(int x) { m_contentsX = x; } + int contentsX() const { return m_contentsX; } + + void setContentsY(int y) { m_contentsY = y; } + int contentsY() const { return m_contentsY; } + +private: + KUrl m_url; + QString m_currentFileName; + int m_contentsX; + int m_contentsY; +}; + +HistoryElem::HistoryElem() : + m_url(), + m_currentFileName(), + m_contentsX(0), + m_contentsY(0) +{ +} + +HistoryElem::HistoryElem(const KUrl& url) : + m_url(url), + m_currentFileName(), + m_contentsX(0), + m_contentsY(0) +{ +} + +HistoryElem::~HistoryElem() +{ +} + +class KUrlNavigator::Private +{ +public: + Private(KUrlNavigator* q, KFilePlacesModel* placesModel); + + void slotReturnPressed(const QString&); + void slotRemoteHostActivated(); + void slotProtocolChanged(const QString&); + + /** + * Appends the widget at the end of the URL navigator. It is assured + * that the filler widget remains as last widget to fill the remaining + * width. + */ + void appendWidget(QWidget* widget); + + /** + * Switches the navigation bar between the breadcrumb view and the + * traditional view (see setUrlEditable()) and is connected to the clicked signal + * of the navigation bar button. + */ + void switchView(); + + /** + * Updates the history element with the current file item + * and the contents position. + */ + void updateHistoryElem(); + void updateContent(); + + /** + * Updates all buttons to have one button for each part of the + * path \a path. Existing buttons, which are available by m_navButtons, + * are reused if possible. If the path is longer, new buttons will be + * created, if the path is shorter, the remaining buttons will be deleted. + * @param startIndex Start index of path part (/), where the buttons + * should be created for each following part. + */ + void updateButtons(const QString& path, int startIndex); + + /** + * Deletes all URL navigator buttons. m_navButtons is + * empty after this operation. + */ + void deleteButtons(); + + + bool m_active; + bool m_showHiddenFiles; + int m_historyIndex; + + QHBoxLayout* m_layout; + + QList m_history; + QToolButton* m_toggleButton; + KFilePlacesSelector* m_placesSelector; + KUrlComboBox* m_pathBox; + KProtocolCombo* m_protocols; + QLabel* m_protocolSeparator; + QLineEdit* m_host; + QLinkedList m_navButtons; + QWidget* m_filler; + QString m_homeUrl; + KUrlNavigator* q; +}; + + +KUrlNavigator::Private::Private(KUrlNavigator* q, KFilePlacesModel* placesModel) + : + m_active(true), + m_showHiddenFiles(false), + m_historyIndex(0), + m_layout(new QHBoxLayout), + m_protocols(0), + m_protocolSeparator(0), + m_host(0), + m_filler(0), + q(q) +{ + m_layout->setSpacing(0); + m_layout->setMargin(0); + + // initialize toggle button which switches between the breadcrumb view + // and the traditional view + m_toggleButton = new QToolButton(); + m_toggleButton->setCheckable(true); + m_toggleButton->setAutoRaise(true); + m_toggleButton->setIcon(KIcon("editinput")); // TODO: is just a placeholder icon (?) + m_toggleButton->setFocusPolicy(Qt::NoFocus); + m_toggleButton->setMinimumHeight(q->minimumHeight()); + connect(m_toggleButton, SIGNAL(clicked()), + q, SLOT(switchView())); + + // initialize the places selector + m_placesSelector = new KFilePlacesSelector(q, placesModel); + connect(m_placesSelector, SIGNAL(placeActivated(const KUrl&)), + q, SLOT(setUrl(const KUrl&))); + + // initialize the path box of the traditional view + m_pathBox = new KUrlComboBox(KUrlComboBox::Directories, true, q); + + KUrlCompletion* kurlCompletion = new KUrlCompletion(KUrlCompletion::DirCompletion); + m_pathBox->setCompletionObject(kurlCompletion); + m_pathBox->setAutoDeleteCompletionObject(true); + + connect(m_pathBox, SIGNAL(returnPressed(QString)), + q, SLOT(slotReturnPressed(QString))); + connect(m_pathBox, SIGNAL(urlActivated(KUrl)), + q, SLOT(setUrl(KUrl))); + + // Append a filler widget at the end, which automatically resizes to the + // maximum available width. This assures that the URL navigator uses the + // whole width, so that the clipboard content can be dropped. + m_filler = new QWidget(); + m_filler->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + + m_layout->addWidget(m_toggleButton); + m_layout->addWidget(m_placesSelector); + m_layout->addWidget(m_pathBox); + m_layout->addWidget(m_filler); +} + +void KUrlNavigator::Private::appendWidget(QWidget* widget) +{ + m_layout->insertWidget(m_layout->count() - 1, widget); +} + +void KUrlNavigator::Private::slotReturnPressed(const QString& text) +{ + // Parts of the following code have been taken + // from the class KateFileSelector located in + // kate/app/katefileselector.hpp of Kate. + // Copyright (C) 2001 Christoph Cullmann + // Copyright (C) 2001 Joseph Wenninger + // Copyright (C) 2001 Anders Lund + + KUrl typedUrl(text); + if (typedUrl.hasPass()) { + typedUrl.setPass(QString()); + } + + QStringList urls = m_pathBox->urls(); + urls.removeAll(typedUrl.url()); + urls.prepend(typedUrl.url()); + m_pathBox->setUrls(urls, KUrlComboBox::RemoveBottom); + + q->setUrl(typedUrl); + // The URL might have been adjusted by KUrlNavigator::setUrl(), hence + // synchronize the result in the path box. + m_pathBox->setUrl(q->url()); +} + +void KUrlNavigator::Private::slotRemoteHostActivated() +{ + KUrl u = q->url(); + + QString host = m_host->text(); + QString user; + + int marker = host.indexOf("@"); + if (marker != -1) + { + user = host.left(marker); + u.setUser(user); + host = host.right(host.length() - marker - 1); + } + + marker = host.indexOf("/"); + if (marker != -1) + { + u.setPath(host.right(host.length() - marker)); + host.truncate(marker); + } + else + { + u.setPath(""); + } + + if (m_protocols->currentProtocol() != u.protocol() || + host != u.host() || + user != u.user()) + { + u.setProtocol(m_protocols->currentProtocol()); + u.setHost(m_host->text()); + + //TODO: get rid of this HACK for file:///! + if (u.protocol() == "file") + { + u.setHost(""); + if (u.path().isEmpty()) + { + u.setPath("/"); + } + } + + q->setUrl(u); + } +} + +void KUrlNavigator::Private::slotProtocolChanged(const QString& protocol) +{ + KUrl url; + url.setProtocol(protocol); + //url.setPath(KProtocolInfo::protocolClass(protocol) == ":local" ? "/" : ""); + url.setPath("/"); + QLinkedList::const_iterator it = m_navButtons.begin(); + const QLinkedList::const_iterator itEnd = m_navButtons.end(); + while (it != itEnd) { + (*it)->close(); + (*it)->deleteLater(); + ++it; + } + m_navButtons.clear(); + + if (KProtocolInfo::protocolClass(protocol) == ":local") { + q->setUrl(url); + } + else { + if (!m_host) { + m_protocolSeparator = new QLabel("://", q); + appendWidget(m_protocolSeparator); + m_host = new QLineEdit(q); + appendWidget(m_host); + + connect(m_host, SIGNAL(lostFocus()), + q, SLOT(slotRemoteHostActivated())); + connect(m_host, SIGNAL(returnPressed()), + q, SLOT(slotRemoteHostActivated())); + } + else { + m_host->setText(""); + } + m_protocolSeparator->show(); + m_host->show(); + m_host->setFocus(); + } +} + +#if 0 +void KUrlNavigator::slotRedirection(const KUrl& oldUrl, const KUrl& newUrl) +{ +// kDebug() << "received redirection to " << newUrl << endl; +kDebug() << "received redirection from " << oldUrl << " to " << newUrl << endl; +/* UrlStack::iterator it = m_urls.find(oldUrl); + if (it != m_urls.end()) + { + m_urls.erase(++it, m_urls.end()); + } + + m_urls.append(newUrl);*/ +} +#endif + +void KUrlNavigator::Private::switchView() +{ + updateContent(); + if (q->isUrlEditable()) { + m_pathBox->setFocus(); + } else { + q->setUrl(m_pathBox->currentText()); + } + emit q->requestActivation(); +} + +void KUrlNavigator::Private::updateHistoryElem() +{ + assert(m_historyIndex >= 0); + const KFileItem* item = 0; // TODO: m_dolphinView->currentFileItem(); + if (item != 0) { + HistoryElem& hist = m_history[m_historyIndex]; + hist.setCurrentFileName(item->name()); + } +} + +void KUrlNavigator::Private::updateContent() +{ + m_placesSelector->updateSelection(q->url()); + + m_toggleButton->setToolTip(QString()); + QString path(q->url().pathOrUrl()); + + // TODO: prevent accessing the DolphinMainWindow out from this scope + //const QAction* action = dolphinView()->mainWindow()->actionCollection()->action("editable_location"); + // TODO: registry of default shortcuts + //QString shortcut = action? action->shortcut().toString() : "Ctrl+L"; + const QString shortcut = "Ctrl+L"; + + if (m_toggleButton->isChecked()) { + delete m_protocols; m_protocols = 0; + delete m_protocolSeparator; m_protocolSeparator = 0; + delete m_host; m_host = 0; + deleteButtons(); + m_filler->hide(); + + m_toggleButton->setToolTip(i18n("Browse (%1, Escape)", shortcut)); + + q->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + m_pathBox->show(); + m_pathBox->setUrl(q->url()); + } + else { + m_toggleButton->setToolTip(i18n("Edit location (%1)", shortcut)); + + q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + m_pathBox->hide(); + m_filler->show(); + + // get the data from the currently selected place + KUrl placeUrl = m_placesSelector->selectedPlaceUrl(); + + QString placePath; + if (!placeUrl.isValid()) { + // No place is a part of the current Url. + // The following code tries to guess the place + // path. E. g. "fish://root@192.168.0.2/var/lib" writes + // "fish://root@192.168.0.2" to 'placePath', which leads to the + // navigation indication 'Custom Path > var > lib". + int idx = path.indexOf(QString("//")); + idx = path.indexOf("/", (idx < 0) ? 0 : idx + 2); + placePath = (idx < 0) ? path : path.left(idx); + } + else { + placePath = placeUrl.pathOrUrl(); + } + const uint len = placePath.length(); + + // calculate the start point for the URL navigator buttons by counting + // the slashs inside the place URL + int slashCount = 0; + for (uint i = 0; i < len; ++i) { + if (placePath.at(i) == QChar('/')) { + ++slashCount; + } + } + if ((len > 0) && placePath.at(len - 1) == QChar('/')) { + assert(slashCount > 0); + --slashCount; + } + + const KUrl currentUrl = q->url(); + if (!currentUrl.isLocalFile() && !placeUrl.isValid()) { + QString protocol = currentUrl.protocol(); + if (!m_protocols) { + deleteButtons(); + m_protocols = new KProtocolCombo(protocol, q); + appendWidget(m_protocols); + connect(m_protocols, SIGNAL(activated(QString)), + q, SLOT(slotProtocolChanged(QString))); + } + else { + m_protocols->setProtocol(protocol); + } + m_protocols->show(); + + if (KProtocolInfo::protocolClass(protocol) != ":local") { + QString hostText = currentUrl.host(); + + if (!currentUrl.user().isEmpty()) { + hostText = currentUrl.user() + '@' + hostText; + } + + if (!m_host) { + // ######### TODO: this code is duplicated from slotProtocolChanged! + m_protocolSeparator = new QLabel("://", q); + appendWidget(m_protocolSeparator); + m_host = new QLineEdit(hostText, q); + appendWidget(m_host); + + connect(m_host, SIGNAL(lostFocus()), + q, SLOT(slotRemoteHostActivated())); + connect(m_host, SIGNAL(returnPressed()), + q, SLOT(slotRemoteHostActivated())); + } + else { + m_host->setText(hostText); + } + m_protocolSeparator->show(); + m_host->show(); + } + else { + delete m_protocolSeparator; m_protocolSeparator = 0; + delete m_host; m_host = 0; + } + } + else if (m_protocols) { + m_protocols->hide(); + + if (m_host) { + m_protocolSeparator->hide(); + m_host->hide(); + } + } + + updateButtons(path, slashCount); + } +} + +void KUrlNavigator::Private::updateButtons(const QString& path, int startIndex) +{ + QLinkedList::iterator it = m_navButtons.begin(); + const QLinkedList::const_iterator itEnd = m_navButtons.end(); + bool createButton = false; + const KUrl currentUrl = q->url(); + + int idx = startIndex; + bool hasNext = true; + do { + createButton = (it == itEnd); + + const QString dirName = path.section('/', idx, idx); + const bool isFirstButton = (idx == startIndex); + hasNext = isFirstButton || !dirName.isEmpty(); + if (hasNext) { + QString text; + if (isFirstButton) { + // the first URL navigator button should get the name of the + // place instead of the directory name + const KUrl placeUrl = m_placesSelector->selectedPlaceUrl(); + text = m_placesSelector->selectedPlaceText(); + if (text.isEmpty()) { + if (currentUrl.isLocalFile()) { + text = i18n("Custom Path"); + } + else { + ++idx; + continue; + } + } + } + + KUrlNavigatorButton* button = 0; + if (createButton) { + button = new KUrlNavigatorButton(idx, q); + appendWidget(button); + } + else { + button = *it; + button->setIndex(idx); + } + + if (isFirstButton) { + button->setText(text); + } + + if (createButton) { + button->show(); + m_navButtons.append(button); + } + else { + ++it; + } + ++idx; + } + } while (hasNext); + + // delete buttons which are not used anymore + QLinkedList::iterator itBegin = it; + while (it != itEnd) { + (*it)->close(); + (*it)->deleteLater(); + ++it; + } + m_navButtons.erase(itBegin, m_navButtons.end()); +} + +void KUrlNavigator::Private::deleteButtons() +{ + QLinkedList::iterator itBegin = m_navButtons.begin(); + QLinkedList::iterator itEnd = m_navButtons.end(); + QLinkedList::iterator it = itBegin; + while (it != itEnd) { + (*it)->close(); + (*it)->deleteLater(); + ++it; + } + m_navButtons.erase(itBegin, itEnd); +} + +//// + + +KUrlNavigator::KUrlNavigator(KFilePlacesModel* placesModel, + const KUrl& url, + QWidget* parent) : + QWidget(parent), + d( new Private(this, placesModel) ) +{ + d->m_history.prepend(HistoryElem(url)); + + QFontMetrics fontMetrics(font()); + setMinimumHeight(fontMetrics.height() + 10); + + setLayout(d->m_layout); + + d->updateContent(); +} + +KUrlNavigator::~KUrlNavigator() +{ + delete d; +} + +const KUrl& KUrlNavigator::url() const +{ + assert(!d->m_history.empty()); + return d->m_history[d->m_historyIndex].url(); +} + +KUrl KUrlNavigator::url(int index) const +{ + assert(index >= 0); + // keep scheme, hostname etc. maybe we will need this in the future + // for e.g. browsing ftp repositories. + KUrl newurl(url()); + newurl.setPath(QString()); + QString path(url().path()); + + if (!path.isEmpty()) { + if (index == 0) //prevent the last "/" from being stripped + path = "/"; //or we end up with an empty path + else + path = path.section('/', 0, index); + } + + newurl.setPath(path); + return newurl; +} + +QPoint KUrlNavigator::savedPosition() const +{ + const HistoryElem& histElem = d->m_history[d->m_historyIndex]; + return QPoint( histElem.contentsX(), histElem.contentsY() ); +} + +int KUrlNavigator::historySize() const +{ + return d->m_history.count(); +} + +void KUrlNavigator::goBack() +{ + d->updateHistoryElem(); + + const int count = d->m_history.count(); + if (d->m_historyIndex < count - 1) { + ++d->m_historyIndex; + d->updateContent(); + emit urlChanged(url()); + emit historyChanged(); + } +} + +void KUrlNavigator::goForward() +{ + if (d->m_historyIndex > 0) { + --d->m_historyIndex; + d->updateContent(); + emit urlChanged(url()); + emit historyChanged(); + } +} + +void KUrlNavigator::goUp() +{ + setUrl(url().upUrl()); +} + +void KUrlNavigator::goHome() +{ + if (d->m_homeUrl.isEmpty()) + setUrl(QDir::homePath()); + else + setUrl(d->m_homeUrl); +} + +bool KUrlNavigator::isUrlEditable() const +{ + return d->m_toggleButton->isChecked(); +} + +void KUrlNavigator::setUrlEditable(bool editable) +{ + if (isUrlEditable() != editable) { + d->m_toggleButton->toggle(); + d->switchView(); + } +} + +void KUrlNavigator::setActive(bool active) +{ + if (active != d->m_active) { + d->m_active = active; + update(); + if (active) { + emit activated(); + } + } +} + +void KUrlNavigator::setShowHiddenFiles( bool show ) +{ + d->m_showHiddenFiles = show; +} + +void KUrlNavigator::dropUrls(const KUrl::List& urls, + const KUrl& destination) +{ + emit urlsDropped(urls, destination); +} + +void KUrlNavigator::setUrl(const KUrl& url) +{ + QString urlStr(url.pathOrUrl()); + + // TODO: a patch has been submitted by Filip Brcic which adjusts + // the URL for tar and zip files. See https://bugs.kde.org/show_bug.cgi?id=142781 + // for details. The URL navigator part of the patch has not been committed yet, + // as the URL navigator will be subject of change and + // we might think of a more generic approach to check the protocol + MIME type for + // this use case. + + //kDebug() << "setUrl(" << url << ")" << endl; + if ( urlStr.length() > 0 && urlStr.at(0) == '~') { + // replace '~' by the home directory + urlStr.remove(0, 1); + urlStr.insert(0, QDir::homePath()); + } + + const KUrl transformedUrl(urlStr); + + if (d->m_historyIndex > 0) { + // Check whether the previous element of the history has the same Url. + // If yes, just go forward instead of inserting a duplicate history + // element. + HistoryElem& prevHistoryElem = d->m_history[d->m_historyIndex - 1]; + if (transformedUrl == prevHistoryElem.url()) { + goForward(); +// kDebug() << "goin' forward in history" << endl; + return; + } + } + + if (this->url() == transformedUrl) { + // don't insert duplicate history elements +// kDebug() << "current url == transformedUrl" << endl; + return; + } + + d->updateHistoryElem(); + d->m_history.insert(d->m_historyIndex, HistoryElem(transformedUrl)); + + d->updateContent(); + + emit urlChanged(transformedUrl); + emit historyChanged(); + + // Prevent an endless growing of the history: remembering + // the last 100 Urls should be enough... + if (d->m_historyIndex > 100) { + d->m_history.removeFirst(); + --d->m_historyIndex; + } + +/* kDebug() << "history starting ====================" << endl; + int i = 0; + for (QValueListIterator it = d->m_history.begin(); + it != d->m_history.end(); + ++it, ++i) + { + kDebug() << i << ": " << (*it).url() << endl; + } + kDebug() << "history done ========================" << endl;*/ + + requestActivation(); +} + +void KUrlNavigator::requestActivation() +{ + setActive(true); +} + +void KUrlNavigator::storeContentsPosition(int x, int y) +{ + HistoryElem& hist = d->m_history[d->m_historyIndex]; + hist.setContentsX(x); + hist.setContentsY(y); +} + +void KUrlNavigator::keyReleaseEvent(QKeyEvent* event) +{ + QWidget::keyReleaseEvent(event); + if (isUrlEditable() && (event->key() == Qt::Key_Escape)) { + setUrlEditable(false); + } +} + +void KUrlNavigator::mouseReleaseEvent(QMouseEvent* event) +{ + if (event->button() == Qt::MidButton) { + QClipboard* clipboard = QApplication::clipboard(); + const QMimeData* mimeData = clipboard->mimeData(); + if (mimeData->hasText()) { + const QString text = mimeData->text(); + setUrl(KUrl(text)); + } + } + QWidget::mouseReleaseEvent(event); +} + +bool KUrlNavigator::isActive() const +{ + return d->m_active; +} + +bool KUrlNavigator::showHiddenFiles() const +{ + return d->m_showHiddenFiles; +} + +void KUrlNavigator::setHomeUrl(const QString& homeUrl) +{ + d->m_homeUrl = homeUrl; +} + +#include "kurlnavigator.moc" diff --git a/src/kurlnavigator.h b/src/kurlnavigator.h new file mode 100644 index 000000000..c8e01b7d0 --- /dev/null +++ b/src/kurlnavigator.h @@ -0,0 +1,222 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz () * + * Copyright (C) 2006 by Aaron J. Seigo () * + * Copyright (C) 2006 by Patrice Tremblay * + * Copyright (C) 2007 by Kevin Ottens (ervin@kde.org) * + * * + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef KURLNAVIGATOR_H +#define KURLNAVIGATOR_H + +#include +#include + +class KFilePlacesModel; +class QMouseEvent; + +/** + * @brief Navigation bar which contains the current shown URL. + * + * The URL navigator offers two modes: + * - Editable: Represents the 'classic' mode, where the current URL + * is editable inside a line editor. + * - Non editable: The URL is represented by a number of buttons, where + * clicking on a button results in activating the URL + * the button represents. This mode also supports drag + * and drop of items. + * + * The mode can be changed by a toggle button located on the left side of + * the navigator. + * + * The URL navigator also remembers the URL history and allows to go + * back and forward within this history. + */ +class KUrlNavigator : public QWidget +{ + Q_OBJECT + +public: + KUrlNavigator(KFilePlacesModel* placesModel, const KUrl& url, QWidget* parent); + virtual ~KUrlNavigator(); + + /** Returns the current active URL. */ + const KUrl& url() const; + + /** Returns the portion of the current active URL up to the button at index. */ + KUrl url(int index) const; + + /** Returns the amount of items in the history */ + int historySize() const; + + /** Returns the saved position from the history */ + QPoint savedPosition() const; + + /** + * Goes back one step in the URL history. The signals + * UrlNavigator::urlChanged and UrlNavigator::historyChanged + * are submitted. + */ + void goBack(); + + /** + * Goes forward one step in the URL history. The signals + * UrlNavigator::urlChanged and UrlNavigator::historyChanged + * are submitted. + */ + void goForward(); + + /** + * Goes up one step of the URL path. The signals + * UrlNavigator::urlChanged and UrlNavigator::historyChanged + * are submitted. + */ + void goUp(); + + /** + * Goes to the home URL. The signals UrlNavigator::urlChanged + * and UrlNavigator::historyChanged are submitted. + */ + void goHome(); + + /** + * Sets the home URL used by goHome(). + */ + void setHomeUrl(const QString& homeUrl); + + /** + * @return True, if the URL is editable by the user within a line editor. + * If false is returned, each part of the URL is presented by a button + * for fast navigation. + */ + bool isUrlEditable() const; + + /** + * Allows to edit the URL of the navigation bar if \a editable + * is true, and sets the focus accordingly. + * If \a editable is false, each part of + * the URL is presented by a button for a fast navigation. + */ + void setUrlEditable(bool editable); + + /** + * Set the URL navigator to the active mode, if \a active + * is true. The active mode is default. Using the URL navigator + * in the inactive mode is useful when having split views, + * where the inactive view is indicated by an inactive URL + * navigator visually. + */ + void setActive(bool active); + + /** + * Returns true, if the URL navigator is in the active mode. + * @see UrlNavigator::setActive() + */ + bool isActive() const; + + /** + * Sets whether or not to show hidden files in lists + */ + void setShowHiddenFiles( bool show ); + + /** + * Returns true if the URL navigator is set to show hidden files + */ + bool showHiddenFiles() const; // TODO rename, looks like a verb + + /** + * Handles the dropping of the URLs \a urls to the given + * destination \a destination and emits the signal urlsDropped. + */ + void dropUrls(const KUrl::List& urls, + const KUrl& destination); + +public slots: + /** + * Sets the current active URL. + * The signals UrlNavigator::urlChanged and UrlNavigator::historyChanged + * are submitted. + */ + void setUrl(const KUrl& url); + + /** + * Activates the URL navigator (UrlNavigator::isActive() will return true) + * and emits the signal 'activationChanged()'. + */ + void requestActivation(); + + /** + * Stores the coordinates of the contents into + * the current history element. + */ + void storeContentsPosition(int x, int y); + +signals: + /** + * Is emitted, if the URL navigator has been activated by + * a user interaction. + */ + void activated(); + + /** + * Is emitted, if the URL has been changed e. g. by + * the user. + * @see setUrl() + */ + void urlChanged(const KUrl& url); + + /** + * Is emitted, if the history has been changed. Usually + * the history is changed if a new URL has been selected. + */ + void historyChanged(); + + /** + * Is emitted if the URLs \a urls have been dropped + * to the destination \a destination. + */ + void urlsDropped(const KUrl::List& urls, + const KUrl& destination); + +protected: + /** + * If the Escape key is pressed, the navigation bar should switch + * to the browse mode. + */ + virtual void keyReleaseEvent(QKeyEvent* event); + + /** + * Paste the clipboard content as URL, if the middle mouse + * button has been clicked. + */ + virtual void mouseReleaseEvent(QMouseEvent* event); + +private: + Q_PRIVATE_SLOT(d, void slotReturnPressed(const QString& text)) + Q_PRIVATE_SLOT(d, void slotRemoteHostActivated()) + Q_PRIVATE_SLOT(d, void slotProtocolChanged(const QString& protocol)) + Q_PRIVATE_SLOT(d, void switchView()) + //Q_PRIVATE_SLOT(d, void slotRedirection(const KUrl&, const KUrl&)) + +private: + class Private; + Private* const d; + + Q_DISABLE_COPY( KUrlNavigator ) +}; + +#endif diff --git a/src/kurlnavigatorbutton.cpp b/src/kurlnavigatorbutton.cpp new file mode 100644 index 000000000..2e8f5fe0b --- /dev/null +++ b/src/kurlnavigatorbutton.cpp @@ -0,0 +1,361 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * + * Copyright (C) 2006 by Aaron J. Seigo () * + * * + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include "kurlnavigatorbutton_p.h" + +#include + +#include "kurlnavigator.h" + +#include +#include +#include +#include + +#include +#include +#include + +KUrlNavigatorButton::KUrlNavigatorButton(int index, KUrlNavigator* parent) : + KUrlButton(parent), + m_index(-1), + m_popupDelay(0), + m_listJob(0) +{ + setAcceptDrops(true); + setMinimumWidth(arrowWidth()); + setIndex(index); + connect(this, SIGNAL(clicked()), this, SLOT(updateNavigatorUrl())); + + m_popupDelay = new QTimer(this); + m_popupDelay->setSingleShot(true); + connect(m_popupDelay, SIGNAL(timeout()), this, SLOT(startListJob())); + connect(this, SIGNAL(pressed()), this, SLOT(startPopupDelay())); +} + +KUrlNavigatorButton::~KUrlNavigatorButton() +{ +} + +void KUrlNavigatorButton::setIndex(int index) +{ + m_index = index; + + if (m_index < 0) { + return; + } + + QString path(urlNavigator()->url().pathOrUrl()); + setText(path.section('/', index, index)); + + // Check whether the button indicates the full path of the Url. If + // this is the case, the button is marked as 'active'. + ++index; + QFont adjustedFont(font()); + if (path.section('/', index, index).isEmpty()) { + setDisplayHintEnabled(ActivatedHint, true); + adjustedFont.setBold(true); + } + else { + setDisplayHintEnabled(ActivatedHint, false); + adjustedFont.setBold(false); + } + + setFont(adjustedFont); + update(); +} + +QSize KUrlNavigatorButton::sizeHint() const +{ + const int width = fontMetrics().width(text()) + (arrowWidth() * 4); + return QSize(width, KUrlButton::sizeHint().height()); +} + +void KUrlNavigatorButton::paintEvent(QPaintEvent* event) +{ + QPainter painter(this); + painter.setClipRect(event->rect()); + const int buttonWidth = width(); + const int buttonHeight = height(); + + QColor backgroundColor; + QColor foregroundColor; + const bool isHighlighted = isDisplayHintEnabled(EnteredHint) || + isDisplayHintEnabled(DraggedHint) || + isDisplayHintEnabled(PopupActiveHint); + if (isHighlighted) { + backgroundColor = KGlobalSettings::highlightColor(); + foregroundColor = KGlobalSettings::highlightedTextColor(); + } + else { + backgroundColor = palette().brush(QPalette::Background).color(); + foregroundColor = KGlobalSettings::buttonTextColor(); + } + + // dimm the colors if the parent view does not have the focus + const bool isActive = urlNavigator()->isActive(); + if (!isActive) { + QColor dimmColor(palette().brush(QPalette::Background).color()); + foregroundColor = mixColors(foregroundColor, dimmColor); + if (isHighlighted) { + backgroundColor = mixColors(backgroundColor, dimmColor); + } + } + + // draw button background + painter.setPen(Qt::NoPen); + painter.setBrush(backgroundColor); + painter.drawRect(0, 0, buttonWidth, buttonHeight); + + int textWidth = buttonWidth; + if (isDisplayHintEnabled(ActivatedHint) && isActive || isHighlighted) { + painter.setPen(foregroundColor); + } + else { + // dimm the foreground color by mixing it with the background + foregroundColor = mixColors(foregroundColor, backgroundColor); + painter.setPen(foregroundColor); + } + + if (!isDisplayHintEnabled(ActivatedHint)) { + // draw arrow + const int border = 2; // horizontal border + const int middleY = height() / 2; + const int width = arrowWidth(); + const int startX = (buttonWidth - width) - (2 * border); + const int startTopY = middleY - (width - 1); + const int startBottomY = middleY + (width - 1); + for (int i = 0; i < width; ++i) { + painter.drawLine(startX, startTopY + i, startX + i, startTopY + i); + painter.drawLine(startX, startBottomY - i, startX + i, startBottomY - i); + } + + textWidth = startX - border; + } + + const bool clipped = isTextClipped(); + const int align = clipped ? Qt::AlignVCenter : Qt::AlignCenter; + const QRect textRect(0, 0, textWidth, buttonHeight); + if (clipped) { + QLinearGradient gradient(textRect.topLeft(), textRect.topRight()); + gradient.setColorAt(0.8, foregroundColor); + gradient.setColorAt(1.0, backgroundColor); + + QPen pen; + pen.setBrush(QBrush(gradient)); + painter.setPen(pen); + painter.drawText(textRect, align, text()); + } + else { + painter.drawText(textRect, align, text()); + } +} + +void KUrlNavigatorButton::enterEvent(QEvent* event) +{ + KUrlButton::enterEvent(event); + + // if the text is clipped due to a small window width, the text should + // be shown as tooltip + if (isTextClipped()) { + setToolTip(text()); + } +} + +void KUrlNavigatorButton::leaveEvent(QEvent* event) +{ + KUrlButton::leaveEvent(event); + setToolTip(QString()); +} + +void KUrlNavigatorButton::dropEvent(QDropEvent* event) +{ + if (m_index < 0) { + return; + } + + const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData()); + if (!urls.isEmpty()) { + event->acceptProposedAction(); + + setDisplayHintEnabled(DraggedHint, true); + + QString path(urlNavigator()->url().prettyUrl()); + path = path.section('/', 0, m_index + 2); + + urlNavigator()->dropUrls(urls, KUrl(path)); + + setDisplayHintEnabled(DraggedHint, false); + update(); + } +} + +void KUrlNavigatorButton::dragEnterEvent(QDragEnterEvent* event) +{ + if (event->mimeData()->hasUrls()) { + setDisplayHintEnabled(DraggedHint, true); + event->acceptProposedAction(); + + update(); + } +} + +void KUrlNavigatorButton::dragLeaveEvent(QDragLeaveEvent* event) +{ + KUrlButton::dragLeaveEvent(event); + + setDisplayHintEnabled(DraggedHint, false); + update(); +} + + +void KUrlNavigatorButton::updateNavigatorUrl() +{ + stopPopupDelay(); + + if (m_index < 0) { + return; + } + + urlNavigator()->setUrl(urlNavigator()->url(m_index)); +} + +void KUrlNavigatorButton::startPopupDelay() +{ + if (m_popupDelay->isActive() || (m_listJob != 0) || (m_index < 0)) { + return; + } + + m_popupDelay->start(300); +} + +void KUrlNavigatorButton::stopPopupDelay() +{ + m_popupDelay->stop(); + if (m_listJob != 0) { + m_listJob->kill(); + m_listJob = 0; + } +} + +void KUrlNavigatorButton::startListJob() +{ + if (m_listJob != 0) { + return; + } + + const KUrl& url = urlNavigator()->url(m_index); + m_listJob = KIO::listDir(url, false, urlNavigator()->showHiddenFiles()); + m_subdirs.clear(); // just to be ++safe + + connect(m_listJob, SIGNAL(entries(KIO::Job*, const KIO::UDSEntryList &)), + this, SLOT(entriesList(KIO::Job*, const KIO::UDSEntryList&))); + connect(m_listJob, SIGNAL(result(KJob*)), this, SLOT(listJobFinished(KJob*))); +} + +void KUrlNavigatorButton::entriesList(KIO::Job* job, const KIO::UDSEntryList& entries) +{ + if (job != m_listJob) { + return; + } + + KIO::UDSEntryList::const_iterator it = entries.constBegin(); + KIO::UDSEntryList::const_iterator itEnd = entries.constEnd(); + + bool showHidden = urlNavigator()->showHiddenFiles(); + while (it != itEnd) { + const KIO::UDSEntry entry = *it; + if (entry.isDir()) { + QString name = entry.stringValue(KIO::UDS_NAME); + + if (!showHidden || (name != "." && name != "..")) { + m_subdirs.append(name); + } + } + + ++it; + } + + m_subdirs.sort(); +} + +void KUrlNavigatorButton::listJobFinished(KJob* job) +{ + if (job != m_listJob) { + return; + } + + if (job->error() || m_subdirs.isEmpty()) { + // clear listing + return; + } + + setDisplayHintEnabled(PopupActiveHint, true); + update(); // ensure the button is drawn highlighted + + KMenu* dirsMenu = new KMenu(this); + QStringList::const_iterator it = m_subdirs.constBegin(); + QStringList::const_iterator itEnd = m_subdirs.constEnd(); + int i = 0; + while (it != itEnd) { + QAction* action = new QAction(*it, this); + action->setData(i); + dirsMenu->addAction(action); + ++it; + ++i; + } + + const QAction* action = dirsMenu->exec(urlNavigator()->mapToGlobal(geometry().bottomLeft())); + if (action != 0) { + const int result = action->data().toInt(); + KUrl url = urlNavigator()->url(m_index); + url.addPath(m_subdirs[result]); + urlNavigator()->setUrl(url); + } + + m_listJob = 0; + m_subdirs.clear(); + delete dirsMenu; + dirsMenu = 0; + + setDisplayHintEnabled(PopupActiveHint, false); +} + +int KUrlNavigatorButton::arrowWidth() const +{ + int width = (height() / 2) - 7; + if (width < 4) { + width = 4; + } + return width; +} + +bool KUrlNavigatorButton::isTextClipped() const +{ + int availableWidth = width(); + if (!isDisplayHintEnabled(ActivatedHint)) { + availableWidth -= arrowWidth() + 1; + } + + QFontMetrics fontMetrics(font()); + return fontMetrics.width(text()) >= availableWidth; +} + +#include "kurlnavigatorbutton_p.moc" diff --git a/src/kurlnavigatorbutton_p.h b/src/kurlnavigatorbutton_p.h new file mode 100644 index 000000000..2244cc699 --- /dev/null +++ b/src/kurlnavigatorbutton_p.h @@ -0,0 +1,86 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * + * Copyright (C) 2006 by Aaron J. Seigo () * + * * + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef KURLNAVIGATORBUTTON_P_H +#define KURLNAVIGATORBUTTON_P_H + +#include +#include "kurlbutton_p.h" + +class KJob; +class KUrl; +class KUrlNavigator; +class QPainter; +class QPaintEvent; + +namespace KIO +{ + class Job; +} + +/** + * @brief Button of the URL navigator which contains one part of an URL. + * + * It is possible to drop a various number of items to an UrlNavigatorButton. In this case + * a context menu is opened where the user must select whether he wants + * to copy, move or link the dropped items to the URL part indicated by + * the button. + */ +class KUrlNavigatorButton : public KUrlButton +{ + Q_OBJECT + +public: + explicit KUrlNavigatorButton(int index, KUrlNavigator* parent); + virtual ~KUrlNavigatorButton(); + void setIndex(int index); + int index() const { return m_index; } + + /** @see QWidget::sizeHint() */ + virtual QSize sizeHint() const; + +protected: + virtual void paintEvent(QPaintEvent* event); + virtual void enterEvent(QEvent* event); + virtual void leaveEvent(QEvent* event); + virtual void dropEvent(QDropEvent* event); + virtual void dragEnterEvent(QDragEnterEvent* event); + virtual void dragLeaveEvent(QDragLeaveEvent* event); + +private slots: + void updateNavigatorUrl(); + void startPopupDelay(); + void stopPopupDelay(); + void startListJob(); + void entriesList(KIO::Job* job, const KIO::UDSEntryList& entries); + void listJobFinished(KJob* job); + +private: + int arrowWidth() const; + bool isTextClipped() const; + +private: + int m_index; + QTimer* m_popupDelay; + KIO::Job* m_listJob; + QStringList m_subdirs; +}; + +#endif diff --git a/src/protocolcombo.cpp b/src/protocolcombo.cpp deleted file mode 100644 index 729102973..000000000 --- a/src/protocolcombo.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Aaron J. Seigo () * - * * - * 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) any later version. * - * * - * 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, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - -#include - -#include -#include -#include - -#include "protocolcombo.h" - -const static int customProtocolIndex = 0; - -ProtocolCombo::ProtocolCombo(const QString& protocol, UrlNavigator* parent) - : UrlNavigatorButton(-1, parent), - m_protocols(KProtocolInfo::protocols()) -{ - qSort(m_protocols); - QStringList::iterator it = m_protocols.begin(); - QStringList::iterator itEnd = m_protocols.end(); - QMenu* menu = new QMenu(this); - while (it != itEnd) - { - //kDebug() << "info for " << *it << " " - // << KProtocolInfo::protocolClass(*it) << endl; - //TODO: wow this is ugly. or .. is it? ;) we need a way to determine - // if a protocol is appropriate for use in a file manager. hum! - //if (KProtocolInfo::capabilities(*it).findIndex("filemanager") == -1) - - // DF: why not just supportsListing? - - if (KProtocolInfo::protocolClass(*it) == ":" || - !KProtocolManager::supportsWriting(*it)) - { - //kDebug() << "!!! removing " << *it << endl; - QStringList::iterator tempIt = it; - ++tempIt; - m_protocols.erase(it); - it = tempIt; - } - else - { - ++it; - } - } - -// setEditable(true); -// menu->insertItem("", customProtocolIndex); -// menu->insertStringList(m_protocols); - int i = 0; - for (QStringList::const_iterator it = m_protocols.constBegin(); - it != m_protocols.constEnd(); - ++it, ++i) - { - menu->insertItem(*it, i); - } - //menu->insertItems(m_protocols); - connect(menu, SIGNAL(activated(int)), this, SLOT(setProtocol(int))); - setText(protocol); - setMenu(menu); - setFlat(true); -} - - -// #include -// #include "urlnavigator.h" -void ProtocolCombo::setProtocol(const QString& protocol) -{ - setText(protocol); -// if (KProtocolInfo::isKnownProtocol(protocol)) -// int index = m_protocols.findIndex(protocol); -// if (index == -1) -// { -// changeItem(protocol, customProtocolIndex); -// setCurrentItem(customProtocolIndex); -// } -// else -// { -// setCurrentItem(index + 1); -// } -} - -void ProtocolCombo::setProtocol(int index) -{ - if (index < 0 || index > m_protocols.count()) - { - return; - } - - QString protocol = m_protocols[index]; -kDebug() << "setProtocol " << index << " " << protocol << endl; - setText(protocol); - emit activated(protocol); -/* */ -} - -QString ProtocolCombo::currentProtocol() const -{ - return text(); //currentText(); -} - -#include "protocolcombo.moc" diff --git a/src/protocolcombo.h b/src/protocolcombo.h deleted file mode 100644 index 56a001863..000000000 --- a/src/protocolcombo.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Aaron J. Seigo () * - * * - * 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) any later version. * - * * - * 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, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ -#ifndef PROTOCOLCOMBO_H -#define PROTOCOLCOMBO_H - -#include "urlnavigatorbutton.h" - -class UrlNavigator; - -/** - * A combobox listing available protocols - */ -class ProtocolCombo : public UrlNavigatorButton -{ - Q_OBJECT - - public: - explicit ProtocolCombo(const QString& protocol, UrlNavigator* parent = 0); - - QString currentProtocol() const; - - public slots: - void setProtocol(const QString& protocol); - void setProtocol(int index); - - signals: - void activated(const QString& protocol); - - private: - QStringList m_protocols; -}; - -#endif diff --git a/src/urlbutton.cpp b/src/urlbutton.cpp deleted file mode 100644 index 32d8da911..000000000 --- a/src/urlbutton.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * - * Copyright (C) 2006 by Aaron J. Seigo () * - * * - * 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) any later version. * - * * - * 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, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - -#include "urlnavigatorbutton.h" -#include "urlnavigator.h" - -UrlButton::UrlButton(UrlNavigator* parent) : - QPushButton(parent), - m_displayHint(0), - m_urlNavigator(parent) -{ - setFocusPolicy(Qt::NoFocus); - setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); - setMinimumHeight(parent->minimumHeight()); - - connect(this, SIGNAL(clicked()), parent, SLOT(requestActivation())); -} - -UrlButton::~UrlButton() -{ -} - -void UrlButton::setDisplayHintEnabled(DisplayHint hint, - bool enable) -{ - if (enable) { - m_displayHint = m_displayHint | hint; - } - else { - m_displayHint = m_displayHint & ~hint; - } - update(); -} - -bool UrlButton::isDisplayHintEnabled(DisplayHint hint) const -{ - return (m_displayHint & hint) > 0; -} - -void UrlButton::enterEvent(QEvent* event) -{ - QPushButton::enterEvent(event); - setDisplayHintEnabled(EnteredHint, true); - update(); -} - -void UrlButton::leaveEvent(QEvent* event) -{ - QPushButton::leaveEvent(event); - setDisplayHintEnabled(EnteredHint, false); - update(); -} - -QColor UrlButton::mixColors(const QColor& c1, - const QColor& c2) const -{ - const int red = (c1.red() + c2.red()) / 2; - const int green = (c1.green() + c2.green()) / 2; - const int blue = (c1.blue() + c2.blue()) / 2; - return QColor(red, green, blue); -} - -#include "urlbutton.moc" diff --git a/src/urlbutton.h b/src/urlbutton.h deleted file mode 100644 index 9ec0375cd..000000000 --- a/src/urlbutton.h +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * - * Copyright (C) 2006 by Aaron J. Seigo () * - * * - * 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) any later version. * - * * - * 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, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - -#ifndef URLBUTTON_H -#define URLBUTTON_H - -#include - -class KUrl; -class QEvent; -class UrlNavigator; - -/** - * @brief Base class for buttons of the URL navigator. - * - * Each button of the URL navigator contains an URL, which - * is set as soon as the button has been clicked. - */ -class UrlButton : public QPushButton -{ - Q_OBJECT - -public: - explicit UrlButton(UrlNavigator* parent); - virtual ~UrlButton(); - - UrlNavigator* urlNavigator() const { return m_urlNavigator; } - -protected: - enum DisplayHint { - ActivatedHint = 1, - EnteredHint = 2, - DraggedHint = 4, - PopupActiveHint = 8 - }; - - void setDisplayHintEnabled(DisplayHint hint, bool enable); - bool isDisplayHintEnabled(DisplayHint hint) const; - - virtual void enterEvent(QEvent* event); - virtual void leaveEvent(QEvent* event); - - QColor mixColors(const QColor& c1, const QColor& c2) const; - -private: - int m_displayHint; - UrlNavigator* m_urlNavigator; -}; - -#endif diff --git a/src/urlnavigator.cpp b/src/urlnavigator.cpp deleted file mode 100644 index 1e8f06b6e..000000000 --- a/src/urlnavigator.cpp +++ /dev/null @@ -1,822 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Peter Penz () * - * Copyright (C) 2006 by Aaron J. Seigo () * - * Copyright (C) 2006 by Patrice Tremblay * - * * - * 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) any later version. * - * * - * 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, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - -#include "urlnavigator.h" - -#include "bookmarkselector.h" -#include "protocolcombo.h" -#include "urlnavigatorbutton.h" - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * @brief Represents the history element of an URL. - * - * A history element contains the URL, the name of the current file - * (the 'current file' is the file where the cursor is located) and - * the x- and y-position of the content. - */ -class HistoryElem { -public: - HistoryElem(); - HistoryElem(const KUrl& url); - ~HistoryElem(); // non virtual - - const KUrl& url() const { return m_url; } - - void setCurrentFileName(const QString& name) { m_currentFileName = name; } - const QString& currentFileName() const { return m_currentFileName; } - - void setContentsX(int x) { m_contentsX = x; } - int contentsX() const { return m_contentsX; } - - void setContentsY(int y) { m_contentsY = y; } - int contentsY() const { return m_contentsY; } - -private: - KUrl m_url; - QString m_currentFileName; - int m_contentsX; - int m_contentsY; -}; - -HistoryElem::HistoryElem() : - m_url(), - m_currentFileName(), - m_contentsX(0), - m_contentsY(0) -{ -} - -HistoryElem::HistoryElem(const KUrl& url) : - m_url(url), - m_currentFileName(), - m_contentsX(0), - m_contentsY(0) -{ -} - -HistoryElem::~HistoryElem() -{ -} - -class UrlNavigator::Private -{ -public: - Private(UrlNavigator* q, KFilePlacesModel* placesModel); - - void slotReturnPressed(const QString&); - void slotRemoteHostActivated(); - void slotProtocolChanged(const QString&); - - /** - * Appends the widget at the end of the URL navigator. It is assured - * that the filler widget remains as last widget to fill the remaining - * width. - */ - void appendWidget(QWidget* widget); - - /** - * Switches the navigation bar between the breadcrumb view and the - * traditional view (see setUrlEditable()) and is connected to the clicked signal - * of the navigation bar button. - */ - void switchView(); - - /** - * Updates the history element with the current file item - * and the contents position. - */ - void updateHistoryElem(); - void updateContent(); - - /** - * Updates all buttons to have one button for each part of the - * path \a path. Existing buttons, which are available by m_navButtons, - * are reused if possible. If the path is longer, new buttons will be - * created, if the path is shorter, the remaining buttons will be deleted. - * @param startIndex Start index of path part (/), where the buttons - * should be created for each following part. - */ - void updateButtons(const QString& path, int startIndex); - - /** - * Deletes all URL navigator buttons. m_navButtons is - * empty after this operation. - */ - void deleteButtons(); - - - bool m_active; - bool m_showHiddenFiles; - int m_historyIndex; - - QHBoxLayout* m_layout; - - QList m_history; - QToolButton* m_toggleButton; - BookmarkSelector* m_bookmarkSelector; - KUrlComboBox* m_pathBox; - ProtocolCombo* m_protocols; - QLabel* m_protocolSeparator; - QLineEdit* m_host; - QLinkedList m_navButtons; - QWidget* m_filler; - QString m_homeUrl; - UrlNavigator* q; -}; - - -UrlNavigator::Private::Private(UrlNavigator* q, KFilePlacesModel* placesModel) - : - m_active(true), - m_showHiddenFiles(false), - m_historyIndex(0), - m_layout(new QHBoxLayout), - m_protocols(0), - m_protocolSeparator(0), - m_host(0), - m_filler(0), - q(q) -{ - m_layout->setSpacing(0); - m_layout->setMargin(0); - - // initialize toggle button which switches between the breadcrumb view - // and the traditional view - m_toggleButton = new QToolButton(); - m_toggleButton->setCheckable(true); - m_toggleButton->setAutoRaise(true); - m_toggleButton->setIcon(KIcon("editinput")); // TODO: is just a placeholder icon (?) - m_toggleButton->setFocusPolicy(Qt::NoFocus); - m_toggleButton->setMinimumHeight(q->minimumHeight()); - connect(m_toggleButton, SIGNAL(clicked()), - q, SLOT(switchView())); - - // initialize the bookmark selector - m_bookmarkSelector = new BookmarkSelector(q, placesModel); - connect(m_bookmarkSelector, SIGNAL(placeActivated(const KUrl&)), - q, SLOT(setUrl(const KUrl&))); - - // initialize the path box of the traditional view - m_pathBox = new KUrlComboBox(KUrlComboBox::Directories, true, q); - - KUrlCompletion* kurlCompletion = new KUrlCompletion(KUrlCompletion::DirCompletion); - m_pathBox->setCompletionObject(kurlCompletion); - m_pathBox->setAutoDeleteCompletionObject(true); - - connect(m_pathBox, SIGNAL(returnPressed(QString)), - q, SLOT(slotReturnPressed(QString))); - connect(m_pathBox, SIGNAL(urlActivated(KUrl)), - q, SLOT(setUrl(KUrl))); - - // Append a filler widget at the end, which automatically resizes to the - // maximum available width. This assures that the URL navigator uses the - // whole width, so that the clipboard content can be dropped. - m_filler = new QWidget(); - m_filler->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - - m_layout->addWidget(m_toggleButton); - m_layout->addWidget(m_bookmarkSelector); - m_layout->addWidget(m_pathBox); - m_layout->addWidget(m_filler); -} - -void UrlNavigator::Private::appendWidget(QWidget* widget) -{ - m_layout->insertWidget(m_layout->count() - 1, widget); -} - -void UrlNavigator::Private::slotReturnPressed(const QString& text) -{ - // Parts of the following code have been taken - // from the class KateFileSelector located in - // kate/app/katefileselector.hpp of Kate. - // Copyright (C) 2001 Christoph Cullmann - // Copyright (C) 2001 Joseph Wenninger - // Copyright (C) 2001 Anders Lund - - KUrl typedUrl(text); - if (typedUrl.hasPass()) { - typedUrl.setPass(QString()); - } - - QStringList urls = m_pathBox->urls(); - urls.removeAll(typedUrl.url()); - urls.prepend(typedUrl.url()); - m_pathBox->setUrls(urls, KUrlComboBox::RemoveBottom); - - q->setUrl(typedUrl); - // The URL might have been adjusted by UrlNavigator::setUrl(), hence - // synchronize the result in the path box. - m_pathBox->setUrl(q->url()); -} - -void UrlNavigator::Private::slotRemoteHostActivated() -{ - KUrl u = q->url(); - - QString host = m_host->text(); - QString user; - - int marker = host.indexOf("@"); - if (marker != -1) - { - user = host.left(marker); - u.setUser(user); - host = host.right(host.length() - marker - 1); - } - - marker = host.indexOf("/"); - if (marker != -1) - { - u.setPath(host.right(host.length() - marker)); - host.truncate(marker); - } - else - { - u.setPath(""); - } - - if (m_protocols->currentProtocol() != u.protocol() || - host != u.host() || - user != u.user()) - { - u.setProtocol(m_protocols->currentProtocol()); - u.setHost(m_host->text()); - - //TODO: get rid of this HACK for file:///! - if (u.protocol() == "file") - { - u.setHost(""); - if (u.path().isEmpty()) - { - u.setPath("/"); - } - } - - q->setUrl(u); - } -} - -void UrlNavigator::Private::slotProtocolChanged(const QString& protocol) -{ - KUrl url; - url.setProtocol(protocol); - //url.setPath(KProtocolInfo::protocolClass(protocol) == ":local" ? "/" : ""); - url.setPath("/"); - QLinkedList::const_iterator it = m_navButtons.begin(); - const QLinkedList::const_iterator itEnd = m_navButtons.end(); - while (it != itEnd) { - (*it)->close(); - (*it)->deleteLater(); - ++it; - } - m_navButtons.clear(); - - if (KProtocolInfo::protocolClass(protocol) == ":local") { - q->setUrl(url); - } - else { - if (!m_host) { - m_protocolSeparator = new QLabel("://", q); - appendWidget(m_protocolSeparator); - m_host = new QLineEdit(q); - appendWidget(m_host); - - connect(m_host, SIGNAL(lostFocus()), - q, SLOT(slotRemoteHostActivated())); - connect(m_host, SIGNAL(returnPressed()), - q, SLOT(slotRemoteHostActivated())); - } - else { - m_host->setText(""); - } - m_protocolSeparator->show(); - m_host->show(); - m_host->setFocus(); - } -} - -#if 0 -void UrlNavigator::slotRedirection(const KUrl& oldUrl, const KUrl& newUrl) -{ -// kDebug() << "received redirection to " << newUrl << endl; -kDebug() << "received redirection from " << oldUrl << " to " << newUrl << endl; -/* UrlStack::iterator it = m_urls.find(oldUrl); - if (it != m_urls.end()) - { - m_urls.erase(++it, m_urls.end()); - } - - m_urls.append(newUrl);*/ -} -#endif - -void UrlNavigator::Private::switchView() -{ - updateContent(); - if (q->isUrlEditable()) { - m_pathBox->setFocus(); - } else { - q->setUrl(m_pathBox->currentText()); - } - emit q->requestActivation(); -} - -void UrlNavigator::Private::updateHistoryElem() -{ - assert(m_historyIndex >= 0); - const KFileItem* item = 0; // TODO: m_dolphinView->currentFileItem(); - if (item != 0) { - HistoryElem& hist = m_history[m_historyIndex]; - hist.setCurrentFileName(item->name()); - } -} - -void UrlNavigator::Private::updateContent() -{ - m_bookmarkSelector->updateSelection(q->url()); - - m_toggleButton->setToolTip(QString()); - QString path(q->url().pathOrUrl()); - - // TODO: prevent accessing the DolphinMainWindow out from this scope - //const QAction* action = dolphinView()->mainWindow()->actionCollection()->action("editable_location"); - // TODO: registry of default shortcuts - //QString shortcut = action? action->shortcut().toString() : "Ctrl+L"; - const QString shortcut = "Ctrl+L"; - - if (m_toggleButton->isChecked()) { - delete m_protocols; m_protocols = 0; - delete m_protocolSeparator; m_protocolSeparator = 0; - delete m_host; m_host = 0; - deleteButtons(); - m_filler->hide(); - - m_toggleButton->setToolTip(i18n("Browse (%1, Escape)", shortcut)); - - q->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - m_pathBox->show(); - m_pathBox->setUrl(q->url()); - } - else { - m_toggleButton->setToolTip(i18n("Edit location (%1)", shortcut)); - - q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - m_pathBox->hide(); - m_filler->show(); - - // get the data from the currently selected bookmark - KUrl placeUrl = m_bookmarkSelector->selectedPlaceUrl(); - - QString placePath; - if (!placeUrl.isValid()) { - // No place is a part of the current Url. - // The following code tries to guess the place - // path. E. g. "fish://root@192.168.0.2/var/lib" writes - // "fish://root@192.168.0.2" to 'placePath', which leads to the - // navigation indication 'Custom Path > var > lib". - int idx = path.indexOf(QString("//")); - idx = path.indexOf("/", (idx < 0) ? 0 : idx + 2); - placePath = (idx < 0) ? path : path.left(idx); - } - else { - placePath = placeUrl.pathOrUrl(); - } - const uint len = placePath.length(); - - // calculate the start point for the URL navigator buttons by counting - // the slashs inside the place URL - int slashCount = 0; - for (uint i = 0; i < len; ++i) { - if (placePath.at(i) == QChar('/')) { - ++slashCount; - } - } - if ((len > 0) && placePath.at(len - 1) == QChar('/')) { - assert(slashCount > 0); - --slashCount; - } - - const KUrl currentUrl = q->url(); - if (!currentUrl.isLocalFile() && !placeUrl.isValid()) { - QString protocol = currentUrl.protocol(); - if (!m_protocols) { - deleteButtons(); - m_protocols = new ProtocolCombo(protocol, q); - appendWidget(m_protocols); - connect(m_protocols, SIGNAL(activated(QString)), - q, SLOT(slotProtocolChanged(QString))); - } - else { - m_protocols->setProtocol(protocol); - } - m_protocols->show(); - - if (KProtocolInfo::protocolClass(protocol) != ":local") { - QString hostText = currentUrl.host(); - - if (!currentUrl.user().isEmpty()) { - hostText = currentUrl.user() + '@' + hostText; - } - - if (!m_host) { - // ######### TODO: this code is duplicated from slotProtocolChanged! - m_protocolSeparator = new QLabel("://", q); - appendWidget(m_protocolSeparator); - m_host = new QLineEdit(hostText, q); - appendWidget(m_host); - - connect(m_host, SIGNAL(lostFocus()), - q, SLOT(slotRemoteHostActivated())); - connect(m_host, SIGNAL(returnPressed()), - q, SLOT(slotRemoteHostActivated())); - } - else { - m_host->setText(hostText); - } - m_protocolSeparator->show(); - m_host->show(); - } - else { - delete m_protocolSeparator; m_protocolSeparator = 0; - delete m_host; m_host = 0; - } - } - else if (m_protocols) { - m_protocols->hide(); - - if (m_host) { - m_protocolSeparator->hide(); - m_host->hide(); - } - } - - updateButtons(path, slashCount); - } -} - -void UrlNavigator::Private::updateButtons(const QString& path, int startIndex) -{ - QLinkedList::iterator it = m_navButtons.begin(); - const QLinkedList::const_iterator itEnd = m_navButtons.end(); - bool createButton = false; - const KUrl currentUrl = q->url(); - - int idx = startIndex; - bool hasNext = true; - do { - createButton = (it == itEnd); - - const QString dirName = path.section('/', idx, idx); - const bool isFirstButton = (idx == startIndex); - hasNext = isFirstButton || !dirName.isEmpty(); - if (hasNext) { - QString text; - if (isFirstButton) { - // the first URL navigator button should get the name of the - // place instead of the directory name - const KUrl placeUrl = m_bookmarkSelector->selectedPlaceUrl(); - text = m_bookmarkSelector->selectedPlaceText(); - if (text.isEmpty()) { - if (currentUrl.isLocalFile()) { - text = i18n("Custom Path"); - } - else { - ++idx; - continue; - } - } - } - - UrlNavigatorButton* button = 0; - if (createButton) { - button = new UrlNavigatorButton(idx, q); - appendWidget(button); - } - else { - button = *it; - button->setIndex(idx); - } - - if (isFirstButton) { - button->setText(text); - } - - if (createButton) { - button->show(); - m_navButtons.append(button); - } - else { - ++it; - } - ++idx; - } - } while (hasNext); - - // delete buttons which are not used anymore - QLinkedList::iterator itBegin = it; - while (it != itEnd) { - (*it)->close(); - (*it)->deleteLater(); - ++it; - } - m_navButtons.erase(itBegin, m_navButtons.end()); -} - -void UrlNavigator::Private::deleteButtons() -{ - QLinkedList::iterator itBegin = m_navButtons.begin(); - QLinkedList::iterator itEnd = m_navButtons.end(); - QLinkedList::iterator it = itBegin; - while (it != itEnd) { - (*it)->close(); - (*it)->deleteLater(); - ++it; - } - m_navButtons.erase(itBegin, itEnd); -} - -//// - - -UrlNavigator::UrlNavigator(KFilePlacesModel* placesModel, - const KUrl& url, - QWidget* parent) : - QWidget(parent), - d( new Private(this, placesModel) ) -{ - d->m_history.prepend(HistoryElem(url)); - - QFontMetrics fontMetrics(font()); - setMinimumHeight(fontMetrics.height() + 10); - - setLayout(d->m_layout); - - d->updateContent(); -} - -UrlNavigator::~UrlNavigator() -{ - delete d; -} - -const KUrl& UrlNavigator::url() const -{ - assert(!d->m_history.empty()); - return d->m_history[d->m_historyIndex].url(); -} - -KUrl UrlNavigator::url(int index) const -{ - assert(index >= 0); - // keep scheme, hostname etc. maybe we will need this in the future - // for e.g. browsing ftp repositories. - KUrl newurl(url()); - newurl.setPath(QString()); - QString path(url().path()); - - if (!path.isEmpty()) { - if (index == 0) //prevent the last "/" from being stripped - path = "/"; //or we end up with an empty path - else - path = path.section('/', 0, index); - } - - newurl.setPath(path); - return newurl; -} - -QPoint UrlNavigator::savedPosition() const -{ - const HistoryElem& histElem = d->m_history[d->m_historyIndex]; - return QPoint( histElem.contentsX(), histElem.contentsY() ); -} - -int UrlNavigator::historySize() const -{ - return d->m_history.count(); -} - -void UrlNavigator::goBack() -{ - d->updateHistoryElem(); - - const int count = d->m_history.count(); - if (d->m_historyIndex < count - 1) { - ++d->m_historyIndex; - d->updateContent(); - emit urlChanged(url()); - emit historyChanged(); - } -} - -void UrlNavigator::goForward() -{ - if (d->m_historyIndex > 0) { - --d->m_historyIndex; - d->updateContent(); - emit urlChanged(url()); - emit historyChanged(); - } -} - -void UrlNavigator::goUp() -{ - setUrl(url().upUrl()); -} - -void UrlNavigator::goHome() -{ - if (d->m_homeUrl.isEmpty()) - setUrl(QDir::homePath()); - else - setUrl(d->m_homeUrl); -} - -bool UrlNavigator::isUrlEditable() const -{ - return d->m_toggleButton->isChecked(); -} - -void UrlNavigator::setUrlEditable(bool editable) -{ - if (isUrlEditable() != editable) { - d->m_toggleButton->toggle(); - d->switchView(); - } -} - -void UrlNavigator::setActive(bool active) -{ - if (active != d->m_active) { - d->m_active = active; - update(); - if (active) { - emit activated(); - } - } -} - -void UrlNavigator::setShowHiddenFiles( bool show ) -{ - d->m_showHiddenFiles = show; -} - -void UrlNavigator::dropUrls(const KUrl::List& urls, - const KUrl& destination) -{ - emit urlsDropped(urls, destination); -} - -void UrlNavigator::setUrl(const KUrl& url) -{ - QString urlStr(url.pathOrUrl()); - - // TODO: a patch has been submitted by Filip Brcic which adjusts - // the URL for tar and zip files. See https://bugs.kde.org/show_bug.cgi?id=142781 - // for details. The URL navigator part of the patch has not been committed yet, - // as the URL navigator will be subject of change and - // we might think of a more generic approach to check the protocol + MIME type for - // this use case. - - //kDebug() << "setUrl(" << url << ")" << endl; - if ( urlStr.length() > 0 && urlStr.at(0) == '~') { - // replace '~' by the home directory - urlStr.remove(0, 1); - urlStr.insert(0, QDir::homePath()); - } - - const KUrl transformedUrl(urlStr); - - if (d->m_historyIndex > 0) { - // Check whether the previous element of the history has the same Url. - // If yes, just go forward instead of inserting a duplicate history - // element. - HistoryElem& prevHistoryElem = d->m_history[d->m_historyIndex - 1]; - if (transformedUrl == prevHistoryElem.url()) { - goForward(); -// kDebug() << "goin' forward in history" << endl; - return; - } - } - - if (this->url() == transformedUrl) { - // don't insert duplicate history elements -// kDebug() << "current url == transformedUrl" << endl; - return; - } - - d->updateHistoryElem(); - d->m_history.insert(d->m_historyIndex, HistoryElem(transformedUrl)); - - d->updateContent(); - - emit urlChanged(transformedUrl); - emit historyChanged(); - - // Prevent an endless growing of the history: remembering - // the last 100 Urls should be enough... - if (d->m_historyIndex > 100) { - d->m_history.removeFirst(); - --d->m_historyIndex; - } - -/* kDebug() << "history starting ====================" << endl; - int i = 0; - for (QValueListIterator it = d->m_history.begin(); - it != d->m_history.end(); - ++it, ++i) - { - kDebug() << i << ": " << (*it).url() << endl; - } - kDebug() << "history done ========================" << endl;*/ - - requestActivation(); -} - -void UrlNavigator::requestActivation() -{ - setActive(true); -} - -void UrlNavigator::storeContentsPosition(int x, int y) -{ - HistoryElem& hist = d->m_history[d->m_historyIndex]; - hist.setContentsX(x); - hist.setContentsY(y); -} - -void UrlNavigator::keyReleaseEvent(QKeyEvent* event) -{ - QWidget::keyReleaseEvent(event); - if (isUrlEditable() && (event->key() == Qt::Key_Escape)) { - setUrlEditable(false); - } -} - -void UrlNavigator::mouseReleaseEvent(QMouseEvent* event) -{ - if (event->button() == Qt::MidButton) { - QClipboard* clipboard = QApplication::clipboard(); - const QMimeData* mimeData = clipboard->mimeData(); - if (mimeData->hasText()) { - const QString text = mimeData->text(); - setUrl(KUrl(text)); - } - } - QWidget::mouseReleaseEvent(event); -} - -bool UrlNavigator::isActive() const -{ - return d->m_active; -} - -bool UrlNavigator::showHiddenFiles() const -{ - return d->m_showHiddenFiles; -} - -void UrlNavigator::setHomeUrl(const QString& homeUrl) -{ - d->m_homeUrl = homeUrl; -} - -#include "urlnavigator.moc" diff --git a/src/urlnavigator.h b/src/urlnavigator.h deleted file mode 100644 index af77fa8e3..000000000 --- a/src/urlnavigator.h +++ /dev/null @@ -1,221 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Peter Penz () * - * Copyright (C) 2006 by Aaron J. Seigo () * - * Copyright (C) 2006 by Patrice Tremblay * - * * - * 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) any later version. * - * * - * 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, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - -#ifndef URLNAVIGATOR_H -#define URLNAVIGATOR_H - -#include -#include - -class KFilePlacesModel; -class QMouseEvent; - -/** - * @brief Navigation bar which contains the current shown URL. - * - * The URL navigator offers two modes: - * - Editable: Represents the 'classic' mode, where the current URL - * is editable inside a line editor. - * - Non editable: The URL is represented by a number of buttons, where - * clicking on a button results in activating the URL - * the button represents. This mode also supports drag - * and drop of items. - * - * The mode can be changed by a toggle button located on the left side of - * the navigator. - * - * The URL navigator also remembers the URL history and allows to go - * back and forward within this history. - */ -class UrlNavigator : public QWidget -{ - Q_OBJECT - -public: - UrlNavigator(KFilePlacesModel* placesModel, const KUrl& url, QWidget* parent); - virtual ~UrlNavigator(); - - /** Returns the current active URL. */ - const KUrl& url() const; - - /** Returns the portion of the current active URL up to the button at index. */ - KUrl url(int index) const; - - /** Returns the amount of items in the history */ - int historySize() const; - - /** Returns the saved position from the history */ - QPoint savedPosition() const; - - /** - * Goes back one step in the URL history. The signals - * UrlNavigator::urlChanged and UrlNavigator::historyChanged - * are submitted. - */ - void goBack(); - - /** - * Goes forward one step in the URL history. The signals - * UrlNavigator::urlChanged and UrlNavigator::historyChanged - * are submitted. - */ - void goForward(); - - /** - * Goes up one step of the URL path. The signals - * UrlNavigator::urlChanged and UrlNavigator::historyChanged - * are submitted. - */ - void goUp(); - - /** - * Goes to the home URL. The signals UrlNavigator::urlChanged - * and UrlNavigator::historyChanged are submitted. - */ - void goHome(); - - /** - * Sets the home URL used by goHome(). - */ - void setHomeUrl(const QString& homeUrl); - - /** - * @return True, if the URL is editable by the user within a line editor. - * If false is returned, each part of the URL is presented by a button - * for fast navigation. - */ - bool isUrlEditable() const; - - /** - * Allows to edit the URL of the navigation bar if \a editable - * is true, and sets the focus accordingly. - * If \a editable is false, each part of - * the URL is presented by a button for a fast navigation. - */ - void setUrlEditable(bool editable); - - /** - * Set the URL navigator to the active mode, if \a active - * is true. The active mode is default. Using the URL navigator - * in the inactive mode is useful when having split views, - * where the inactive view is indicated by an inactive URL - * navigator visually. - */ - void setActive(bool active); - - /** - * Returns true, if the URL navigator is in the active mode. - * @see UrlNavigator::setActive() - */ - bool isActive() const; - - /** - * Sets whether or not to show hidden files in lists - */ - void setShowHiddenFiles( bool show ); - - /** - * Returns true if the URL navigator is set to show hidden files - */ - bool showHiddenFiles() const; // TODO rename, looks like a verb - - /** - * Handles the dropping of the URLs \a urls to the given - * destination \a destination and emits the signal urlsDropped. - */ - void dropUrls(const KUrl::List& urls, - const KUrl& destination); - -public slots: - /** - * Sets the current active URL. - * The signals UrlNavigator::urlChanged and UrlNavigator::historyChanged - * are submitted. - */ - void setUrl(const KUrl& url); - - /** - * Activates the URL navigator (UrlNavigator::isActive() will return true) - * and emits the signal 'activationChanged()'. - */ - void requestActivation(); - - /** - * Stores the coordinates of the contents into - * the current history element. - */ - void storeContentsPosition(int x, int y); - -signals: - /** - * Is emitted, if the URL navigator has been activated by - * a user interaction. - */ - void activated(); - - /** - * Is emitted, if the URL has been changed e. g. by - * the user. - * @see setUrl() - */ - void urlChanged(const KUrl& url); - - /** - * Is emitted, if the history has been changed. Usually - * the history is changed if a new URL has been selected. - */ - void historyChanged(); - - /** - * Is emitted if the URLs \a urls have been dropped - * to the destination \a destination. - */ - void urlsDropped(const KUrl::List& urls, - const KUrl& destination); - -protected: - /** - * If the Escape key is pressed, the navigation bar should switch - * to the browse mode. - */ - virtual void keyReleaseEvent(QKeyEvent* event); - - /** - * Paste the clipboard content as URL, if the middle mouse - * button has been clicked. - */ - virtual void mouseReleaseEvent(QMouseEvent* event); - -private: - Q_PRIVATE_SLOT(d, void slotReturnPressed(const QString& text)) - Q_PRIVATE_SLOT(d, void slotRemoteHostActivated()) - Q_PRIVATE_SLOT(d, void slotProtocolChanged(const QString& protocol)) - Q_PRIVATE_SLOT(d, void switchView()) - //Q_PRIVATE_SLOT(d, void slotRedirection(const KUrl&, const KUrl&)) - -private: - class Private; - Private* const d; - - Q_DISABLE_COPY( UrlNavigator ) -}; - -#endif diff --git a/src/urlnavigatorbutton.cpp b/src/urlnavigatorbutton.cpp deleted file mode 100644 index 2925ed350..000000000 --- a/src/urlnavigatorbutton.cpp +++ /dev/null @@ -1,361 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * - * Copyright (C) 2006 by Aaron J. Seigo () * - * * - * 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) any later version. * - * * - * 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, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - -#include "urlnavigatorbutton.h" - -#include - -#include "urlnavigator.h" - -#include -#include -#include -#include - -#include -#include -#include - -UrlNavigatorButton::UrlNavigatorButton(int index, UrlNavigator* parent) : - UrlButton(parent), - m_index(-1), - m_popupDelay(0), - m_listJob(0) -{ - setAcceptDrops(true); - setMinimumWidth(arrowWidth()); - setIndex(index); - connect(this, SIGNAL(clicked()), this, SLOT(updateNavigatorUrl())); - - m_popupDelay = new QTimer(this); - m_popupDelay->setSingleShot(true); - connect(m_popupDelay, SIGNAL(timeout()), this, SLOT(startListJob())); - connect(this, SIGNAL(pressed()), this, SLOT(startPopupDelay())); -} - -UrlNavigatorButton::~UrlNavigatorButton() -{ -} - -void UrlNavigatorButton::setIndex(int index) -{ - m_index = index; - - if (m_index < 0) { - return; - } - - QString path(urlNavigator()->url().pathOrUrl()); - setText(path.section('/', index, index)); - - // Check whether the button indicates the full path of the Url. If - // this is the case, the button is marked as 'active'. - ++index; - QFont adjustedFont(font()); - if (path.section('/', index, index).isEmpty()) { - setDisplayHintEnabled(ActivatedHint, true); - adjustedFont.setBold(true); - } - else { - setDisplayHintEnabled(ActivatedHint, false); - adjustedFont.setBold(false); - } - - setFont(adjustedFont); - update(); -} - -QSize UrlNavigatorButton::sizeHint() const -{ - const int width = fontMetrics().width(text()) + (arrowWidth() * 4); - return QSize(width, UrlButton::sizeHint().height()); -} - -void UrlNavigatorButton::paintEvent(QPaintEvent* event) -{ - QPainter painter(this); - painter.setClipRect(event->rect()); - const int buttonWidth = width(); - const int buttonHeight = height(); - - QColor backgroundColor; - QColor foregroundColor; - const bool isHighlighted = isDisplayHintEnabled(EnteredHint) || - isDisplayHintEnabled(DraggedHint) || - isDisplayHintEnabled(PopupActiveHint); - if (isHighlighted) { - backgroundColor = KGlobalSettings::highlightColor(); - foregroundColor = KGlobalSettings::highlightedTextColor(); - } - else { - backgroundColor = palette().brush(QPalette::Background).color(); - foregroundColor = KGlobalSettings::buttonTextColor(); - } - - // dimm the colors if the parent view does not have the focus - const bool isActive = urlNavigator()->isActive(); - if (!isActive) { - QColor dimmColor(palette().brush(QPalette::Background).color()); - foregroundColor = mixColors(foregroundColor, dimmColor); - if (isHighlighted) { - backgroundColor = mixColors(backgroundColor, dimmColor); - } - } - - // draw button background - painter.setPen(Qt::NoPen); - painter.setBrush(backgroundColor); - painter.drawRect(0, 0, buttonWidth, buttonHeight); - - int textWidth = buttonWidth; - if (isDisplayHintEnabled(ActivatedHint) && isActive || isHighlighted) { - painter.setPen(foregroundColor); - } - else { - // dimm the foreground color by mixing it with the background - foregroundColor = mixColors(foregroundColor, backgroundColor); - painter.setPen(foregroundColor); - } - - if (!isDisplayHintEnabled(ActivatedHint)) { - // draw arrow - const int border = 2; // horizontal border - const int middleY = height() / 2; - const int width = arrowWidth(); - const int startX = (buttonWidth - width) - (2 * border); - const int startTopY = middleY - (width - 1); - const int startBottomY = middleY + (width - 1); - for (int i = 0; i < width; ++i) { - painter.drawLine(startX, startTopY + i, startX + i, startTopY + i); - painter.drawLine(startX, startBottomY - i, startX + i, startBottomY - i); - } - - textWidth = startX - border; - } - - const bool clipped = isTextClipped(); - const int align = clipped ? Qt::AlignVCenter : Qt::AlignCenter; - const QRect textRect(0, 0, textWidth, buttonHeight); - if (clipped) { - QLinearGradient gradient(textRect.topLeft(), textRect.topRight()); - gradient.setColorAt(0.8, foregroundColor); - gradient.setColorAt(1.0, backgroundColor); - - QPen pen; - pen.setBrush(QBrush(gradient)); - painter.setPen(pen); - painter.drawText(textRect, align, text()); - } - else { - painter.drawText(textRect, align, text()); - } -} - -void UrlNavigatorButton::enterEvent(QEvent* event) -{ - UrlButton::enterEvent(event); - - // if the text is clipped due to a small window width, the text should - // be shown as tooltip - if (isTextClipped()) { - setToolTip(text()); - } -} - -void UrlNavigatorButton::leaveEvent(QEvent* event) -{ - UrlButton::leaveEvent(event); - setToolTip(QString()); -} - -void UrlNavigatorButton::dropEvent(QDropEvent* event) -{ - if (m_index < 0) { - return; - } - - const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData()); - if (!urls.isEmpty()) { - event->acceptProposedAction(); - - setDisplayHintEnabled(DraggedHint, true); - - QString path(urlNavigator()->url().prettyUrl()); - path = path.section('/', 0, m_index + 2); - - urlNavigator()->dropUrls(urls, KUrl(path)); - - setDisplayHintEnabled(DraggedHint, false); - update(); - } -} - -void UrlNavigatorButton::dragEnterEvent(QDragEnterEvent* event) -{ - if (event->mimeData()->hasUrls()) { - setDisplayHintEnabled(DraggedHint, true); - event->acceptProposedAction(); - - update(); - } -} - -void UrlNavigatorButton::dragLeaveEvent(QDragLeaveEvent* event) -{ - UrlButton::dragLeaveEvent(event); - - setDisplayHintEnabled(DraggedHint, false); - update(); -} - - -void UrlNavigatorButton::updateNavigatorUrl() -{ - stopPopupDelay(); - - if (m_index < 0) { - return; - } - - urlNavigator()->setUrl(urlNavigator()->url(m_index)); -} - -void UrlNavigatorButton::startPopupDelay() -{ - if (m_popupDelay->isActive() || (m_listJob != 0) || (m_index < 0)) { - return; - } - - m_popupDelay->start(300); -} - -void UrlNavigatorButton::stopPopupDelay() -{ - m_popupDelay->stop(); - if (m_listJob != 0) { - m_listJob->kill(); - m_listJob = 0; - } -} - -void UrlNavigatorButton::startListJob() -{ - if (m_listJob != 0) { - return; - } - - const KUrl& url = urlNavigator()->url(m_index); - m_listJob = KIO::listDir(url, false, urlNavigator()->showHiddenFiles()); - m_subdirs.clear(); // just to be ++safe - - connect(m_listJob, SIGNAL(entries(KIO::Job*, const KIO::UDSEntryList &)), - this, SLOT(entriesList(KIO::Job*, const KIO::UDSEntryList&))); - connect(m_listJob, SIGNAL(result(KJob*)), this, SLOT(listJobFinished(KJob*))); -} - -void UrlNavigatorButton::entriesList(KIO::Job* job, const KIO::UDSEntryList& entries) -{ - if (job != m_listJob) { - return; - } - - KIO::UDSEntryList::const_iterator it = entries.constBegin(); - KIO::UDSEntryList::const_iterator itEnd = entries.constEnd(); - - bool showHidden = urlNavigator()->showHiddenFiles(); - while (it != itEnd) { - const KIO::UDSEntry entry = *it; - if (entry.isDir()) { - QString name = entry.stringValue(KIO::UDS_NAME); - - if (!showHidden || (name != "." && name != "..")) { - m_subdirs.append(name); - } - } - - ++it; - } - - m_subdirs.sort(); -} - -void UrlNavigatorButton::listJobFinished(KJob* job) -{ - if (job != m_listJob) { - return; - } - - if (job->error() || m_subdirs.isEmpty()) { - // clear listing - return; - } - - setDisplayHintEnabled(PopupActiveHint, true); - update(); // ensure the button is drawn highlighted - - KMenu* dirsMenu = new KMenu(this); - QStringList::const_iterator it = m_subdirs.constBegin(); - QStringList::const_iterator itEnd = m_subdirs.constEnd(); - int i = 0; - while (it != itEnd) { - QAction* action = new QAction(*it, this); - action->setData(i); - dirsMenu->addAction(action); - ++it; - ++i; - } - - const QAction* action = dirsMenu->exec(urlNavigator()->mapToGlobal(geometry().bottomLeft())); - if (action != 0) { - const int result = action->data().toInt(); - KUrl url = urlNavigator()->url(m_index); - url.addPath(m_subdirs[result]); - urlNavigator()->setUrl(url); - } - - m_listJob = 0; - m_subdirs.clear(); - delete dirsMenu; - dirsMenu = 0; - - setDisplayHintEnabled(PopupActiveHint, false); -} - -int UrlNavigatorButton::arrowWidth() const -{ - int width = (height() / 2) - 7; - if (width < 4) { - width = 4; - } - return width; -} - -bool UrlNavigatorButton::isTextClipped() const -{ - int availableWidth = width(); - if (!isDisplayHintEnabled(ActivatedHint)) { - availableWidth -= arrowWidth() + 1; - } - - QFontMetrics fontMetrics(font()); - return fontMetrics.width(text()) >= availableWidth; -} - -#include "urlnavigatorbutton.moc" diff --git a/src/urlnavigatorbutton.h b/src/urlnavigatorbutton.h deleted file mode 100644 index 335001be2..000000000 --- a/src/urlnavigatorbutton.h +++ /dev/null @@ -1,86 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * - * Copyright (C) 2006 by Aaron J. Seigo () * - * * - * 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) any later version. * - * * - * 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, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - -#ifndef URLNAVIGATORBUTTON_H -#define URLNAVIGATORBUTTON_H - -#include -#include "urlbutton.h" - -class KJob; -class KUrl; -class UrlNavigator; -class QPainter; -class QPaintEvent; - -namespace KIO -{ - class Job; -} - -/** - * @brief Button of the URL navigator which contains one part of an URL. - * - * It is possible to drop a various number of items to an UrlNavigatorButton. In this case - * a context menu is opened where the user must select whether he wants - * to copy, move or link the dropped items to the URL part indicated by - * the button. - */ -class UrlNavigatorButton : public UrlButton -{ - Q_OBJECT - -public: - explicit UrlNavigatorButton(int index, UrlNavigator* parent); - virtual ~UrlNavigatorButton(); - void setIndex(int index); - int index() const { return m_index; } - - /** @see QWidget::sizeHint() */ - virtual QSize sizeHint() const; - -protected: - virtual void paintEvent(QPaintEvent* event); - virtual void enterEvent(QEvent* event); - virtual void leaveEvent(QEvent* event); - virtual void dropEvent(QDropEvent* event); - virtual void dragEnterEvent(QDragEnterEvent* event); - virtual void dragLeaveEvent(QDragLeaveEvent* event); - -private slots: - void updateNavigatorUrl(); - void startPopupDelay(); - void stopPopupDelay(); - void startListJob(); - void entriesList(KIO::Job* job, const KIO::UDSEntryList& entries); - void listJobFinished(KJob* job); - -private: - int arrowWidth() const; - bool isTextClipped() const; - -private: - int m_index; - QTimer* m_popupDelay; - KIO::Job* m_listJob; - QStringList m_subdirs; -}; - -#endif -- cgit v1.3