1 /***************************************************************************
2 * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***************************************************************************/
20 #include "dolphincolumnview.h"
22 #include "dolphincontroller.h"
23 #include "dolphinsettings.h"
25 #include "dolphin_columnmodesettings.h"
27 #include <kcolorutils.h>
28 #include <kcolorscheme.h>
29 #include <kdirmodel.h>
30 #include <kdirlister.h>
31 #include <kfileitem.h>
33 #include <QAbstractProxyModel>
37 * Represents one column inside the DolphinColumnView and has been
38 * extended to respect view options and hovering information.
40 class ColumnWidget
: public QListView
43 ColumnWidget(QWidget
* parent
,
44 DolphinColumnView
* columnView
,
46 virtual ~ColumnWidget();
48 /** Sets the size of the icons. */
49 void setDecorationSize(const QSize
& size
);
52 * An active column is defined as column, which shows the same URL
53 * as indicated by the URL navigator. The active column is usually
54 * drawn in a lighter color. All operations are applied to this column.
56 void setActive(bool active
);
58 inline const KUrl
& url() const;
61 virtual QStyleOptionViewItem
viewOptions() const;
62 virtual void dragEnterEvent(QDragEnterEvent
* event
);
63 virtual void dragLeaveEvent(QDragLeaveEvent
* event
);
64 virtual void dragMoveEvent(QDragMoveEvent
* event
);
65 virtual void dropEvent(QDropEvent
* event
);
66 virtual void mousePressEvent(QMouseEvent
* event
);
67 virtual void paintEvent(QPaintEvent
* event
);
68 virtual void contextMenuEvent(QContextMenuEvent
* event
);
71 /** Used by ColumnWidget::setActive(). */
74 /** Used by ColumnWidget::setActive(). */
80 DolphinColumnView
* m_view
;
81 QStyleOptionViewItem m_viewOptions
;
83 bool m_dragging
; // TODO: remove this property when the issue #160611 is solved in Qt 4.4
84 QRect m_dropRect
; // TODO: remove this property when the issue #160611 is solved in Qt 4.4
87 ColumnWidget::ColumnWidget(QWidget
* parent
,
88 DolphinColumnView
* columnView
,
98 setDragDropMode(QAbstractItemView::DragDrop
);
99 setDropIndicatorShown(false);
101 setMouseTracking(true);
102 viewport()->setAttribute(Qt::WA_Hover
);
104 // apply the column mode settings to the widget
105 const ColumnModeSettings
* settings
= DolphinSettings::instance().columnModeSettings();
106 Q_ASSERT(settings
!= 0);
108 m_viewOptions
= QListView::viewOptions();
110 QFont
font(settings
->fontFamily(), settings
->fontSize());
111 font
.setItalic(settings
->italicFont());
112 font
.setBold(settings
->boldFont());
113 m_viewOptions
.font
= font
;
115 const int iconSize
= settings
->iconSize();
116 m_viewOptions
.decorationSize
= QSize(iconSize
, iconSize
);
121 ColumnWidget::~ColumnWidget()
125 void ColumnWidget::setDecorationSize(const QSize
& size
)
127 m_viewOptions
.decorationSize
= size
;
131 void ColumnWidget::setActive(bool active
)
133 if (m_active
== active
) {
146 const KUrl
& ColumnWidget::url() const
151 QStyleOptionViewItem
ColumnWidget::viewOptions() const
153 return m_viewOptions
;
156 void ColumnWidget::dragEnterEvent(QDragEnterEvent
* event
)
158 if (event
->mimeData()->hasUrls()) {
159 event
->acceptProposedAction();
165 void ColumnWidget::dragLeaveEvent(QDragLeaveEvent
* event
)
167 QListView::dragLeaveEvent(event
);
169 // TODO: remove this code when the issue #160611 is solved in Qt 4.4
171 setDirtyRegion(m_dropRect
);
174 void ColumnWidget::dragMoveEvent(QDragMoveEvent
* event
)
176 QListView::dragMoveEvent(event
);
178 // TODO: remove this code when the issue #160611 is solved in Qt 4.4
179 const QModelIndex index
= indexAt(event
->pos());
180 setDirtyRegion(m_dropRect
);
181 m_dropRect
= visualRect(index
);
182 setDirtyRegion(m_dropRect
);
185 void ColumnWidget::dropEvent(QDropEvent
* event
)
187 const KUrl::List urls
= KUrl::List::fromMimeData(event
->mimeData());
188 if (!urls
.isEmpty()) {
189 event
->acceptProposedAction();
190 m_view
->m_controller
->indicateDroppedUrls(urls
,
191 indexAt(event
->pos()),
194 QListView::dropEvent(event
);
198 void ColumnWidget::mousePressEvent(QMouseEvent
* event
)
200 if (m_active
|| indexAt(event
->pos()).isValid()) {
201 // Only accept the mouse press event in inactive views,
202 // if a click is done on an item. This assures that
203 // the current selection, which usually shows the
204 // the directory for next column, won't get deleted.
205 QListView::mousePressEvent(event
);
209 void ColumnWidget::paintEvent(QPaintEvent
* event
)
211 QListView::paintEvent(event
);
213 // TODO: remove this code when the issue #160611 is solved in Qt 4.4
215 const QBrush
& brush
= m_viewOptions
.palette
.brush(QPalette::Normal
, QPalette::Highlight
);
216 DolphinController::drawHoverIndication(viewport(), m_dropRect
, brush
);
220 void ColumnWidget::contextMenuEvent(QContextMenuEvent
* event
)
222 if (m_view
->viewport()->children().first() == this) {
223 // This column widget represents the root column. DolphinColumnView::createColumn()
224 // cannot retrieve the correct URL at this stage, as the directory lister will be
225 // started after the model has been assigned. This will be fixed here, where it is
226 // assured that the directory lister has been started already.
227 const QAbstractProxyModel
* proxyModel
= static_cast<const QAbstractProxyModel
*>(model());
228 const KDirModel
* dirModel
= static_cast<const KDirModel
*>(proxyModel
->sourceModel());
229 const KDirLister
* dirLister
= dirModel
->dirLister();
230 m_url
= dirLister
->url();
233 QListView::contextMenuEvent(event
);
235 const QModelIndex index
= indexAt(event
->pos());
236 const KUrl
& navigatorUrl
= m_view
->m_controller
->url();
237 if (index
.isValid() || (m_url
== navigatorUrl
)) {
238 // Only open a context menu above an item or if the mouse is above
239 // the active column.
240 const QPoint pos
= m_view
->viewport()->mapFromGlobal(event
->globalPos());
241 m_view
->m_controller
->triggerContextMenuRequest(pos
);
245 void ColumnWidget::activate()
247 const QColor bgColor
= KColorScheme(KColorScheme::View
).background();
248 QPalette palette
= viewport()->palette();
249 palette
.setColor(viewport()->backgroundRole(), bgColor
);
250 viewport()->setPalette(palette
);
252 setSelectionMode(MultiSelection
);
255 void ColumnWidget::deactivate()
257 QColor bgColor
= KColorScheme(KColorScheme::View
).background();
258 const QColor fgColor
= KColorScheme(KColorScheme::View
).foreground();
259 bgColor
= KColorUtils::mix(bgColor
, fgColor
, 0.04);
261 QPalette palette
= viewport()->palette();
262 palette
.setColor(viewport()->backgroundRole(), bgColor
);
263 viewport()->setPalette(palette
);
265 setSelectionMode(SingleSelection
);
270 DolphinColumnView::DolphinColumnView(QWidget
* parent
, DolphinController
* controller
) :
272 m_controller(controller
)
274 Q_ASSERT(controller
!= 0);
276 setAcceptDrops(true);
277 setSelectionBehavior(SelectItems
);
278 setDragDropMode(QAbstractItemView::DragDrop
);
279 setDropIndicatorShown(false);
281 if (KGlobalSettings::singleClick()) {
282 connect(this, SIGNAL(clicked(const QModelIndex
&)),
283 this, SLOT(triggerItem(const QModelIndex
&)));
285 connect(this, SIGNAL(doubleClicked(const QModelIndex
&)),
286 this, SLOT(triggerItem(const QModelIndex
&)));
288 connect(this, SIGNAL(activated(const QModelIndex
&)),
289 this, SLOT(triggerItem(const QModelIndex
&)));
290 connect(this, SIGNAL(entered(const QModelIndex
&)),
291 controller
, SLOT(emitItemEntered(const QModelIndex
&)));
292 connect(this, SIGNAL(viewportEntered()),
293 controller
, SLOT(emitViewportEntered()));
294 connect(controller
, SIGNAL(zoomIn()),
295 this, SLOT(zoomIn()));
296 connect(controller
, SIGNAL(zoomOut()),
297 this, SLOT(zoomOut()));
299 updateDecorationSize();
302 DolphinColumnView::~DolphinColumnView()
306 QAbstractItemView
* DolphinColumnView::createColumn(const QModelIndex
& index
)
308 // To be able to visually indicate whether a column is active (which means
309 // that it represents the content of the URL navigator), the column
310 // must remember its URL.
311 const QAbstractProxyModel
* proxyModel
= static_cast<const QAbstractProxyModel
*>(model());
312 const KDirModel
* dirModel
= static_cast<const KDirModel
*>(proxyModel
->sourceModel());
314 const QModelIndex dirModelIndex
= proxyModel
->mapToSource(index
);
315 KFileItem
* fileItem
= dirModel
->itemForIndex(dirModelIndex
);
319 columnUrl
= fileItem
->url();
322 ColumnWidget
* view
= new ColumnWidget(viewport(),
326 // The following code has been copied 1:1 from QColumnView::createColumn().
327 // Copyright (C) 1992-2007 Trolltech ASA. In Qt 4.4 the new method
328 // QColumnView::initializeColumn() will be available for this.
330 view
->setFrameShape(QFrame::NoFrame
);
331 view
->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff
);
332 view
->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn
);
333 view
->setMinimumWidth(100);
334 view
->setAttribute(Qt::WA_MacShowFocusRect
, false);
336 // copy the 'view' behavior
337 view
->setDragDropMode(dragDropMode());
338 view
->setDragDropOverwriteMode(dragDropOverwriteMode());
339 view
->setDropIndicatorShown(showDropIndicator());
340 view
->setAlternatingRowColors(alternatingRowColors());
341 view
->setAutoScroll(hasAutoScroll());
342 view
->setEditTriggers(editTriggers());
343 view
->setHorizontalScrollMode(horizontalScrollMode());
344 view
->setIconSize(iconSize());
345 view
->setSelectionBehavior(selectionBehavior());
346 view
->setSelectionMode(selectionMode());
347 view
->setTabKeyNavigation(tabKeyNavigation());
348 view
->setTextElideMode(textElideMode());
349 view
->setVerticalScrollMode(verticalScrollMode());
351 view
->setModel(model());
353 // set the delegate to be the columnview delegate
354 QAbstractItemDelegate
* delegate
= view
->itemDelegate();
355 view
->setItemDelegate(itemDelegate());
358 view
->setRootIndex(index
);
360 if (model()->canFetchMore(index
)) {
361 model()->fetchMore(index
);
367 void DolphinColumnView::mousePressEvent(QMouseEvent
* event
)
369 m_controller
->triggerActivation();
370 QColumnView::mousePressEvent(event
);
373 void DolphinColumnView::dragEnterEvent(QDragEnterEvent
* event
)
375 if (event
->mimeData()->hasUrls()) {
376 event
->acceptProposedAction();
380 void DolphinColumnView::dropEvent(QDropEvent
* event
)
382 const KUrl::List urls
= KUrl::List::fromMimeData(event
->mimeData());
383 if (!urls
.isEmpty()) {
384 m_controller
->indicateDroppedUrls(urls
,
385 indexAt(event
->pos()),
387 event
->acceptProposedAction();
389 QColumnView::dropEvent(event
);
392 void DolphinColumnView::zoomIn()
394 if (isZoomInPossible()) {
395 ColumnModeSettings
* settings
= DolphinSettings::instance().columnModeSettings();
396 // TODO: get rid of K3Icon sizes
397 switch (settings
->iconSize()) {
398 case K3Icon::SizeSmall
: settings
->setIconSize(K3Icon::SizeMedium
); break;
399 case K3Icon::SizeMedium
: settings
->setIconSize(K3Icon::SizeLarge
); break;
400 default: Q_ASSERT(false); break;
402 updateDecorationSize();
406 void DolphinColumnView::zoomOut()
408 if (isZoomOutPossible()) {
409 ColumnModeSettings
* settings
= DolphinSettings::instance().columnModeSettings();
410 // TODO: get rid of K3Icon sizes
411 switch (settings
->iconSize()) {
412 case K3Icon::SizeLarge
: settings
->setIconSize(K3Icon::SizeMedium
); break;
413 case K3Icon::SizeMedium
: settings
->setIconSize(K3Icon::SizeSmall
); break;
414 default: Q_ASSERT(false); break;
416 updateDecorationSize();
420 void DolphinColumnView::triggerItem(const QModelIndex
& index
)
422 m_controller
->triggerItem(index
);
424 // Update the activation state of all columns. Only the column
425 // which represents the URL of the URL navigator is marked as active.
426 const KUrl
& navigatorUrl
= m_controller
->url();
427 foreach (QObject
* object
, viewport()->children()) {
428 if (object
->inherits("QListView")) {
429 ColumnWidget
* widget
= static_cast<ColumnWidget
*>(object
);
430 widget
->setActive(navigatorUrl
== widget
->url());
435 bool DolphinColumnView::isZoomInPossible() const
437 ColumnModeSettings
* settings
= DolphinSettings::instance().columnModeSettings();
438 return settings
->iconSize() < K3Icon::SizeLarge
;
441 bool DolphinColumnView::isZoomOutPossible() const
443 ColumnModeSettings
* settings
= DolphinSettings::instance().columnModeSettings();
444 return settings
->iconSize() > K3Icon::SizeSmall
;
447 void DolphinColumnView::updateDecorationSize()
449 ColumnModeSettings
* settings
= DolphinSettings::instance().columnModeSettings();
450 const int iconSize
= settings
->iconSize();
452 foreach (QObject
* object
, viewport()->children()) {
453 if (object
->inherits("QListView")) {
454 ColumnWidget
* widget
= static_cast<ColumnWidget
*>(object
);
455 widget
->setDecorationSize(QSize(iconSize
, iconSize
));
459 m_controller
->setZoomInPossible(isZoomInPossible());
460 m_controller
->setZoomOutPossible(isZoomOutPossible());
465 #include "dolphincolumnview.moc"