]>
cloud.milkyroute.net Git - dolphin.git/blob - src/urlnavigatorbutton.cpp
1 /***************************************************************************
2 * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) *
3 * Copyright (C) 2006 by Aaron J. Seigo (<aseigo@kde.org>) *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
19 ***************************************************************************/
21 #include "urlnavigatorbutton.h"
23 #include <qfontmetrics.h>
29 #include <QDragLeaveEvent>
30 #include <Q3PopupMenu>
32 #include <QDragEnterEvent>
34 #include <kglobalsettings.h>
35 #include <kiconloader.h>
36 #include <kio/jobclasses.h>
41 #include "urlnavigator.h"
42 #include "dolphinview.h"
43 #include "dolphinmainwindow.h"
45 UrlNavigatorButton::UrlNavigatorButton(int index
, UrlNavigator
* parent
) :
51 setMinimumWidth(arrowWidth());
53 connect(this, SIGNAL(clicked()), this, SLOT(updateNavigatorUrl()));
55 m_popupDelay
= new QTimer(this);
56 connect(m_popupDelay
, SIGNAL(timeout()), this, SLOT(startListJob()));
57 connect(this, SIGNAL(pressed()), this, SLOT(startPopupDelay()));
60 UrlNavigatorButton::~UrlNavigatorButton()
64 void UrlNavigatorButton::setIndex(int index
)
72 QString
path(urlNavigator()->url().pathOrUrl());
73 setText(path
.section('/', index
, index
));
75 // Check whether the button indicates the full path of the Url. If
76 // this is the case, the button is marked as 'active'.
78 QFont
adjustedFont(font());
79 if (path
.section('/', index
, index
).isEmpty()) {
80 setDisplayHintEnabled(ActivatedHint
, true);
81 adjustedFont
.setBold(true);
84 setDisplayHintEnabled(ActivatedHint
, false);
85 adjustedFont
.setBold(false);
88 setFont(adjustedFont
);
92 QSize
UrlNavigatorButton::sizeHint() const
94 const int width
= fontMetrics().width(text()) + (arrowWidth() * 4);
95 return QSize(width
, UrlButton::sizeHint().height());
98 void UrlNavigatorButton::paintEvent(QPaintEvent
* event
)
100 QPainter
painter(this);
101 painter
.setClipRect(event
->rect());
102 const int buttonWidth
= width();
103 const int buttonHeight
= height();
105 QColor backgroundColor
;
106 QColor foregroundColor
;
107 const bool isHighlighted
= isDisplayHintEnabled(EnteredHint
) ||
108 isDisplayHintEnabled(DraggedHint
) ||
109 isDisplayHintEnabled(PopupActiveHint
);
111 backgroundColor
= KGlobalSettings::highlightColor();
112 foregroundColor
= KGlobalSettings::highlightedTextColor();
115 backgroundColor
= palette().brush(QPalette::Background
).color();
116 foregroundColor
= KGlobalSettings::buttonTextColor();
119 // dimm the colors if the parent view does not have the focus
120 const DolphinView
* parentView
= urlNavigator()->dolphinView();
121 const DolphinMainWindow
* dolphin
= parentView
->mainWindow();
123 const bool isActive
= (dolphin
->activeView() == parentView
);
125 QColor
dimmColor(palette().brush(QPalette::Background
).color());
126 foregroundColor
= mixColors(foregroundColor
, dimmColor
);
128 backgroundColor
= mixColors(backgroundColor
, dimmColor
);
132 // draw button background
133 painter
.setPen(Qt::NoPen
);
134 painter
.setBrush(backgroundColor
);
135 painter
.drawRect(0, 0, buttonWidth
, buttonHeight
);
137 int textWidth
= buttonWidth
;
138 if (isDisplayHintEnabled(ActivatedHint
) && isActive
|| isHighlighted
) {
139 painter
.setPen(foregroundColor
);
142 // dimm the foreground color by mixing it with the background
143 foregroundColor
= mixColors(foregroundColor
, backgroundColor
);
144 painter
.setPen(foregroundColor
);
147 if (!isDisplayHintEnabled(ActivatedHint
)) {
149 const int border
= 2; // horizontal border
150 const int middleY
= height() / 2;
151 const int width
= arrowWidth();
152 const int startX
= (buttonWidth
- width
) - (2 * border
);
153 const int startTopY
= middleY
- (width
- 1);
154 const int startBottomY
= middleY
+ (width
- 1);
155 for (int i
= 0; i
< width
; ++i
) {
156 painter
.drawLine(startX
, startTopY
+ i
, startX
+ i
, startTopY
+ i
);
157 painter
.drawLine(startX
, startBottomY
- i
, startX
+ i
, startBottomY
- i
);
160 textWidth
= startX
- border
;
163 const bool clipped
= isTextClipped();
164 const int align
= clipped
? Qt::AlignVCenter
: Qt::AlignCenter
;
165 painter
.drawText(QRect(0, 0, textWidth
, buttonHeight
), align
, text());
168 // Blend the right area of the text with the background, as the
170 // TODO: use alpha blending in Qt4 instead of drawing the text that often
171 const int blendSteps
= 16;
173 QColor
blendColor(backgroundColor
);
174 const int redInc
= (foregroundColor
.red() - backgroundColor
.red()) / blendSteps
;
175 const int greenInc
= (foregroundColor
.green() - backgroundColor
.green()) / blendSteps
;
176 const int blueInc
= (foregroundColor
.blue() - backgroundColor
.blue()) / blendSteps
;
177 for (int i
= 0; i
< blendSteps
; ++i
) {
178 painter
.setClipRect(QRect(textWidth
- i
, 0, 1, buttonHeight
));
179 painter
.setPen(blendColor
);
180 painter
.drawText(QRect(0, 0, textWidth
, buttonHeight
), align
, text());
182 blendColor
.setRgb(blendColor
.red() + redInc
,
183 blendColor
.green() + greenInc
,
184 blendColor
.blue() + blueInc
);
189 void UrlNavigatorButton::enterEvent(QEvent
* event
)
191 UrlButton::enterEvent(event
);
193 // if the text is clipped due to a small window width, the text should
194 // be shown as tooltip
195 if (isTextClipped()) {
200 void UrlNavigatorButton::leaveEvent(QEvent
* event
)
202 UrlButton::leaveEvent(event
);
203 setToolTip(QString());
206 void UrlNavigatorButton::dropEvent(QDropEvent
* event
)
212 const KUrl::List urls
= KUrl::List::fromMimeData(event
->mimeData());
213 if (!urls
.isEmpty()) {
214 event
->acceptProposedAction();
216 setDisplayHintEnabled(DraggedHint
, true);
218 QString
path(urlNavigator()->url().prettyUrl());
219 path
= path
.section('/', 0, m_index
+ 2);
221 DolphinMainWindow
* win
= urlNavigator()->dolphinView()->mainWindow();
222 win
->dropUrls(urls
, KUrl(path
));
224 setDisplayHintEnabled(DraggedHint
, false);
229 void UrlNavigatorButton::dragEnterEvent(QDragEnterEvent
* event
)
231 if (event
->mimeData()->hasUrls()) {
232 setDisplayHintEnabled(DraggedHint
, true);
233 event
->acceptProposedAction();
239 void UrlNavigatorButton::dragLeaveEvent(QDragLeaveEvent
* event
)
241 UrlButton::dragLeaveEvent(event
);
243 setDisplayHintEnabled(DraggedHint
, false);
248 void UrlNavigatorButton::updateNavigatorUrl()
254 UrlNavigator
* navigator
= urlNavigator();
255 assert(navigator
!= 0);
256 navigator
->setUrl(navigator
->url(m_index
));
259 void UrlNavigatorButton::startPopupDelay()
261 if (m_popupDelay
->isActive() || m_listJob
|| m_index
< 0) {
265 m_popupDelay
->setSingleShot(true);
266 m_popupDelay
->start(300);
269 void UrlNavigatorButton::stopPopupDelay()
271 m_popupDelay
->stop();
278 void UrlNavigatorButton::startListJob()
284 KUrl url
= urlNavigator()->url(m_index
);
285 m_listJob
= KIO::listDir(url
, false, false);
286 m_subdirs
.clear(); // just to be ++safe
288 connect(m_listJob
, SIGNAL(entries(KIO::Job
*, const KIO::UDSEntryList
&)),
289 this, SLOT(entriesList(KIO::Job
*, const KIO::UDSEntryList
&)));
290 connect(m_listJob
, SIGNAL(result(KJob
*)), this, SLOT(listJobFinished(KJob
*)));
293 void UrlNavigatorButton::entriesList(KIO::Job
* job
, const KIO::UDSEntryList
& entries
)
295 if (job
!= m_listJob
) {
299 KIO::UDSEntryList::const_iterator it
= entries
.constBegin();
300 KIO::UDSEntryList::const_iterator itEnd
= entries
.constEnd();
301 while (it
!= itEnd
) {
304 KIO::UDSEntry entry
= *it
;
307 KIO::UDSEntry::const_iterator atomIt = entry.constBegin();
308 KIO::UDSEntry::const_iterator atomEndIt = entry.constEnd();
310 while (atomIt != atomEndIt) {
311 switch ((*atomIt).m_uds) {
313 name = (*atomIt).m_str;
315 case KIO::UDS_FILE_TYPE:
316 isDir = S_ISDIR((*atomIt).m_long);
324 m_subdirs.append(name);
329 m_subdirs
.append(entry
.stringValue(KIO::UDS_NAME
));
338 void UrlNavigatorButton::listJobFinished(KJob
* job
)
340 if (job
!= m_listJob
) {
344 if (job
->error() || m_subdirs
.isEmpty()) {
349 setDisplayHintEnabled(PopupActiveHint
, true);
350 update(); // ensure the button is drawn highlighted
351 Q3PopupMenu
* dirsMenu
= new Q3PopupMenu(this);
353 QStringList::const_iterator it
= m_subdirs
.constBegin();
354 QStringList::const_iterator itEnd
= m_subdirs
.constEnd();
356 while (it
!= itEnd
) {
357 dirsMenu
->insertItem(*it
, i
);
362 int result
= dirsMenu
->exec(urlNavigator()->mapToGlobal(geometry().bottomLeft()));
365 KUrl url
= urlNavigator()->url(m_index
);
366 url
.addPath(m_subdirs
[result
]);
367 urlNavigator()->setUrl(url
);
373 setDisplayHintEnabled(PopupActiveHint
, false);
376 int UrlNavigatorButton::arrowWidth() const
378 int width
= (height() / 2) - 7;
385 bool UrlNavigatorButton::isTextClipped() const
387 int availableWidth
= width();
388 if (!isDisplayHintEnabled(ActivatedHint
)) {
389 availableWidth
-= arrowWidth() + 1;
392 QFontMetrics
fontMetrics(font());
393 return fontMetrics
.width(text()) >= availableWidth
;
396 #include "urlnavigatorbutton.moc"