]>
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"
24 #include "bookmarkselector.h"
25 #include "dolphinsettings.h"
26 #include "generalsettings.h"
27 #include "protocolcombo.h"
28 #include "urlnavigatorbutton.h"
32 #include <kfileitem.h>
34 #include <kprotocolinfo.h>
35 #include <kurlcombobox.h>
36 #include <kurlcompletion.h>
43 UrlNavigator::HistoryElem::HistoryElem() :
51 UrlNavigator::HistoryElem::HistoryElem(const KUrl
& url
) :
59 UrlNavigator::HistoryElem::~HistoryElem()
63 UrlNavigator::UrlNavigator(const KUrl
& url
,
69 m_protocolSeparator(0),
72 m_history
.prepend(HistoryElem(url
));
74 QFontMetrics
fontMetrics(font());
75 setMinimumHeight(fontMetrics
.height() + 8);
77 m_toggleButton
= new QCheckBox(this);
78 //m_toggleButton->setFlat(true);
79 //m_toggleButton->setToggleButton(true);
80 m_toggleButton
->setFocusPolicy(Qt::NoFocus
);
81 m_toggleButton
->setMinimumHeight(minimumHeight());
82 connect(m_toggleButton
, SIGNAL(clicked()),
83 this, SLOT(slotClicked()));
84 if (DolphinSettings::instance().generalSettings()->editableUrl()) {
85 m_toggleButton
->toggle();
88 m_bookmarkSelector
= new BookmarkSelector(this);
89 connect(m_bookmarkSelector
, SIGNAL(bookmarkActivated(const KUrl
&)),
90 this, SLOT(setUrl(const KUrl
&)));
92 m_pathBox
= new KUrlComboBox(KUrlComboBox::Directories
, true, this);
94 KUrlCompletion
* kurlCompletion
= new KUrlCompletion(KUrlCompletion::DirCompletion
);
95 m_pathBox
->setCompletionObject(kurlCompletion
);
96 m_pathBox
->setAutoDeleteCompletionObject(true);
98 connect(m_pathBox
, SIGNAL(returnPressed(const QString
&)),
99 this, SLOT(slotReturnPressed(const QString
&)));
100 connect(m_pathBox
, SIGNAL(urlActivated(const KUrl
&)),
101 this, SLOT(slotUrlActivated(const KUrl
&)));
103 //connect(dolphinView, SIGNAL(redirection(const KUrl&, const KUrl&)),
104 // this, SLOT(slotRedirection(const KUrl&, const KUrl&)));
108 UrlNavigator::~UrlNavigator()
112 const KUrl
& UrlNavigator::url() const
114 assert(!m_history
.empty());
115 QLinkedList
<HistoryElem
>::const_iterator it
= m_history
.begin();
116 it
+= m_historyIndex
;
120 KUrl
UrlNavigator::url(int index
) const
123 QString
path(url().pathOrUrl());
124 path
= path
.section('/', 0, index
);
126 if ( path
.length() >= 1 && path
.at(path
.length()-1) != '/')
134 const QLinkedList
<UrlNavigator::HistoryElem
>& UrlNavigator::history(int& index
) const
136 index
= m_historyIndex
;
140 void UrlNavigator::goBack()
144 const int count
= m_history
.count();
145 if (m_historyIndex
< count
- 1) {
148 emit
urlChanged(url());
149 emit
historyChanged();
153 void UrlNavigator::goForward()
155 if (m_historyIndex
> 0) {
158 emit
urlChanged(url());
159 emit
historyChanged();
163 void UrlNavigator::goUp()
165 setUrl(url().upUrl());
168 void UrlNavigator::goHome()
170 setUrl(DolphinSettings::instance().generalSettings()->homeUrl());
173 void UrlNavigator::setUrlEditable(bool editable
)
175 if (isUrlEditable() != editable
) {
176 m_toggleButton
->toggle();
181 bool UrlNavigator::isUrlEditable() const
183 return m_toggleButton
->isChecked();
186 void UrlNavigator::editUrl(bool editOrBrowse
)
188 setUrlEditable(editOrBrowse
);
192 m_pathBox
->setFocus();
196 void UrlNavigator::setActive(bool active
)
198 if (active
!= m_active
) {
207 void UrlNavigator::dropUrls(const KUrl::List
& urls
,
208 const KUrl
& destination
)
210 kDebug() << "------------------- URLS dropped" << endl
;
211 emit
urlsDropped(urls
, destination
);
214 void UrlNavigator::setUrl(const KUrl
& url
)
216 QString
urlStr(url
.pathOrUrl());
217 //kDebug() << "setUrl(" << url << ")" << endl;
218 if ( urlStr
.length() > 0 && urlStr
.at(0) == '~') {
219 // replace '~' by the home directory
221 urlStr
.insert(0, QDir::home().path());
224 const KUrl
transformedUrl(urlStr
);
226 if (m_historyIndex
> 0) {
227 // Check whether the previous element of the history has the same Url.
228 // If yes, just go forward instead of inserting a duplicate history
230 QLinkedList
<HistoryElem
>::const_iterator it
= m_history
.begin();
231 it
+= m_historyIndex
- 1;
232 const KUrl
& nextUrl
= (*it
).url();
233 if (transformedUrl
== nextUrl
) {
235 // kDebug() << "goin' forward in history" << endl;
240 QLinkedList
<HistoryElem
>::iterator it
= m_history
.begin() + m_historyIndex
;
241 const KUrl
& currUrl
= (*it
).url();
242 if (currUrl
== transformedUrl
) {
243 // don't insert duplicate history elements
244 // kDebug() << "currUrl == transformedUrl" << endl;
249 m_history
.insert(it
, HistoryElem(transformedUrl
));
253 emit
urlChanged(transformedUrl
);
254 emit
historyChanged();
256 // Prevent an endless growing of the history: remembering
257 // the last 100 Urls should be enough...
258 if (m_historyIndex
> 100) {
259 m_history
.erase(m_history
.begin());
263 /* kDebug() << "history starting ====================" << endl;
265 for (QValueListIterator<UrlNavigator::HistoryElem> it = m_history.begin();
266 it != m_history.end();
269 kDebug() << i << ": " << (*it).url() << endl;
271 kDebug() << "history done ========================" << endl;*/
276 void UrlNavigator::requestActivation()
278 kDebug() << "--------------------------- request activation" << endl
;
282 void UrlNavigator::storeContentsPosition(int x
, int y
)
284 QLinkedList
<HistoryElem
>::iterator it
= m_history
.begin() + m_historyIndex
;
285 (*it
).setContentsX(x
);
286 (*it
).setContentsY(y
);
289 void UrlNavigator::keyReleaseEvent(QKeyEvent
* event
)
291 KHBox::keyReleaseEvent(event
);
292 if (isUrlEditable() && (event
->key() == Qt::Key_Escape
)) {
293 setUrlEditable(false);
297 void UrlNavigator::slotReturnPressed(const QString
& text
)
299 // Parts of the following code have been taken
300 // from the class KateFileSelector located in
301 // kate/app/katefileselector.hpp of Kate.
302 // Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
303 // Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
304 // Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
307 if (typedUrl
.hasPass()) {
308 typedUrl
.setPass(QString::null
);
311 QStringList urls
= m_pathBox
->urls();
312 urls
.removeAll(typedUrl
.url());
313 urls
.prepend(typedUrl
.url());
314 m_pathBox
->setUrls(urls
, KUrlComboBox::RemoveBottom
);
317 // The Url might have been adjusted by UrlNavigator::setUrl(), hence
318 // synchronize the result in the path box.
319 m_pathBox
->setUrl(url());
322 void UrlNavigator::slotUrlActivated(const KUrl
& url
)
327 void UrlNavigator::slotRemoteHostActivated()
331 QString host
= m_host
->text();
334 int marker
= host
.indexOf("@");
337 user
= host
.left(marker
);
339 host
= host
.right(host
.length() - marker
- 1);
342 marker
= host
.indexOf("/");
345 u
.setPath(host
.right(host
.length() - marker
));
346 host
.truncate(marker
);
353 if (m_protocols
->currentProtocol() != u
.protocol() ||
357 u
.setProtocol(m_protocols
->currentProtocol());
358 u
.setHost(m_host
->text());
360 //TODO: get rid of this HACK for file:///!
361 if (u
.protocol() == "file")
364 if (u
.path().isEmpty())
374 void UrlNavigator::slotProtocolChanged(const QString
& protocol
)
377 url
.setProtocol(protocol
);
378 //url.setPath(KProtocolInfo::protocolClass(protocol) == ":local" ? "/" : "");
380 QLinkedList
<QWidget
*>::const_iterator it
= m_navButtons
.begin();
381 const QLinkedList
<QWidget
*>::const_iterator itEnd
= m_navButtons
.end();
382 while (it
!= itEnd
) {
384 (*it
)->deleteLater();
387 m_navButtons
.clear();
389 if (KProtocolInfo::protocolClass(protocol
) == ":local") {
394 m_protocolSeparator
= new QLabel("://", this);
395 m_host
= new QLineEdit(this);
397 connect(m_host
, SIGNAL(lostFocus()),
398 this, SLOT(slotRemoteHostActivated()));
399 connect(m_host
, SIGNAL(returnPressed()),
400 this, SLOT(slotRemoteHostActivated()));
405 m_protocolSeparator
->show();
411 void UrlNavigator::slotRedirection(const KUrl
& oldUrl
, const KUrl
& newUrl
)
413 // kDebug() << "received redirection to " << newUrl << endl;
414 kDebug() << "received redirection from " << oldUrl
<< " to " << newUrl
<< endl
;
415 /* UrlStack::iterator it = m_urls.find(oldUrl);
416 if (it != m_urls.end())
418 m_urls.erase(++it, m_urls.end());
421 m_urls.append(newUrl);*/
424 void UrlNavigator::slotClicked()
426 if (isUrlEditable()) {
427 m_pathBox
->setFocus();
431 setUrl(m_pathBox
->currentText());
432 emit
requestActivation();
436 void UrlNavigator::updateHistoryElem()
438 assert(m_historyIndex
>= 0);
439 const KFileItem
* item
= 0; // TODO: m_dolphinView->currentFileItem();
441 QLinkedList
<HistoryElem
>::iterator it
= m_history
.begin() + m_historyIndex
;
442 (*it
).setCurrentFileName(item
->name());
446 void UrlNavigator::updateContent()
448 // delete all existing Url navigator buttons
449 QLinkedList
<QWidget
*>::const_iterator it
= m_navButtons
.begin();
450 const QLinkedList
<QWidget
*>::const_iterator itEnd
= m_navButtons
.end();
451 while (it
!= itEnd
) {
453 (*it
)->deleteLater();
456 m_navButtons
.clear();
458 m_bookmarkSelector
->updateSelection(url());
460 m_toggleButton
->setToolTip(QString());
461 QString
path(url().pathOrUrl());
463 // TODO: prevent accessing the DolphinMainWindow out from this scope
464 //const QAction* action = dolphinView()->mainWindow()->actionCollection()->action("editable_location");
465 // TODO: registry of default shortcuts
466 //QString shortcut = action? action->shortcut().toString() : "Ctrl+L";
467 const QString shortcut
= "Ctrl+L";
469 if (m_toggleButton
->isChecked()) {
470 delete m_protocols
; m_protocols
= 0;
471 delete m_protocolSeparator
; m_protocolSeparator
= 0;
472 delete m_host
; m_host
= 0;
474 m_toggleButton
->setToolTip(i18n("Browse (%1, Escape)", shortcut
));
476 setSizePolicy(QSizePolicy::Minimum
, QSizePolicy::Fixed
);
478 m_pathBox
->setUrl(url());
481 m_toggleButton
->setToolTip(i18n("Edit location (%1)", shortcut
));
483 setSizePolicy(QSizePolicy::Fixed
, QSizePolicy::Fixed
);
487 // get the data from the currently selected bookmark
488 KBookmark bookmark
= m_bookmarkSelector
->selectedBookmark();
489 //int bookmarkIndex = m_bookmarkSelector->selectedIndex();
491 QString bookmarkPath
;
492 if (bookmark
.isNull()) {
493 // No bookmark is a part of the current Url.
494 // The following code tries to guess the bookmark
495 // path. E. g. "fish://root@192.168.0.2/var/lib" writes
496 // "fish://root@192.168.0.2" to 'bookmarkPath', which leads to the
497 // navigation indication 'Custom Path > var > lib".
498 int idx
= path
.indexOf(QString("//"));
499 idx
= path
.indexOf("/", (idx
< 0) ? 0 : idx
+ 2);
500 bookmarkPath
= (idx
< 0) ? path
: path
.left(idx
);
503 bookmarkPath
= bookmark
.url().pathOrUrl();
505 const uint len
= bookmarkPath
.length();
507 // calculate the start point for the Url navigator buttons by counting
508 // the slashs inside the bookmark Url
510 for (uint i
= 0; i
< len
; ++i
) {
511 if (bookmarkPath
.at(i
) == QChar('/')) {
515 if ((len
> 0) && bookmarkPath
.at(len
- 1) == QChar('/')) {
516 assert(slashCount
> 0);
520 if (!url().isLocalFile() && bookmark
.isNull()) {
521 QString protocol
= url().protocol();
523 m_protocols
= new ProtocolCombo(protocol
, this);
524 connect(m_protocols
, SIGNAL(activated(const QString
&)),
525 this, SLOT(slotProtocolChanged(const QString
&)));
528 m_protocols
->setProtocol(protocol
);
532 if (KProtocolInfo::protocolClass(protocol
) != ":local")
534 QString hostText
= url().host();
536 if (!url().user().isEmpty())
538 hostText
= url().user() + "@" + hostText
;
542 m_protocolSeparator
= new QLabel("://", this);
543 m_host
= new QLineEdit(hostText
, this);
545 connect(m_host
, SIGNAL(lostFocus()),
546 this, SLOT(slotRemoteHostActivated()));
547 connect(m_host
, SIGNAL(returnPressed()),
548 this, SLOT(slotRemoteHostActivated()));
551 m_host
->setText(hostText
);
553 m_protocolSeparator
->show();
557 delete m_protocolSeparator
; m_protocolSeparator
= 0;
558 delete m_host
; m_host
= 0;
561 else if (m_protocols
) {
565 m_protocolSeparator
->hide();
570 // create Url navigator buttons
571 int idx
= slashCount
;
574 dir_name
= path
.section('/', idx
, idx
);
575 const bool isFirstButton
= (idx
== slashCount
);
576 hasNext
= isFirstButton
|| !dir_name
.isEmpty();
578 UrlNavigatorButton
* button
= new UrlNavigatorButton(idx
, this);
580 // the first Url navigator button should get the name of the
581 // bookmark instead of the directory name
582 QString text
= bookmark
.text();
583 if (text
.isEmpty()) {
584 if (url().isLocalFile())
586 text
= i18n("Custom Path");
595 button
->setText(text
);
598 m_navButtons
.append(button
);
605 #include "urlnavigator.moc"