]>
cloud.milkyroute.net Git - dolphin.git/blob - src/urlnavigator.cpp
1 /***************************************************************************
2 * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) *
3 * Copyright (C) 2006 by Aaron J. Seigo (<aseigo@kde.org>) *
4 * Copyright (C) 2006 by Patrice Tremblay *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20 ***************************************************************************/
22 #include "urlnavigator.h"
26 #include <qcombobox.h>
29 #include <q3listbox.h>
30 #include <qlineedit.h>
32 #include <q3popupmenu.h>
33 #include <qpushbutton.h>
34 #include <qsizepolicy.h>
37 #include <Q3ValueList>
42 #include <kactioncollection.h>
43 #include <kiconloader.h>
46 #include <kprotocolinfo.h>
48 #include <kurlcombobox.h>
49 #include <kurlcompletion.h>
50 #include <kbookmarkmanager.h>
53 #include "bookmarkselector.h"
54 #include "dolphinmainwindow.h"
55 #include "dolphinsettings.h"
56 #include "dolphinstatusbar.h"
57 #include "dolphinview.h"
58 #include "generalsettings.h"
59 #include "protocolcombo.h"
60 #include "urlnavigatorbutton.h"
62 UrlNavigator::HistoryElem::HistoryElem()
70 UrlNavigator::HistoryElem::HistoryElem(const KUrl
& url
)
78 UrlNavigator::HistoryElem::~HistoryElem()
82 UrlNavigator::UrlNavigator(const KUrl
& url
,
83 DolphinView
* dolphinView
) :
86 m_dolphinView(dolphinView
),
88 m_protocolSeparator(0),
91 m_history
.prepend(HistoryElem(url
));
93 QFontMetrics
fontMetrics(font());
94 setMinimumHeight(fontMetrics
.height() + 8);
96 m_toggleButton
= new QCheckBox(this);
97 //m_toggleButton->setFlat(true);
98 //m_toggleButton->setToggleButton(true);
99 m_toggleButton
->setFocusPolicy(Qt::NoFocus
);
100 m_toggleButton
->setMinimumHeight(minimumHeight());
101 connect(m_toggleButton
, SIGNAL(clicked()),
102 this, SLOT(slotClicked()));
103 if (DolphinSettings::instance().generalSettings()->editableUrl()) {
104 m_toggleButton
->toggle();
107 m_bookmarkSelector
= new BookmarkSelector(this);
108 connect(m_bookmarkSelector
, SIGNAL(bookmarkActivated(int)),
109 this, SLOT(slotBookmarkActivated(int)));
111 m_pathBox
= new KUrlComboBox(KUrlComboBox::Directories
, true, this);
113 KUrlCompletion
* kurlCompletion
= new KUrlCompletion(KUrlCompletion::DirCompletion
);
114 m_pathBox
->setCompletionObject(kurlCompletion
);
115 m_pathBox
->setAutoDeleteCompletionObject(true);
117 connect(m_pathBox
, SIGNAL(returnPressed(const QString
&)),
118 this, SLOT(slotReturnPressed(const QString
&)));
119 connect(m_pathBox
, SIGNAL(urlActivated(const KUrl
&)),
120 this, SLOT(slotUrlActivated(const KUrl
&)));
122 connect(dolphinView
, SIGNAL(contentsMoved(int, int)),
123 this, SLOT(slotContentsMoved(int, int)));
124 connect(dolphinView
, SIGNAL(redirection(const KUrl
&, const KUrl
&)),
125 this, SLOT(slotRedirection(const KUrl
&, const KUrl
&)));
126 /* connect(dolphinView, SIGNAL(redirection(const KUrl&)),
127 this, SLOT(slotRedirection(const KUrl&)));*/
131 UrlNavigator::~UrlNavigator()
135 void UrlNavigator::setUrl(const KUrl
& url
)
137 QString
urlStr(url
.pathOrUrl());
138 //kDebug() << "setUrl(" << url << ")" << endl;
139 if ( urlStr
.length() > 0 && urlStr
.at(0) == '~') {
140 // replace '~' by the home directory
142 urlStr
.insert(0, QDir::home().path());
145 const KUrl
transformedUrl(urlStr
);
147 if (m_historyIndex
> 0) {
148 // Check whether the previous element of the history has the same Url.
149 // If yes, just go forward instead of inserting a duplicate history
151 const KUrl
& nextUrl
= m_history
[m_historyIndex
- 1].url();
152 if (transformedUrl
== nextUrl
) {
154 // kDebug() << "goin' forward in history" << endl;
159 const KUrl
& currUrl
= m_history
[m_historyIndex
].url();
160 if (currUrl
== transformedUrl
) {
161 // don't insert duplicate history elements
162 // kDebug() << "currUrl == transformedUrl" << endl;
168 const Q3ValueListIterator
<UrlNavigator::HistoryElem
> it
= m_history
.at(m_historyIndex
);
169 m_history
.insert(it
, HistoryElem(transformedUrl
));
173 emit
urlChanged(transformedUrl
);
174 emit
historyChanged();
176 // Prevent an endless growing of the history: remembering
177 // the last 100 Urls should be enough...
178 if (m_historyIndex
> 100) {
179 m_history
.erase(m_history
.begin());
183 /* kDebug() << "history starting ====================" << endl;
185 for (QValueListIterator<UrlNavigator::HistoryElem> it = m_history.begin();
186 it != m_history.end();
189 kDebug() << i << ": " << (*it).url() << endl;
191 kDebug() << "history done ========================" << endl;*/
194 const KUrl
& UrlNavigator::url() const
196 assert(!m_history
.empty());
197 return m_history
[m_historyIndex
].url();
200 KUrl
UrlNavigator::url(int index
) const
203 QString
path(url().pathOrUrl());
204 path
= path
.section('/', 0, index
);
206 if ( path
.length() >= 1 && path
.at(path
.length()-1) != '/')
214 const Q3ValueList
<UrlNavigator::HistoryElem
>& UrlNavigator::history(int& index
) const
216 index
= m_historyIndex
;
220 void UrlNavigator::goBack()
224 const int count
= m_history
.count();
225 if (m_historyIndex
< count
- 1) {
228 emit
urlChanged(url());
229 emit
historyChanged();
233 void UrlNavigator::goForward()
235 if (m_historyIndex
> 0) {
238 emit
urlChanged(url());
239 emit
historyChanged();
243 void UrlNavigator::goUp()
245 setUrl(url().upUrl());
248 void UrlNavigator::goHome()
250 setUrl(DolphinSettings::instance().generalSettings()->homeUrl());
253 void UrlNavigator::setUrlEditable(bool editable
)
255 if (isUrlEditable() != editable
) {
256 m_toggleButton
->toggle();
261 bool UrlNavigator::isUrlEditable() const
263 return m_toggleButton
->isChecked();
266 void UrlNavigator::editUrl(bool editOrBrowse
)
268 setUrlEditable(editOrBrowse
);
272 m_pathBox
->setFocus();
276 DolphinView
* UrlNavigator::dolphinView() const
278 return m_dolphinView
;
281 void UrlNavigator::keyReleaseEvent(QKeyEvent
* event
)
283 KHBox::keyReleaseEvent(event
);
284 if (isUrlEditable() && (event
->key() == Qt::Key_Escape
)) {
285 setUrlEditable(false);
289 void UrlNavigator::slotReturnPressed(const QString
& text
)
291 // Parts of the following code have been taken
292 // from the class KateFileSelector located in
293 // kate/app/katefileselector.hpp of Kate.
294 // Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
295 // Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
296 // Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
299 if (typedUrl
.hasPass()) {
300 typedUrl
.setPass(QString::null
);
303 QStringList urls
= m_pathBox
->urls();
304 urls
.removeAll(typedUrl
.url());
305 urls
.prepend(typedUrl
.url());
306 m_pathBox
->setUrls(urls
, KUrlComboBox::RemoveBottom
);
309 // The Url might have been adjusted by UrlNavigator::setUrl(), hence
310 // synchronize the result in the path box.
311 m_pathBox
->setUrl(url());
314 void UrlNavigator::slotUrlActivated(const KUrl
& url
)
319 void UrlNavigator::slotRemoteHostActivated()
323 QString host
= m_host
->text();
326 int marker
= host
.indexOf("@");
329 user
= host
.left(marker
);
331 host
= host
.right(host
.length() - marker
- 1);
334 marker
= host
.indexOf("/");
337 u
.setPath(host
.right(host
.length() - marker
));
338 host
.truncate(marker
);
345 if (m_protocols
->currentProtocol() != u
.protocol() ||
349 u
.setProtocol(m_protocols
->currentProtocol());
350 u
.setHost(m_host
->text());
352 //TODO: get rid of this HACK for file:///!
353 if (u
.protocol() == "file")
356 if (u
.path().isEmpty())
366 void UrlNavigator::slotProtocolChanged(const QString
& protocol
)
369 url
.setProtocol(protocol
);
370 //url.setPath(KProtocolInfo::protocolClass(protocol) == ":local" ? "/" : "");
372 Q3ValueList
<QWidget
*>::const_iterator it
= m_navButtons
.constBegin();
373 while (it
!= m_navButtons
.constEnd()) {
375 (*it
)->deleteLater();
378 m_navButtons
.clear();
380 if (KProtocolInfo::protocolClass(protocol
) == ":local") {
385 m_protocolSeparator
= new QLabel("://", this);
386 m_host
= new QLineEdit(this);
388 connect(m_host
, SIGNAL(lostFocus()),
389 this, SLOT(slotRemoteHostActivated()));
390 connect(m_host
, SIGNAL(returnPressed()),
391 this, SLOT(slotRemoteHostActivated()));
396 m_protocolSeparator
->show();
402 void UrlNavigator::slotRequestActivation()
404 m_dolphinView
->requestActivation();
407 void UrlNavigator::slotBookmarkActivated(int index
)
409 m_dolphinView
->statusBar()->clear();
410 m_dolphinView
->requestActivation();
412 KBookmark bookmark
= DolphinSettings::instance().bookmark(index
);
413 m_dolphinView
->setUrl(bookmark
.url());
416 void UrlNavigator::slotRedirection(const KUrl
& oldUrl
, const KUrl
& newUrl
)
418 // kDebug() << "received redirection to " << newUrl << endl;
419 kDebug() << "received redirection from " << oldUrl
<< " to " << newUrl
<< endl
;
420 /* UrlStack::iterator it = m_urls.find(oldUrl);
421 if (it != m_urls.end())
423 m_urls.erase(++it, m_urls.end());
426 m_urls.append(newUrl);*/
429 void UrlNavigator::slotContentsMoved(int x
, int y
)
431 m_history
[m_historyIndex
].setContentsX(x
);
432 m_history
[m_historyIndex
].setContentsY(y
);
435 void UrlNavigator::slotClicked()
437 if (isUrlEditable()) {
438 m_pathBox
->setFocus();
442 setUrl(m_pathBox
->currentText());
443 m_dolphinView
->setFocus();
447 void UrlNavigator::updateHistoryElem()
449 assert(m_historyIndex
>= 0);
450 const KFileItem
* item
= 0; // TODO: m_dolphinView->currentFileItem();
452 m_history
[m_historyIndex
].setCurrentFileName(item
->name());
454 m_history
[m_historyIndex
].setContentsX(m_dolphinView
->contentsX());
455 m_history
[m_historyIndex
].setContentsY(m_dolphinView
->contentsY());
458 void UrlNavigator::updateContent()
460 // delete all existing Url navigator buttons
461 Q3ValueList
<QWidget
*>::const_iterator it
= m_navButtons
.constBegin();
462 while (it
!= m_navButtons
.constEnd()) {
464 (*it
)->deleteLater();
467 m_navButtons
.clear();
469 m_bookmarkSelector
->updateSelection(url());
471 m_toggleButton
->setToolTip(QString());
472 QString
path(url().pathOrUrl());
473 const QAction
* action
= dolphinView()->mainWindow()->actionCollection()->action("editable_location");
474 // TODO: registry of default shortcuts
475 QString shortcut
= action
? action
->shortcut().toString() : "Ctrl+L";
476 if (m_toggleButton
->isChecked()) {
477 delete m_protocols
; m_protocols
= 0;
478 delete m_protocolSeparator
; m_protocolSeparator
= 0;
479 delete m_host
; m_host
= 0;
481 m_toggleButton
->setToolTip(i18n("Browse (%1, Escape)",shortcut
));
483 setSizePolicy(QSizePolicy::Minimum
, QSizePolicy::Fixed
);
485 m_pathBox
->setUrl(url());
488 m_toggleButton
->setToolTip(i18n("Edit location (%1)",shortcut
));
490 setSizePolicy(QSizePolicy::Fixed
, QSizePolicy::Fixed
);
494 // get the data from the currently selected bookmark
495 KBookmark bookmark
= m_bookmarkSelector
->selectedBookmark();
496 //int bookmarkIndex = m_bookmarkSelector->selectedIndex();
498 QString bookmarkPath
;
499 if (bookmark
.isNull()) {
500 // No bookmark is a part of the current Url.
501 // The following code tries to guess the bookmark
502 // path. E. g. "fish://root@192.168.0.2/var/lib" writes
503 // "fish://root@192.168.0.2" to 'bookmarkPath', which leads to the
504 // navigation indication 'Custom Path > var > lib".
505 int idx
= path
.indexOf(QString("//"));
506 idx
= path
.indexOf("/", (idx
< 0) ? 0 : idx
+ 2);
507 bookmarkPath
= (idx
< 0) ? path
: path
.left(idx
);
510 bookmarkPath
= bookmark
.url().pathOrUrl();
512 const uint len
= bookmarkPath
.length();
514 // calculate the start point for the Url navigator buttons by counting
515 // the slashs inside the bookmark Url
517 for (uint i
= 0; i
< len
; ++i
) {
518 if (bookmarkPath
.at(i
) == QChar('/')) {
522 if ((len
> 0) && bookmarkPath
.at(len
- 1) == QChar('/')) {
523 assert(slashCount
> 0);
527 if (!url().isLocalFile() && bookmark
.isNull()) {
528 QString protocol
= url().protocol();
530 m_protocols
= new ProtocolCombo(protocol
, this);
531 connect(m_protocols
, SIGNAL(activated(const QString
&)),
532 this, SLOT(slotProtocolChanged(const QString
&)));
535 m_protocols
->setProtocol(protocol
);
539 if (KProtocolInfo::protocolClass(protocol
) != ":local")
541 QString hostText
= url().host();
543 if (!url().user().isEmpty())
545 hostText
= url().user() + "@" + hostText
;
549 m_protocolSeparator
= new QLabel("://", this);
550 m_host
= new QLineEdit(hostText
, this);
552 connect(m_host
, SIGNAL(lostFocus()),
553 this, SLOT(slotRemoteHostActivated()));
554 connect(m_host
, SIGNAL(returnPressed()),
555 this, SLOT(slotRemoteHostActivated()));
558 m_host
->setText(hostText
);
560 m_protocolSeparator
->show();
564 delete m_protocolSeparator
; m_protocolSeparator
= 0;
565 delete m_host
; m_host
= 0;
568 else if (m_protocols
) {
572 m_protocolSeparator
->hide();
577 // create Url navigator buttons
578 int idx
= slashCount
;
581 dir_name
= path
.section('/', idx
, idx
);
582 const bool isFirstButton
= (idx
== slashCount
);
583 hasNext
= isFirstButton
|| !dir_name
.isEmpty();
585 UrlNavigatorButton
* button
= new UrlNavigatorButton(idx
, this);
587 // the first Url navigator button should get the name of the
588 // bookmark instead of the directory name
589 QString text
= bookmark
.text();
590 if (text
.isEmpty()) {
591 if (url().isLocalFile())
593 text
= i18n("Custom Path");
602 button
->setText(text
);
605 m_navButtons
.append(button
);
612 #include "urlnavigator.moc"