1/*****************************************************************************
2 * Copyright (C) 2007 by Peter Penz <peter.penz@gmx.at> *
3 * *
4 * This library is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Library General Public *
6 * License version 2 as published by the Free Software Foundation. *
7 * *
8 * This library is distributed in the hope that it will be useful, *
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
11 * Library General Public License for more details. *
12 * *
13 * You should have received a copy of the GNU Library General Public License *
14 * along with this library; see the file COPYING.LIB. If not, write to *
15 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
16 * Boston, MA 02110-1301, USA. *
17 *****************************************************************************/
18
19#include "kdiroperatordetailview_p.h"
20
21#include <kdirlister.h>
22#include <kdirmodel.h>
23#include <kdebug.h>
24
25#include <QtCore/QEvent>
26#include <QtCore/QTimer>
27#include <QtGui/QAbstractProxyModel>
28#include <QtGui/QApplication>
29#include <QtGui/QHeaderView>
30#include <QtGui/QListView>
31#include <QtGui/QResizeEvent>
32#include <QtGui/QScrollBar>
33
34KDirOperatorDetailView::KDirOperatorDetailView(QWidget *parent) :
35 QTreeView(parent),
36 m_resizeColumns(true), m_hideDetailColumns(false)
37{
38 setRootIsDecorated(false);
39 setSortingEnabled(true);
40 setUniformRowHeights(true);
41 setDragDropMode(QListView::DragOnly);
42 setSelectionBehavior(QAbstractItemView::SelectRows);
43 setEditTriggers(QAbstractItemView::NoEditTriggers);
44 setVerticalScrollMode(QListView::ScrollPerPixel);
45 setHorizontalScrollMode(QListView::ScrollPerPixel);
46}
47
48KDirOperatorDetailView::~KDirOperatorDetailView()
49{
50}
51
52void KDirOperatorDetailView::setModel(QAbstractItemModel *model)
53{
54 if (model->rowCount() == 0) {
55 // The model is empty. Assure that the columns get automatically resized
56 // until the loading has been finished.
57 QAbstractProxyModel *proxyModel = static_cast<QAbstractProxyModel*>(model);
58 KDirModel *dirModel = static_cast<KDirModel*>(proxyModel->sourceModel());
59 connect(dirModel->dirLister(), SIGNAL(completed()),
60 this, SLOT(resetResizing()));
61 } else {
62 resetResizing();
63 }
64
65 connect(model, SIGNAL(layoutChanged()), this, SLOT(slotLayoutChanged()));
66
67 QTreeView::setModel(model);
68}
69
70bool KDirOperatorDetailView::setViewMode(KFile::FileView viewMode)
71{
72 bool tree = false;
73
74 if (KFile::isDetailView(viewMode)) {
75 m_hideDetailColumns = false;
76 } else if (KFile::isTreeView(viewMode)) {
77 m_hideDetailColumns = true;
78 tree = true;
79 } else if (KFile::isDetailTreeView(viewMode)) {
80 m_hideDetailColumns = false;
81 tree = true;
82 } else {
83 return false;
84 }
85
86 setRootIsDecorated(tree);
87 setItemsExpandable(tree);
88 // This allows to have a horizontal scrollbar in case this view is used as
89 // a plain treeview instead of cutting off filenames, especially useful when
90 // using KDirOperator in horizontally limited parts of an app.
91 if( tree && m_hideDetailColumns ) {
92 header()->setResizeMode( QHeaderView::ResizeToContents );
93 header()->setStretchLastSection( false );
94 }
95
96 return true;
97}
98
99bool KDirOperatorDetailView::event(QEvent *event)
100{
101 if (event->type() == QEvent::Polish) {
102 QHeaderView *headerView = header();
103 headerView->setResizeMode(QHeaderView::Interactive);
104 headerView->setStretchLastSection(true);
105 headerView->setMovable(false);
106
107 setColumnHidden(KDirModel::Size, m_hideDetailColumns);
108 setColumnHidden(KDirModel::ModifiedTime, m_hideDetailColumns);
109 hideColumn(KDirModel::Type);
110 hideColumn(KDirModel::Permissions);
111 hideColumn(KDirModel::Owner);
112 hideColumn(KDirModel::Group);
113 }
114 else if (event->type() == QEvent::UpdateRequest) {
115 // A wheel movement will scroll 4 items
116 if (model()->rowCount())
117 verticalScrollBar()->setSingleStep((sizeHintForRow(0) / 3) * 4);
118 }
119
120 return QTreeView::event(event);
121}
122
123void KDirOperatorDetailView::dragEnterEvent(QDragEnterEvent *event)
124{
125 if (event->mimeData()->hasUrls()) {
126 event->acceptProposedAction();
127 }
128}
129
130void KDirOperatorDetailView::resizeEvent(QResizeEvent *event)
131{
132 QTreeView::resizeEvent(event);
133 slotLayoutChanged();
134}
135
136void KDirOperatorDetailView::mousePressEvent(QMouseEvent *event)
137{
138 QTreeView::mousePressEvent(event);
139
140 const QModelIndex index = indexAt(event->pos());
141 if (!index.isValid() || (index.column() != KDirModel::Name)) {
142 const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
143 if (!(modifiers & Qt::ShiftModifier) && !(modifiers & Qt::ControlModifier)) {
144 clearSelection();
145 }
146 }
147}
148
149void KDirOperatorDetailView::currentChanged(const QModelIndex& current, const QModelIndex& previous)
150{
151 QTreeView::currentChanged(current, previous);
152}
153
154void KDirOperatorDetailView::resetResizing()
155{
156 QTimer::singleShot(300, this, SLOT(disableColumnResizing()));
157}
158
159void KDirOperatorDetailView::disableColumnResizing()
160{
161 m_resizeColumns = false;
162}
163
164void KDirOperatorDetailView::slotLayoutChanged()
165{
166 if (m_resizeColumns) {
167 QHeaderView *headerView = header();
168 headerView->resizeSections(QHeaderView::ResizeToContents);
169
170 // calculate the required width for all columns except the name column
171 int requiredWidth = 0;
172 const int count = headerView->count();
173 for (int i = 1; i < count; ++i) {
174 requiredWidth += headerView->sectionSize(i);
175 }
176
177 // try to stretch the name column if enough width is available
178 int oldNameColumnWidth = headerView->sectionSize(KDirModel::Name);
179 int nameColumnWidth = viewport()->width() - requiredWidth;
180 if (nameColumnWidth < oldNameColumnWidth) {
181 nameColumnWidth = oldNameColumnWidth;
182 }
183 headerView->resizeSection(KDirModel::Name, nameColumnWidth);
184 }
185}
186
187// kate: space-indent on; indent-width 4; replace-tabs on;
188