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 | |
34 | KDirOperatorDetailView::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 | |
48 | KDirOperatorDetailView::~KDirOperatorDetailView() |
49 | { |
50 | } |
51 | |
52 | void 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 | |
70 | bool 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 | |
99 | bool KDirOperatorDetailView::event(QEvent *event) |
100 | { |
101 | if (event->type() == QEvent::Polish) { |
102 | QHeaderView * = 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 | |
123 | void KDirOperatorDetailView::dragEnterEvent(QDragEnterEvent *event) |
124 | { |
125 | if (event->mimeData()->hasUrls()) { |
126 | event->acceptProposedAction(); |
127 | } |
128 | } |
129 | |
130 | void KDirOperatorDetailView::resizeEvent(QResizeEvent *event) |
131 | { |
132 | QTreeView::resizeEvent(event); |
133 | slotLayoutChanged(); |
134 | } |
135 | |
136 | void 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 | |
149 | void KDirOperatorDetailView::currentChanged(const QModelIndex& current, const QModelIndex& previous) |
150 | { |
151 | QTreeView::currentChanged(current, previous); |
152 | } |
153 | |
154 | void KDirOperatorDetailView::resetResizing() |
155 | { |
156 | QTimer::singleShot(300, this, SLOT(disableColumnResizing())); |
157 | } |
158 | |
159 | void KDirOperatorDetailView::disableColumnResizing() |
160 | { |
161 | m_resizeColumns = false; |
162 | } |
163 | |
164 | void KDirOperatorDetailView::slotLayoutChanged() |
165 | { |
166 | if (m_resizeColumns) { |
167 | QHeaderView * = 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 | |