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