]> cloud.milkyroute.net Git - dolphin.git/blob - src/views/tooltips/tooltipmanager.cpp
9375172eb4feefb70a3c8ca07d9debe0145ddc84
[dolphin.git] / src / views / tooltips / tooltipmanager.cpp
1 /*******************************************************************************
2 * Copyright (C) 2008 by Konstantin Heil <konst.heil@stud.uni-heidelberg.de> *
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 "tooltipmanager.h"
21
22 #include "dolphinfilemetadatawidget.h"
23 #include <QIcon>
24 #include <KIO/JobUiDelegate>
25 #include <KIO/PreviewJob>
26 #include <KJobWidgets>
27 #include <KToolTipWidget>
28
29 #include <QApplication>
30 #include <QDesktopWidget>
31 #include <QLayout>
32 #include <QStyle>
33 #include <QTimer>
34 #include <QWindow>
35
36 ToolTipManager::ToolTipManager(QWidget* parent) :
37 QObject(parent),
38 m_showToolTipTimer(0),
39 m_contentRetrievalTimer(0),
40 m_transientParent(0),
41 m_fileMetaDataWidget(0),
42 m_toolTipRequested(false),
43 m_metaDataRequested(false),
44 m_appliedWaitCursor(false),
45 m_margin(4),
46 m_item(),
47 m_itemRect()
48 {
49 if (parent) {
50 m_margin = qMax(m_margin, parent->style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth));
51 }
52
53 m_showToolTipTimer = new QTimer(this);
54 m_showToolTipTimer->setSingleShot(true);
55 m_showToolTipTimer->setInterval(500);
56 connect(m_showToolTipTimer, &QTimer::timeout, this, static_cast<void(ToolTipManager::*)()>(&ToolTipManager::showToolTip));
57
58 m_contentRetrievalTimer = new QTimer(this);
59 m_contentRetrievalTimer->setSingleShot(true);
60 m_contentRetrievalTimer->setInterval(200);
61 connect(m_contentRetrievalTimer, &QTimer::timeout, this, &ToolTipManager::startContentRetrieval);
62
63 Q_ASSERT(m_contentRetrievalTimer->interval() < m_showToolTipTimer->interval());
64 }
65
66 ToolTipManager::~ToolTipManager()
67 {
68 }
69
70 void ToolTipManager::showToolTip(const KFileItem& item, const QRectF& itemRect, QWindow *transientParent)
71 {
72 hideToolTip();
73
74 m_itemRect = itemRect.toRect();
75
76 m_itemRect.adjust(-m_margin, -m_margin, m_margin, m_margin);
77 m_item = item;
78
79 m_transientParent = transientParent;
80
81 // Only start the retrieving of the content, when the mouse has been over this
82 // item for 200 milliseconds. This prevents a lot of useless preview jobs and
83 // meta data retrieval, when passing rapidly over a lot of items.
84 delete m_fileMetaDataWidget;
85 m_fileMetaDataWidget = new DolphinFileMetaDataWidget();
86 connect(m_fileMetaDataWidget, &DolphinFileMetaDataWidget::metaDataRequestFinished,
87 this, &ToolTipManager::slotMetaDataRequestFinished);
88 connect(m_fileMetaDataWidget, &DolphinFileMetaDataWidget::urlActivated,
89 this, &ToolTipManager::urlActivated);
90
91 m_contentRetrievalTimer->start();
92 m_showToolTipTimer->start();
93 m_toolTipRequested = true;
94 Q_ASSERT(!m_metaDataRequested);
95 }
96
97 void ToolTipManager::hideToolTip()
98 {
99 if (m_appliedWaitCursor) {
100 QApplication::restoreOverrideCursor();
101 m_appliedWaitCursor = false;
102 }
103
104 m_toolTipRequested = false;
105 m_metaDataRequested = false;
106 m_showToolTipTimer->stop();
107 m_contentRetrievalTimer->stop();
108 if (m_tooltipWidget) {
109 m_tooltipWidget->hideLater();
110 }
111 }
112
113 void ToolTipManager::startContentRetrieval()
114 {
115 if (!m_toolTipRequested) {
116 return;
117 }
118
119 m_fileMetaDataWidget->setName(m_item.text());
120
121 // Request the retrieval of meta-data. The slot
122 // slotMetaDataRequestFinished() is invoked after the
123 // meta-data have been received.
124 m_metaDataRequested = true;
125 m_fileMetaDataWidget->setItems(KFileItemList() << m_item);
126 m_fileMetaDataWidget->adjustSize();
127
128 // Request a preview of the item
129 m_fileMetaDataWidget->setPreview(QPixmap());
130
131 KIO::PreviewJob* job = new KIO::PreviewJob(KFileItemList() << m_item, QSize(256, 256));
132 job->setIgnoreMaximumSize(m_item.isLocalFile());
133 if (job->uiDelegate()) {
134 KJobWidgets::setWindow(job, qApp->activeWindow());
135 }
136
137 connect(job, &KIO::PreviewJob::gotPreview,
138 this, &ToolTipManager::setPreviewPix);
139 connect(job, &KIO::PreviewJob::failed,
140 this, &ToolTipManager::previewFailed);
141 }
142
143
144 void ToolTipManager::setPreviewPix(const KFileItem& item,
145 const QPixmap& pixmap)
146 {
147 if (!m_toolTipRequested || (m_item.url() != item.url())) {
148 // No tooltip is requested anymore or an old preview has been received
149 return;
150 }
151
152 if (pixmap.isNull()) {
153 previewFailed();
154 } else {
155 m_fileMetaDataWidget->setPreview(pixmap);
156 if (!m_showToolTipTimer->isActive()) {
157 showToolTip();
158 }
159 }
160 }
161
162 void ToolTipManager::previewFailed()
163 {
164 if (!m_toolTipRequested) {
165 return;
166 }
167
168 const QPixmap pixmap = QIcon::fromTheme(m_item.iconName()).pixmap(128, 128);
169 m_fileMetaDataWidget->setPreview(pixmap);
170 if (!m_showToolTipTimer->isActive()) {
171 showToolTip();
172 }
173 }
174
175 void ToolTipManager::slotMetaDataRequestFinished()
176 {
177 if (!m_toolTipRequested) {
178 return;
179 }
180
181 m_metaDataRequested = false;
182
183 if (!m_showToolTipTimer->isActive()) {
184 showToolTip();
185 }
186 }
187
188 void ToolTipManager::showToolTip()
189 {
190 Q_ASSERT(m_toolTipRequested);
191 if (m_appliedWaitCursor) {
192 QApplication::restoreOverrideCursor();
193 m_appliedWaitCursor = false;
194 }
195
196 if (m_fileMetaDataWidget->preview().isNull() || m_metaDataRequested) {
197 Q_ASSERT(!m_appliedWaitCursor);
198 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
199 m_appliedWaitCursor = true;
200 return;
201 }
202
203 // Adjust the size to get a proper sizeHint()
204 m_fileMetaDataWidget->adjustSize();
205 if (!m_tooltipWidget) {
206 m_tooltipWidget.reset(new KToolTipWidget());
207 }
208 m_tooltipWidget->showBelow(m_itemRect, m_fileMetaDataWidget, m_transientParent);
209 m_toolTipRequested = false;
210 }
211