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