]> cloud.milkyroute.net Git - dolphin.git/blob - src/panels/information/informationpanel.cpp
Fixed regression when refactoring the Information Panel: Don't forget to give a visua...
[dolphin.git] / src / panels / information / informationpanel.cpp
1 /***************************************************************************
2 * Copyright (C) 2006-2009 by Peter Penz <peter.penz@gmx.at> *
3 * *
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. *
8 * *
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. *
13 * *
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 ***************************************************************************/
19
20 #include "informationpanel.h"
21 #include <kdirnotify.h>
22 #include <QShowEvent>
23 #include "informationpanelcontent.h"
24
25 InformationPanel::InformationPanel(QWidget* parent) :
26 Panel(parent),
27 m_initialized(false),
28 m_infoTimer(0),
29 m_urlChangedTimer(0),
30 m_resetUrlTimer(0),
31 m_shownUrl(),
32 m_urlCandidate(),
33 m_invalidUrlCandidate(),
34 m_fileItem(),
35 m_selection(),
36 m_content(0)
37 {
38 }
39
40 InformationPanel::~InformationPanel()
41 {
42 }
43
44 QSize InformationPanel::sizeHint() const
45 {
46 QSize size = Panel::sizeHint();
47 size.setWidth(minimumSizeHint().width());
48 return size;
49 }
50
51 void InformationPanel::setUrl(const KUrl& url)
52 {
53 Panel::setUrl(url);
54 if (url.isValid() && !isEqualToShownUrl(url)) {
55 if (isVisible()) {
56 cancelRequest();
57 m_shownUrl = url;
58 // Update the content with a delay. This gives
59 // the directory lister the chance to show the content
60 // before expensive operations are done to show
61 // meta information.
62 m_urlChangedTimer->start();
63 } else {
64 m_shownUrl = url;
65 }
66 }
67 }
68
69 void InformationPanel::setSelection(const KFileItemList& selection)
70 {
71 if (!isVisible()) {
72 return;
73 }
74
75 if ((selection.count() == 0) && (m_selection.count() == 0)) {
76 // The selection has not really changed, only the current index.
77 // QItemSelectionModel emits a signal in this case and it is less
78 // expensive doing the check this way instead of patching
79 // DolphinView::emitSelectionChanged().
80 return;
81 }
82
83 m_selection = selection;
84
85 const int count = selection.count();
86 if (count == 0) {
87 if (!isEqualToShownUrl(url())) {
88 m_shownUrl = url();
89 showItemInfo();
90 }
91 } else {
92 if ((count == 1) && !selection.first().url().isEmpty()) {
93 m_urlCandidate = selection.first().url();
94 }
95 m_infoTimer->start();
96 }
97 }
98
99 void InformationPanel::requestDelayedItemInfo(const KFileItem& item)
100 {
101 if (!isVisible()) {
102 return;
103 }
104
105 cancelRequest();
106
107 m_fileItem = KFileItem();
108 if (item.isNull()) {
109 // The cursor is above the viewport. If files are selected,
110 // show information regarding the selection.
111 if (m_selection.size() > 0) {
112 m_infoTimer->start();
113 }
114 } else {
115 const KUrl url = item.url();
116 if (url.isValid() && !isEqualToShownUrl(url)) {
117 m_urlCandidate = item.url();
118 m_fileItem = item;
119 m_infoTimer->start();
120 }
121 }
122 }
123
124 void InformationPanel::showEvent(QShowEvent* event)
125 {
126 Panel::showEvent(event);
127 if (!event->spontaneous()) {
128 if (!m_initialized) {
129 // do a delayed initialization so that no performance
130 // penalty is given when Dolphin is started with a closed
131 // Information Panel
132 init();
133 }
134 showItemInfo();
135 }
136 }
137
138 void InformationPanel::resizeEvent(QResizeEvent* event)
139 {
140 if (isVisible()) {
141 m_urlCandidate = m_shownUrl;
142 m_infoTimer->start();
143 }
144 Panel::resizeEvent(event);
145 }
146
147 void InformationPanel::contextMenuEvent(QContextMenuEvent* event)
148 {
149 m_content->configureSettings();
150 Panel::contextMenuEvent(event);
151 }
152
153 void InformationPanel::showItemInfo()
154 {
155 if (!isVisible()) {
156 return;
157 }
158
159 cancelRequest();
160
161 if (showMultipleSelectionInfo()) {
162 m_content->showItems(m_selection);
163 m_shownUrl = KUrl();
164 } else {
165 KFileItem item;
166 if (!m_fileItem.isNull()) {
167 item = m_fileItem;
168 } else if (!m_selection.isEmpty()) {
169 Q_ASSERT(m_selection.count() == 1);
170 item = m_selection.first();
171 } else {
172 // no item is hovered and no selection has been done: provide
173 // an item for the directory represented by m_shownUrl
174 m_fileItem = KFileItem(KFileItem::Unknown, KFileItem::Unknown, m_shownUrl);
175 m_fileItem.refresh();
176 item = m_fileItem;
177 }
178
179 m_content->showItem(item);
180 }
181 }
182
183 void InformationPanel::slotInfoTimeout()
184 {
185 m_shownUrl = m_urlCandidate;
186 showItemInfo();
187 }
188
189 void InformationPanel::reset()
190 {
191 if (m_invalidUrlCandidate == m_shownUrl) {
192 m_invalidUrlCandidate = KUrl();
193
194 // The current URL is still invalid. Reset
195 // the content to show the directory URL.
196 m_selection.clear();
197 m_shownUrl = url();
198 m_fileItem = KFileItem();
199 showItemInfo();
200 }
201 }
202
203 void InformationPanel::slotFileRenamed(const QString& source, const QString& dest)
204 {
205 if (m_shownUrl == KUrl(source)) {
206 m_shownUrl = KUrl(dest);
207 m_fileItem = KFileItem(KFileItem::Unknown, KFileItem::Unknown, m_shownUrl);
208 showItemInfo();
209 }
210 }
211
212 void InformationPanel::slotFilesAdded(const QString& directory)
213 {
214 if (m_shownUrl == KUrl(directory)) {
215 // If the 'trash' icon changes because the trash has been emptied or got filled,
216 // the signal filesAdded("trash:/") will be emitted.
217 KFileItem item(KFileItem::Unknown, KFileItem::Unknown, KUrl(directory));
218 requestDelayedItemInfo(item);
219 }
220 }
221
222 void InformationPanel::slotFilesChanged(const QStringList& files)
223 {
224 foreach (const QString& fileName, files) {
225 if (m_shownUrl == KUrl(fileName)) {
226 showItemInfo();
227 break;
228 }
229 }
230 }
231
232 void InformationPanel::slotFilesRemoved(const QStringList& files)
233 {
234 foreach (const QString& fileName, files) {
235 if (m_shownUrl == KUrl(fileName)) {
236 // the currently shown item has been removed, show
237 // the parent directory as fallback
238 markUrlAsInvalid();
239 break;
240 }
241 }
242 }
243
244 void InformationPanel::slotEnteredDirectory(const QString& directory)
245 {
246 if (m_shownUrl == KUrl(directory)) {
247 KFileItem item(KFileItem::Unknown, KFileItem::Unknown, KUrl(directory));
248 requestDelayedItemInfo(item);
249 }
250 }
251
252 void InformationPanel::slotLeftDirectory(const QString& directory)
253 {
254 if (m_shownUrl == KUrl(directory)) {
255 // The signal 'leftDirectory' is also emitted when a media
256 // has been unmounted. In this case no directory change will be
257 // done in Dolphin, but the Information Panel must be updated to
258 // indicate an invalid directory.
259 markUrlAsInvalid();
260 }
261 }
262
263 void InformationPanel::cancelRequest()
264 {
265 m_infoTimer->stop();
266 }
267
268 bool InformationPanel::showMultipleSelectionInfo() const
269 {
270 return m_fileItem.isNull() && (m_selection.count() > 1);
271 }
272
273 bool InformationPanel::isEqualToShownUrl(const KUrl& url) const
274 {
275 return m_shownUrl.equals(url, KUrl::CompareWithoutTrailingSlash);
276 }
277
278 void InformationPanel::markUrlAsInvalid()
279 {
280 m_invalidUrlCandidate = m_shownUrl;
281 m_resetUrlTimer->start();
282 }
283
284 void InformationPanel::init()
285 {
286 const int defaultDelay = 300;
287
288 m_infoTimer = new QTimer(this);
289 m_infoTimer->setInterval(defaultDelay);
290 m_infoTimer->setSingleShot(true);
291 connect(m_infoTimer, SIGNAL(timeout()),
292 this, SLOT(slotInfoTimeout()));
293
294 m_urlChangedTimer = new QTimer(this);
295 m_urlChangedTimer->setInterval(defaultDelay);
296 m_urlChangedTimer->setSingleShot(true);
297 connect(m_urlChangedTimer, SIGNAL(timeout()),
298 this, SLOT(showItemInfo()));
299
300 m_resetUrlTimer = new QTimer(this);
301 m_resetUrlTimer->setInterval(defaultDelay * 3);
302 m_resetUrlTimer->setSingleShot(true);
303 connect(m_resetUrlTimer, SIGNAL(timeout()),
304 this, SLOT(reset()));
305
306 org::kde::KDirNotify* dirNotify = new org::kde::KDirNotify(QString(), QString(),
307 QDBusConnection::sessionBus(), this);
308 connect(dirNotify, SIGNAL(FileRenamed(QString, QString)), SLOT(slotFileRenamed(QString, QString)));
309 connect(dirNotify, SIGNAL(FilesAdded(QString)), SLOT(slotFilesAdded(QString)));
310 connect(dirNotify, SIGNAL(FilesChanged(QStringList)), SLOT(slotFilesChanged(QStringList)));
311 connect(dirNotify, SIGNAL(FilesRemoved(QStringList)), SLOT(slotFilesRemoved(QStringList)));
312 connect(dirNotify, SIGNAL(enteredDirectory(QString)), SLOT(slotEnteredDirectory(QString)));
313 connect(dirNotify, SIGNAL(leftDirectory(QString)), SLOT(slotLeftDirectory(QString)));
314
315 m_content = new InformationPanelContent(this);
316
317 m_initialized = true;
318 }
319
320 #include "informationpanel.moc"