/***************************************************************************
- * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) *
+ * Copyright (C) 2006 by Peter Penz (<peter.penz@gmx.at>) *
* Copyright (C) 2006 by Aaron J. Seigo (<aseigo@kde.org>) *
* Copyright (C) 2006 by Patrice Tremblay *
* *
* 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "urlnavigator.h"
+#include "bookmarkselector.h"
+#include "protocolcombo.h"
+#include "urlnavigatorbutton.h"
+
#include <assert.h>
-#include <qcombobox.h>
-#include <qfont.h>
-#include <qlabel.h>
-#include <q3listbox.h>
-#include <qlineedit.h>
-#include <qobject.h>
-#include <q3popupmenu.h>
-#include <qpushbutton.h>
-#include <qsizepolicy.h>
-#include <qtooltip.h>
-//Added by qt3to4:
-#include <Q3ValueList>
-#include <QKeyEvent>
-#include <QCheckBox>
-
-#include <kaction.h>
-#include <kactioncollection.h>
-#include <kiconloader.h>
-#include <kio/job.h>
+#include <kfileitem.h>
+#include <kicon.h>
#include <klocale.h>
#include <kprotocolinfo.h>
-#include <kurl.h>
#include <kurlcombobox.h>
#include <kurlcompletion.h>
-#include <kbookmarkmanager.h>
-#include <kvbox.h>
-#include "bookmarkselector.h"
-#include "dolphinmainwindow.h"
-#include "dolphinsettings.h"
-#include "dolphinstatusbar.h"
-#include "dolphinview.h"
-#include "generalsettings.h"
-#include "protocolcombo.h"
-#include "urlnavigatorbutton.h"
-
-UrlNavigator::HistoryElem::HistoryElem()
- : m_url(),
+#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)
{
}
-UrlNavigator::HistoryElem::HistoryElem(const KUrl& url)
- : m_url(url),
+HistoryElem::HistoryElem(const KUrl& url) :
+ m_url(url),
m_currentFileName(),
m_contentsX(0),
m_contentsY(0)
{
}
-UrlNavigator::HistoryElem::~HistoryElem()
+HistoryElem::~HistoryElem()
{
}
-UrlNavigator::UrlNavigator(const KUrl& url,
- DolphinView* dolphinView) :
- KHBox(dolphinView),
+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<HistoryElem> m_history;
+ QToolButton* m_toggleButton;
+ BookmarkSelector* m_bookmarkSelector;
+ KUrlComboBox* m_pathBox;
+ ProtocolCombo* m_protocols;
+ QLabel* m_protocolSeparator;
+ QLineEdit* m_host;
+ QLinkedList<UrlNavigatorButton*> 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_dolphinView(dolphinView),
+ m_layout(new QHBoxLayout),
m_protocols(0),
m_protocolSeparator(0),
- m_host(0)
+ m_host(0),
+ m_filler(0),
+ q(q)
{
- m_history.prepend(HistoryElem(url));
-
- QFontMetrics fontMetrics(font());
- setMinimumHeight(fontMetrics.height() + 8);
-
- m_toggleButton = new QCheckBox(this);
- //m_toggleButton->setFlat(true);
- //m_toggleButton->setToggleButton(true);
+ 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(minimumHeight());
+ m_toggleButton->setMinimumHeight(q->minimumHeight());
connect(m_toggleButton, SIGNAL(clicked()),
- this, SLOT(slotClicked()));
- if (DolphinSettings::instance().generalSettings()->editableUrl()) {
- m_toggleButton->toggle();
- }
+ q, SLOT(switchView()));
- m_bookmarkSelector = new BookmarkSelector(this);
- connect(m_bookmarkSelector, SIGNAL(bookmarkActivated(int)),
- this, SLOT(slotBookmarkActivated(int)));
+ // initialize the bookmark selector
+ m_bookmarkSelector = new BookmarkSelector(q, placesModel);
+ connect(m_bookmarkSelector, SIGNAL(placeActivated(const KUrl&)),
+ q, SLOT(setUrl(const KUrl&)));
- m_pathBox = new KUrlComboBox(KUrlComboBox::Directories, true, this);
+ // 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(const QString&)),
- this, SLOT(slotReturnPressed(const QString&)));
- connect(m_pathBox, SIGNAL(urlActivated(const KUrl&)),
- this, SLOT(slotUrlActivated(const KUrl&)));
-
- connect(dolphinView, SIGNAL(contentsMoved(int, int)),
- this, SLOT(slotContentsMoved(int, int)));
- connect(dolphinView, SIGNAL(redirection(const KUrl&, const KUrl&)),
- this, SLOT(slotRedirection(const KUrl&, const KUrl&)));
-/* connect(dolphinView, SIGNAL(redirection(const KUrl&)),
- this, SLOT(slotRedirection(const KUrl&)));*/
- updateContent();
-}
-
-UrlNavigator::~UrlNavigator()
-{
-}
-
-void UrlNavigator::setUrl(const KUrl& url)
-{
- QString urlStr(url.pathOrUrl());
- //kDebug() << "setUrl(" << url << ")" << endl;
- if (urlStr.at(0) == '~') {
- // replace '~' by the home directory
- urlStr.remove(0, 1);
- urlStr.insert(0, QDir::home().path());
- }
-
- const KUrl transformedUrl(urlStr);
-
- if (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.
- const KUrl& nextUrl = m_history[m_historyIndex - 1].url();
- if (transformedUrl == nextUrl) {
- goForward();
-// kDebug() << "goin' forward in history" << endl;
- return;
- }
- }
-
- const KUrl& currUrl = m_history[m_historyIndex].url();
- if (currUrl == transformedUrl) {
- // don't insert duplicate history elements
-// kDebug() << "currUrl == transformedUrl" << endl;
- return;
- }
-
- updateHistoryElem();
-
- const Q3ValueListIterator<UrlNavigator::HistoryElem> it = m_history.at(m_historyIndex);
- m_history.insert(it, HistoryElem(transformedUrl));
-
- updateContent();
-
- emit urlChanged(transformedUrl);
- emit historyChanged();
-
- // Prevent an endless growing of the history: remembering
- // the last 100 Urls should be enough...
- if (m_historyIndex > 100) {
- m_history.erase(m_history.begin());
- --m_historyIndex;
- }
-
-/* kDebug() << "history starting ====================" << endl;
- int i = 0;
- for (QValueListIterator<UrlNavigator::HistoryElem> it = m_history.begin();
- it != m_history.end();
- ++it, ++i)
- {
- kDebug() << i << ": " << (*it).url() << endl;
- }
- kDebug() << "history done ========================" << endl;*/
-}
-
-const KUrl& UrlNavigator::url() const
-{
- assert(!m_history.empty());
- return m_history[m_historyIndex].url();
-}
-
-KUrl UrlNavigator::url(int index) const
-{
- assert(index >= 0);
- QString path(url().pathOrUrl());
- path = path.section('/', 0, index);
-
- if (path.at(path.length()-1) != '/')
- {
- path.append('/');
- }
-
- return path;
-}
-
-const Q3ValueList<UrlNavigator::HistoryElem>& UrlNavigator::history(int& index) const
-{
- index = m_historyIndex;
- return m_history;
-}
-
-void UrlNavigator::goBack()
-{
- updateHistoryElem();
-
- const int count = m_history.count();
- if (m_historyIndex < count - 1) {
- ++m_historyIndex;
- updateContent();
- emit urlChanged(url());
- emit historyChanged();
- }
+ 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::goForward()
+void UrlNavigator::Private::appendWidget(QWidget* widget)
{
- if (m_historyIndex > 0) {
- --m_historyIndex;
- updateContent();
- emit urlChanged(url());
- emit historyChanged();
- }
+ m_layout->insertWidget(m_layout->count() - 1, widget);
}
-void UrlNavigator::goUp()
-{
- setUrl(url().upUrl());
-}
-
-void UrlNavigator::goHome()
-{
- setUrl(DolphinSettings::instance().generalSettings()->homeUrl());
-}
-
-void UrlNavigator::setUrlEditable(bool editable)
-{
- if (isUrlEditable() != editable) {
- m_toggleButton->toggle();
- slotClicked();
- }
-}
-
-bool UrlNavigator::isUrlEditable() const
-{
- return m_toggleButton->isChecked();
-}
-
-void UrlNavigator::editUrl(bool editOrBrowse)
-{
- setUrlEditable(editOrBrowse);
-
- if (editOrBrowse)
- {
- m_pathBox->setFocus();
- }
-}
-
-DolphinView* UrlNavigator::dolphinView() const
-{
- return m_dolphinView;
-}
-
-void UrlNavigator::keyReleaseEvent(QKeyEvent* event)
-{
- KHBox::keyReleaseEvent(event);
- if (isUrlEditable() && (event->key() == Qt::Key_Escape)) {
- setUrlEditable(false);
- }
-}
-
-void UrlNavigator::slotReturnPressed(const QString& text)
+void UrlNavigator::Private::slotReturnPressed(const QString& text)
{
// Parts of the following code have been taken
// from the class KateFileSelector located in
KUrl typedUrl(text);
if (typedUrl.hasPass()) {
- typedUrl.setPass(QString::null);
+ typedUrl.setPass(QString());
}
QStringList urls = m_pathBox->urls();
urls.prepend(typedUrl.url());
m_pathBox->setUrls(urls, KUrlComboBox::RemoveBottom);
- setUrl(typedUrl);
- // The Url might have been adjusted by UrlNavigator::setUrl(), hence
+ q->setUrl(typedUrl);
+ // The URL might have been adjusted by UrlNavigator::setUrl(), hence
// synchronize the result in the path box.
- m_pathBox->setUrl(url());
-}
-
-void UrlNavigator::slotUrlActivated(const KUrl& url)
-{
- setUrl(url);
+ m_pathBox->setUrl(q->url());
}
-void UrlNavigator::slotRemoteHostActivated()
+void UrlNavigator::Private::slotRemoteHostActivated()
{
- KUrl u = url();
+ KUrl u = q->url();
QString host = m_host->text();
QString user;
}
}
- setUrl(u);
+ q->setUrl(u);
}
}
-void UrlNavigator::slotProtocolChanged(const QString& protocol)
+void UrlNavigator::Private::slotProtocolChanged(const QString& protocol)
{
KUrl url;
url.setProtocol(protocol);
//url.setPath(KProtocolInfo::protocolClass(protocol) == ":local" ? "/" : "");
url.setPath("/");
- Q3ValueList<QWidget*>::const_iterator it = m_navButtons.constBegin();
- while (it != m_navButtons.constEnd()) {
+ QLinkedList<UrlNavigatorButton*>::const_iterator it = m_navButtons.begin();
+ const QLinkedList<UrlNavigatorButton*>::const_iterator itEnd = m_navButtons.end();
+ while (it != itEnd) {
(*it)->close();
(*it)->deleteLater();
++it;
m_navButtons.clear();
if (KProtocolInfo::protocolClass(protocol) == ":local") {
- setUrl(url);
+ q->setUrl(url);
}
else {
if (!m_host) {
- m_protocolSeparator = new QLabel("://", this);
- m_host = new QLineEdit(this);
+ m_protocolSeparator = new QLabel("://", q);
+ appendWidget(m_protocolSeparator);
+ m_host = new QLineEdit(q);
+ appendWidget(m_host);
connect(m_host, SIGNAL(lostFocus()),
- this, SLOT(slotRemoteHostActivated()));
+ q, SLOT(slotRemoteHostActivated()));
connect(m_host, SIGNAL(returnPressed()),
- this, SLOT(slotRemoteHostActivated()));
+ q, SLOT(slotRemoteHostActivated()));
}
else {
m_host->setText("");
}
}
-void UrlNavigator::slotRequestActivation()
-{
- m_dolphinView->requestActivation();
-}
-
-void UrlNavigator::slotBookmarkActivated(int index)
-{
- m_dolphinView->statusBar()->clear();
- m_dolphinView->requestActivation();
-
- KBookmark bookmark = DolphinSettings::instance().bookmark(index);
- m_dolphinView->setUrl(bookmark.url());
-}
-
+#if 0
void UrlNavigator::slotRedirection(const KUrl& oldUrl, const KUrl& newUrl)
{
// kDebug() << "received redirection to " << newUrl << endl;
m_urls.append(newUrl);*/
}
+#endif
-void UrlNavigator::slotContentsMoved(int x, int y)
-{
- m_history[m_historyIndex].setContentsX(x);
- m_history[m_historyIndex].setContentsY(y);
-}
-
-void UrlNavigator::slotClicked()
+void UrlNavigator::Private::switchView()
{
- if (isUrlEditable()) {
+ updateContent();
+ if (q->isUrlEditable()) {
m_pathBox->setFocus();
- updateContent();
- }
- else {
- setUrl(m_pathBox->currentText());
- m_dolphinView->setFocus();
+ } else {
+ q->setUrl(m_pathBox->currentText());
}
+ emit q->requestActivation();
}
-void UrlNavigator::updateHistoryElem()
+void UrlNavigator::Private::updateHistoryElem()
{
assert(m_historyIndex >= 0);
- const KFileItem* item = m_dolphinView->currentFileItem();
+ const KFileItem* item = 0; // TODO: m_dolphinView->currentFileItem();
if (item != 0) {
- m_history[m_historyIndex].setCurrentFileName(item->name());
+ HistoryElem& hist = m_history[m_historyIndex];
+ hist.setCurrentFileName(item->name());
}
- m_history[m_historyIndex].setContentsX(m_dolphinView->contentsX());
- m_history[m_historyIndex].setContentsY(m_dolphinView->contentsY());
}
-void UrlNavigator::updateContent()
+void UrlNavigator::Private::updateContent()
{
- // delete all existing Url navigator buttons
- Q3ValueList<QWidget*>::const_iterator it = m_navButtons.constBegin();
- while (it != m_navButtons.constEnd()) {
- (*it)->close();
- (*it)->deleteLater();
- ++it;
- }
- m_navButtons.clear();
-
- m_bookmarkSelector->updateSelection(url());
+ m_bookmarkSelector->updateSelection(q->url());
m_toggleButton->setToolTip(QString());
- QString path(url().pathOrUrl());
- const QAction* action = dolphinView()->mainWindow()->actionCollection()->action("editable_location");
+ 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";
+ //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));
+ m_toggleButton->setToolTip(i18n("Browse (%1, Escape)", shortcut));
- setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+ q->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
m_pathBox->show();
- m_pathBox->setUrl(url());
+ m_pathBox->setUrl(q->url());
}
else {
- m_toggleButton->setToolTip(i18n("Edit location (%1)",shortcut));
+ m_toggleButton->setToolTip(i18n("Edit location (%1)", shortcut));
- setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_pathBox->hide();
- QString dir_name;
+ m_filler->show();
// get the data from the currently selected bookmark
- KBookmark bookmark = m_bookmarkSelector->selectedBookmark();
- //int bookmarkIndex = m_bookmarkSelector->selectedIndex();
+ KUrl placeUrl = m_bookmarkSelector->selectedPlaceUrl();
- QString bookmarkPath;
- if (bookmark.isNull()) {
- // No bookmark is a part of the current Url.
- // The following code tries to guess the bookmark
+ 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 'bookmarkPath', which leads to the
+ // "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);
- bookmarkPath = (idx < 0) ? path : path.left(idx);
+ placePath = (idx < 0) ? path : path.left(idx);
}
else {
- bookmarkPath = bookmark.url().pathOrUrl();
+ placePath = placeUrl.pathOrUrl();
}
- const uint len = bookmarkPath.length();
+ const uint len = placePath.length();
- // calculate the start point for the Url navigator buttons by counting
- // the slashs inside the bookmark Url
+ // 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 (bookmarkPath.at(i) == QChar('/')) {
+ if (placePath.at(i) == QChar('/')) {
++slashCount;
}
}
- if ((len > 0) && bookmarkPath.at(len - 1) == QChar('/')) {
+ if ((len > 0) && placePath.at(len - 1) == QChar('/')) {
assert(slashCount > 0);
--slashCount;
}
- if (!url().isLocalFile() && bookmark.isNull()) {
- QString protocol = url().protocol();
+ const KUrl currentUrl = q->url();
+ if (!currentUrl.isLocalFile() && !placeUrl.isValid()) {
+ QString protocol = currentUrl.protocol();
if (!m_protocols) {
- m_protocols = new ProtocolCombo(protocol, this);
- connect(m_protocols, SIGNAL(activated(const QString&)),
- this, SLOT(slotProtocolChanged(const QString&)));
+ 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 = url().host();
+ if (KProtocolInfo::protocolClass(protocol) != ":local") {
+ QString hostText = currentUrl.host();
- if (!url().user().isEmpty())
- {
- hostText = url().user() + "@" + hostText;
+ if (!currentUrl.user().isEmpty()) {
+ hostText = currentUrl.user() + '@' + hostText;
}
if (!m_host) {
- m_protocolSeparator = new QLabel("://", this);
- m_host = new QLineEdit(hostText, this);
+ // ######### 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()),
- this, SLOT(slotRemoteHostActivated()));
+ q, SLOT(slotRemoteHostActivated()));
connect(m_host, SIGNAL(returnPressed()),
- this, SLOT(slotRemoteHostActivated()));
+ q, SLOT(slotRemoteHostActivated()));
}
else {
m_host->setText(hostText);
}
}
- // create Url navigator buttons
- int idx = slashCount;
- bool hasNext = true;
- do {
- dir_name = path.section('/', idx, idx);
- const bool isFirstButton = (idx == slashCount);
- hasNext = isFirstButton || !dir_name.isEmpty();
- if (hasNext) {
- UrlNavigatorButton* button = new UrlNavigatorButton(idx, this);
- if (isFirstButton) {
- // the first Url navigator button should get the name of the
- // bookmark instead of the directory name
- QString text = bookmark.text();
- if (text.isEmpty()) {
- if (url().isLocalFile())
- {
- text = i18n("Custom Path");
- }
- else
- {
- delete button;
- ++idx;
- continue;
- }
+ updateButtons(path, slashCount);
+ }
+}
+
+void UrlNavigator::Private::updateButtons(const QString& path, int startIndex)
+{
+ QLinkedList<UrlNavigatorButton*>::iterator it = m_navButtons.begin();
+ const QLinkedList<UrlNavigatorButton*>::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;
}
- button->setText(text);
}
+ }
+
+ 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);
- ++idx;
}
- } while (hasNext);
+ else {
+ ++it;
+ }
+ ++idx;
+ }
+ } while (hasNext);
+
+ // delete buttons which are not used anymore
+ QLinkedList<UrlNavigatorButton*>::iterator itBegin = it;
+ while (it != itEnd) {
+ (*it)->close();
+ (*it)->deleteLater();
+ ++it;
+ }
+ m_navButtons.erase(itBegin, m_navButtons.end());
+}
+
+void UrlNavigator::Private::deleteButtons()
+{
+ QLinkedList<UrlNavigatorButton*>::iterator itBegin = m_navButtons.begin();
+ QLinkedList<UrlNavigatorButton*>::iterator itEnd = m_navButtons.end();
+ QLinkedList<UrlNavigatorButton*>::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<UrlNavigator::HistoryElem> 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"