diff options
| author | Kevin Ottens <[email protected]> | 2007-04-02 20:08:14 +0000 |
|---|---|---|
| committer | Kevin Ottens <[email protected]> | 2007-04-02 20:08:14 +0000 |
| commit | b94f306f56c52733bcecf1730a7ee654de2806ae (patch) | |
| tree | 50df5e113e980ffb6a8795d8e179f5901a85c460 /src/kurlnavigator.cpp | |
| parent | 72e83bb42ab8bf9c54fbb866371aa0a6f26872f2 (diff) | |
Places and url navigator are now provided by kfile. Port Dolphin to this
change.
svn path=/trunk/KDE/kdebase/apps/; revision=649541
Diffstat (limited to 'src/kurlnavigator.cpp')
| -rw-r--r-- | src/kurlnavigator.cpp | 823 |
1 files changed, 0 insertions, 823 deletions
diff --git a/src/kurlnavigator.cpp b/src/kurlnavigator.cpp deleted file mode 100644 index 2d2cd8cf2..000000000 --- a/src/kurlnavigator.cpp +++ /dev/null @@ -1,823 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Peter Penz (<[email protected]>) * - * Copyright (C) 2006 by Aaron J. Seigo (<[email protected]>) * - * Copyright (C) 2006 by Patrice Tremblay * - * Copyright (C) 2007 by Kevin Ottens ([email protected]) * - * * - * 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 <assert.h> - -#include <kfileitem.h> -#include <kicon.h> -#include <klocale.h> -#include <kprotocolinfo.h> -#include <kurlcombobox.h> -#include <kurlcompletion.h> - -#include <QApplication> -#include <QClipboard> -#include <QDir> -#include <QHBoxLayout> -#include <QLabel> -#include <QLineEdit> -#include <QLinkedList> -#include <QMouseEvent> -#include <QToolButton> - -/** - * @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<HistoryElem> m_history; - QToolButton* m_toggleButton; - KFilePlacesSelector* m_placesSelector; - KUrlComboBox* m_pathBox; - KProtocolCombo* m_protocols; - QLabel* m_protocolSeparator; - QLineEdit* m_host; - QLinkedList<KUrlNavigatorButton*> 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 <[email protected]> - // Copyright (C) 2001 Joseph Wenninger <[email protected]> - // Copyright (C) 2001 Anders Lund <[email protected]> - - 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<KUrlNavigatorButton*>::const_iterator it = m_navButtons.begin(); - const QLinkedList<KUrlNavigatorButton*>::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://[email protected]/var/lib" writes - // "fish://[email protected]" 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<KUrlNavigatorButton*>::iterator it = m_navButtons.begin(); - const QLinkedList<KUrlNavigatorButton*>::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<KUrlNavigatorButton*>::iterator itBegin = it; - while (it != itEnd) { - (*it)->close(); - (*it)->deleteLater(); - ++it; - } - m_navButtons.erase(itBegin, m_navButtons.end()); -} - -void KUrlNavigator::Private::deleteButtons() -{ - QLinkedList<KUrlNavigatorButton*>::iterator itBegin = m_navButtons.begin(); - QLinkedList<KUrlNavigatorButton*>::iterator itEnd = m_navButtons.end(); - QLinkedList<KUrlNavigatorButton*>::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<KUrlNavigator::HistoryElem> 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" |
