]>
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 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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>
52 #include "bookmarkselector.h"
54 #include "dolphinsettings.h"
55 #include "dolphinstatusbar.h"
56 #include "dolphinview.h"
57 #include "generalsettings.h"
58 #include "protocolcombo.h"
59 #include "urlnavigatorbutton.h"
61 URLNavigator::HistoryElem::HistoryElem()
69 URLNavigator::HistoryElem::HistoryElem(const KUrl
& url
)
77 URLNavigator::HistoryElem::~HistoryElem()
81 URLNavigator::URLNavigator(const KUrl
& url
,
82 DolphinView
* dolphinView
) :
85 m_dolphinView(dolphinView
),
87 m_protocolSeparator(0),
90 m_history
.prepend(HistoryElem(url
));
92 QFontMetrics
fontMetrics(font());
93 setMinimumHeight(fontMetrics
.height() + 8);
95 m_toggleButton
= new QCheckBox(this);
96 //m_toggleButton->setFlat(true);
97 //m_toggleButton->setToggleButton(true);
98 m_toggleButton
->setFocusPolicy(Qt::NoFocus
);
99 m_toggleButton
->setMinimumHeight(minimumHeight());
100 connect(m_toggleButton
, SIGNAL(clicked()),
101 this, SLOT(slotClicked()));
102 if (DolphinSettings::instance().generalSettings()->editableURL()) {
103 m_toggleButton
->toggle();
106 m_bookmarkSelector
= new BookmarkSelector(this);
107 connect(m_bookmarkSelector
, SIGNAL(bookmarkActivated(int)),
108 this, SLOT(slotBookmarkActivated(int)));
110 m_pathBox
= new KUrlComboBox(KUrlComboBox::Directories
, true, this);
112 KUrlCompletion
* kurlCompletion
= new KUrlCompletion(KUrlCompletion::DirCompletion
);
113 m_pathBox
->setCompletionObject(kurlCompletion
);
114 m_pathBox
->setAutoDeleteCompletionObject(true);
116 connect(m_pathBox
, SIGNAL(returnPressed(const QString
&)),
117 this, SLOT(slotReturnPressed(const QString
&)));
118 connect(m_pathBox
, SIGNAL(urlActivated(const KUrl
&)),
119 this, SLOT(slotURLActivated(const KUrl
&)));
121 connect(dolphinView
, SIGNAL(contentsMoved(int, int)),
122 this, SLOT(slotContentsMoved(int, int)));
123 connect(dolphinView
, SIGNAL(redirection(const KUrl
&, const KUrl
&)),
124 this, SLOT(slotRedirection(const KUrl
&, const KUrl
&)));
125 /* connect(dolphinView, SIGNAL(redirection(const KUrl&)),
126 this, SLOT(slotRedirection(const KUrl&)));*/
130 URLNavigator::~URLNavigator()
134 void URLNavigator::setURL(const KUrl
& url
)
136 QString
urlStr(url
.pathOrUrl());
137 //kdDebug() << "setURL(" << url << ")" << endl;
138 if (urlStr
.at(0) == '~') {
139 // replace '~' by the home directory
141 urlStr
.insert(0, QDir::home().path());
144 const KUrl
transformedURL(urlStr
);
146 if (m_historyIndex
> 0) {
147 // Check whether the previous element of the history has the same URL.
148 // If yes, just go forward instead of inserting a duplicate history
150 const KUrl
& nextURL
= m_history
[m_historyIndex
- 1].url();
151 if (transformedURL
== nextURL
) {
153 // kdDebug() << "goin' forward in history" << endl;
158 const KUrl
& currURL
= m_history
[m_historyIndex
].url();
159 if (currURL
== transformedURL
) {
160 // don't insert duplicate history elements
161 // kdDebug() << "currURL == transformedURL" << endl;
167 const Q3ValueListIterator
<URLNavigator::HistoryElem
> it
= m_history
.at(m_historyIndex
);
168 m_history
.insert(it
, HistoryElem(transformedURL
));
172 emit
urlChanged(transformedURL
);
173 emit
historyChanged();
175 // Prevent an endless growing of the history: remembering
176 // the last 100 URLs should be enough...
177 if (m_historyIndex
> 100) {
178 m_history
.erase(m_history
.begin());
182 /* kdDebug() << "history starting ====================" << endl;
184 for (QValueListIterator<URLNavigator::HistoryElem> it = m_history.begin();
185 it != m_history.end();
188 kdDebug() << i << ": " << (*it).url() << endl;
190 kdDebug() << "history done ========================" << endl;*/
193 const KUrl
& URLNavigator::url() const
195 assert(!m_history
.empty());
196 return m_history
[m_historyIndex
].url();
199 KUrl
URLNavigator::url(int index
) const
202 QString
path(url().pathOrUrl());
203 path
= path
.section('/', 0, index
);
205 if (path
.at(path
.length()) != '/')
213 const Q3ValueList
<URLNavigator::HistoryElem
>& URLNavigator::history(int& index
) const
215 index
= m_historyIndex
;
219 void URLNavigator::goBack()
223 const int count
= m_history
.count();
224 if (m_historyIndex
< count
- 1) {
227 emit
urlChanged(url());
228 emit
historyChanged();
232 void URLNavigator::goForward()
234 if (m_historyIndex
> 0) {
237 emit
urlChanged(url());
238 emit
historyChanged();
242 void URLNavigator::goUp()
244 setURL(url().upUrl());
247 void URLNavigator::goHome()
249 setURL(DolphinSettings::instance().generalSettings()->homeURL());
252 void URLNavigator::setURLEditable(bool editable
)
254 if (isURLEditable() != editable
) {
255 m_toggleButton
->toggle();
260 bool URLNavigator::isURLEditable() const
262 return m_toggleButton
->isChecked();
265 void URLNavigator::editURL(bool editOrBrowse
)
267 setURLEditable(editOrBrowse
);
271 m_pathBox
->setFocus();
275 DolphinView
* URLNavigator::dolphinView() const
277 return m_dolphinView
;
280 void URLNavigator::keyReleaseEvent(QKeyEvent
* event
)
282 Q3HBox::keyReleaseEvent(event
);
283 if (isURLEditable() && (event
->key() == Qt::Key_Escape
)) {
284 setURLEditable(false);
288 void URLNavigator::slotReturnPressed(const QString
& text
)
290 // Parts of the following code have been taken
291 // from the class KateFileSelector located in
292 // kate/app/katefileselector.hpp of Kate.
293 // Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
294 // Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
295 // Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
298 if (typedURL
.hasPass()) {
299 typedURL
.setPass(QString::null
);
302 QStringList urls
= m_pathBox
->urls();
303 urls
.remove(typedURL
.url());
304 urls
.prepend(typedURL
.url());
305 m_pathBox
->setUrls(urls
, KUrlComboBox::RemoveBottom
);
308 // The URL might have been adjusted by URLNavigator::setURL(), hence
309 // synchronize the result in the path box.
310 m_pathBox
->setUrl(url());
313 void URLNavigator::slotURLActivated(const KUrl
& url
)
318 void URLNavigator::slotRemoteHostActivated()
322 QString host
= m_host
->text();
325 int marker
= host
.find("@");
328 user
= host
.left(marker
);
330 host
= host
.right(host
.length() - marker
- 1);
333 marker
= host
.find("/");
336 u
.setPath(host
.right(host
.length() - marker
));
337 host
.truncate(marker
);
344 if (m_protocols
->currentProtocol() != u
.protocol() ||
348 u
.setProtocol(m_protocols
->currentProtocol());
349 u
.setHost(m_host
->text());
351 //TODO: get rid of this HACK for file:///!
352 if (u
.protocol() == "file")
355 if (u
.path().isEmpty())
365 void URLNavigator::slotProtocolChanged(const QString
& protocol
)
368 url
.setProtocol(protocol
);
369 //url.setPath(KProtocolInfo::protocolClass(protocol) == ":local" ? "/" : "");
371 Q3ValueList
<QWidget
*>::const_iterator it
= m_navButtons
.constBegin();
372 while (it
!= m_navButtons
.constEnd()) {
374 (*it
)->deleteLater();
377 m_navButtons
.clear();
379 if (KProtocolInfo::protocolClass(protocol
) == ":local") {
384 m_protocolSeparator
= new QLabel("://", this);
385 m_host
= new QLineEdit(this);
387 connect(m_host
, SIGNAL(lostFocus()),
388 this, SLOT(slotRemoteHostActivated()));
389 connect(m_host
, SIGNAL(returnPressed()),
390 this, SLOT(slotRemoteHostActivated()));
395 m_protocolSeparator
->show();
401 void URLNavigator::slotRequestActivation()
403 m_dolphinView
->requestActivation();
406 void URLNavigator::slotBookmarkActivated(int index
)
408 m_dolphinView
->statusBar()->clear();
409 m_dolphinView
->requestActivation();
411 KBookmark bookmark
= DolphinSettings::instance().bookmark(index
);
412 m_dolphinView
->setURL(bookmark
.url());
415 void URLNavigator::slotRedirection(const KUrl
& oldUrl
, const KUrl
& newUrl
)
417 // kdDebug() << "received redirection to " << newUrl << endl;
418 kdDebug() << "received redirection from " << oldUrl
<< " to " << newUrl
<< endl
;
419 /* UrlStack::iterator it = m_urls.find(oldUrl);
420 if (it != m_urls.end())
422 m_urls.erase(++it, m_urls.end());
425 m_urls.append(newUrl);*/
428 void URLNavigator::slotContentsMoved(int x
, int y
)
430 m_history
[m_historyIndex
].setContentsX(x
);
431 m_history
[m_historyIndex
].setContentsY(y
);
434 void URLNavigator::slotClicked()
436 if (isURLEditable()) {
437 m_pathBox
->setFocus();
441 setURL(m_pathBox
->currentText());
442 m_dolphinView
->setFocus();
446 void URLNavigator::updateHistoryElem()
448 assert(m_historyIndex
>= 0);
449 const KFileItem
* item
= m_dolphinView
->currentFileItem();
451 m_history
[m_historyIndex
].setCurrentFileName(item
->name());
453 m_history
[m_historyIndex
].setContentsX(m_dolphinView
->contentsX());
454 m_history
[m_historyIndex
].setContentsY(m_dolphinView
->contentsY());
457 void URLNavigator::updateContent()
459 // delete all existing URL navigator buttons
460 Q3ValueList
<QWidget
*>::const_iterator it
= m_navButtons
.constBegin();
461 while (it
!= m_navButtons
.constEnd()) {
463 (*it
)->deleteLater();
466 m_navButtons
.clear();
468 m_bookmarkSelector
->updateSelection(url());
470 QToolTip::remove(m_toggleButton
);
471 QString
path(url().pathOrUrl());
472 const KAction
* action
= Dolphin::mainWin().actionCollection()->action("editable_location");
473 // TODO: registry of default shortcuts
474 QString shortcut
= action
? action
->shortcutText() : "Ctrl+L";
475 if (m_toggleButton
->isChecked()) {
476 delete m_protocols
; m_protocols
= 0;
477 delete m_protocolSeparator
; m_protocolSeparator
= 0;
478 delete m_host
; m_host
= 0;
480 QToolTip::add(m_toggleButton
, i18n("Browse (%1, Escape)").arg(shortcut
));
482 setSizePolicy(QSizePolicy::Minimum
, QSizePolicy::Fixed
);
484 m_pathBox
->setUrl(url());
487 QToolTip::add(m_toggleButton
, i18n("Edit location (%1)").arg(shortcut
));
489 setSizePolicy(QSizePolicy::Fixed
, QSizePolicy::Fixed
);
493 // get the data from the currently selected bookmark
494 KBookmark bookmark
= m_bookmarkSelector
->selectedBookmark();
495 //int bookmarkIndex = m_bookmarkSelector->selectedIndex();
497 QString bookmarkPath
;
498 if (bookmark
.isNull()) {
499 // No bookmark is a part of the current URL.
500 // The following code tries to guess the bookmark
501 // path. E. g. "fish://root@192.168.0.2/var/lib" writes
502 // "fish://root@192.168.0.2" to 'bookmarkPath', which leads to the
503 // navigation indication 'Custom Path > var > lib".
504 int idx
= path
.find(QString("//"));
505 idx
= path
.find("/", (idx
< 0) ? 0 : idx
+ 2);
506 bookmarkPath
= (idx
< 0) ? path
: path
.left(idx
);
509 bookmarkPath
= bookmark
.url().pathOrUrl();
511 const uint len
= bookmarkPath
.length();
513 // calculate the start point for the URL navigator buttons by counting
514 // the slashs inside the bookmark URL
516 for (uint i
= 0; i
< len
; ++i
) {
517 if (bookmarkPath
.at(i
) == QChar('/')) {
521 if ((len
> 0) && bookmarkPath
.at(len
- 1) == QChar('/')) {
522 assert(slashCount
> 0);
526 if (!url().isLocalFile() && bookmark
.isNull()) {
527 QString protocol
= url().protocol();
529 m_protocols
= new ProtocolCombo(protocol
, this);
530 connect(m_protocols
, SIGNAL(activated(const QString
&)),
531 this, SLOT(slotProtocolChanged(const QString
&)));
534 m_protocols
->setProtocol(protocol
);
538 if (KProtocolInfo::protocolClass(protocol
) != ":local")
540 QString hostText
= url().host();
542 if (!url().user().isEmpty())
544 hostText
= url().user() + "@" + hostText
;
548 m_protocolSeparator
= new QLabel("://", this);
549 m_host
= new QLineEdit(hostText
, this);
551 connect(m_host
, SIGNAL(lostFocus()),
552 this, SLOT(slotRemoteHostActivated()));
553 connect(m_host
, SIGNAL(returnPressed()),
554 this, SLOT(slotRemoteHostActivated()));
557 m_host
->setText(hostText
);
559 m_protocolSeparator
->show();
563 delete m_protocolSeparator
; m_protocolSeparator
= 0;
564 delete m_host
; m_host
= 0;
567 else if (m_protocols
) {
571 m_protocolSeparator
->hide();
576 // create URL navigator buttons
577 int idx
= slashCount
;
580 dir_name
= path
.section('/', idx
, idx
);
581 const bool isFirstButton
= (idx
== slashCount
);
582 hasNext
= isFirstButton
|| !dir_name
.isEmpty();
584 URLNavigatorButton
* button
= new URLNavigatorButton(idx
, this);
586 // the first URL navigator button should get the name of the
587 // bookmark instead of the directory name
588 QString text
= bookmark
.text();
589 if (text
.isEmpty()) {
590 if (url().isLocalFile())
592 text
= i18n("Custom Path");
601 button
->setText(text
);
604 m_navButtons
.append(button
);
611 #include "urlnavigator.moc"