Changeset View
Changeset View
Standalone View
Standalone View
src/panels/information/informationpanelcontent.cpp
Show All 40 Lines | |||||
41 | 41 | | |||
42 | #include <QLabel> | 42 | #include <QLabel> | ||
43 | #include <QDialogButtonBox> | 43 | #include <QDialogButtonBox> | ||
44 | #include <QScrollArea> | 44 | #include <QScrollArea> | ||
45 | #include <QTextLayout> | 45 | #include <QTextLayout> | ||
46 | #include <QTimer> | 46 | #include <QTimer> | ||
47 | #include <QVBoxLayout> | 47 | #include <QVBoxLayout> | ||
48 | #include <QStyle> | 48 | #include <QStyle> | ||
49 | #include <QPainter> | ||||
50 | #include <QBitmap> | ||||
49 | 51 | | |||
50 | #include "dolphin_informationpanelsettings.h" | 52 | #include "dolphin_informationpanelsettings.h" | ||
51 | #include "phononwidget.h" | 53 | #include "phononwidget.h" | ||
52 | #include "pixmapviewer.h" | 54 | #include "pixmapviewer.h" | ||
53 | 55 | | |||
56 | const uint PLAY_ARROW_SIZE = 48; | ||||
57 | const uint PLAY_ARROW_BORDER_SIZE = 4; | ||||
58 | | ||||
54 | InformationPanelContent::InformationPanelContent(QWidget* parent) : | 59 | InformationPanelContent::InformationPanelContent(QWidget* parent) : | ||
55 | QWidget(parent), | 60 | QWidget(parent), | ||
56 | m_item(), | 61 | m_item(), | ||
57 | m_previewJob(nullptr), | 62 | m_previewJob(nullptr), | ||
58 | m_outdatedPreviewTimer(nullptr), | 63 | m_outdatedPreviewTimer(nullptr), | ||
59 | m_preview(nullptr), | 64 | m_preview(nullptr), | ||
60 | m_phononWidget(nullptr), | 65 | m_phononWidget(nullptr), | ||
61 | m_nameLabel(nullptr), | 66 | m_nameLabel(nullptr), | ||
62 | m_metaDataWidget(nullptr), | 67 | m_metaDataWidget(nullptr), | ||
63 | m_metaDataArea(nullptr), | 68 | m_metaDataArea(nullptr), | ||
64 | m_placesItemModel(nullptr) | 69 | m_placesItemModel(nullptr), | ||
70 | m_usePhonon(false) | ||||
65 | { | 71 | { | ||
66 | parent->installEventFilter(this); | 72 | parent->installEventFilter(this); | ||
67 | 73 | | |||
68 | // Initialize timer for disabling an outdated preview with a small | 74 | // Initialize timer for disabling an outdated preview with a small | ||
69 | // delay. This prevents flickering if the new preview can be generated | 75 | // delay. This prevents flickering if the new preview can be generated | ||
70 | // within a very small timeframe. | 76 | // within a very small timeframe. | ||
71 | m_outdatedPreviewTimer = new QTimer(this); | 77 | m_outdatedPreviewTimer = new QTimer(this); | ||
72 | m_outdatedPreviewTimer->setInterval(300); | 78 | m_outdatedPreviewTimer->setInterval(300); | ||
▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Line(s) | 161 | { | |||
156 | InformationPanelSettings::self()->save(); | 162 | InformationPanelSettings::self()->save(); | ||
157 | } | 163 | } | ||
158 | 164 | | |||
159 | void InformationPanelContent::showItem(const KFileItem& item) | 165 | void InformationPanelContent::showItem(const KFileItem& item) | ||
160 | { | 166 | { | ||
161 | if (item != m_item) { | 167 | if (item != m_item) { | ||
162 | m_item = item; | 168 | m_item = item; | ||
163 | 169 | | |||
164 | refreshPreview(); | | |||
165 | refreshMetaData(); | 170 | refreshMetaData(); | ||
166 | } | 171 | } | ||
172 | refreshPreview(); | ||||
167 | } | 173 | } | ||
168 | 174 | | |||
169 | void InformationPanelContent::refreshPreview() | 175 | void InformationPanelContent::refreshPreview() | ||
170 | { | 176 | { | ||
171 | // If there is a preview job, kill it to prevent that we have jobs for | 177 | // If there is a preview job, kill it to prevent that we have jobs for | ||
172 | // multiple items running, and thus a race condition (bug 250787). | 178 | // multiple items running, and thus a race condition (bug 250787). | ||
elvisangelaccio: Why remove this comment? We are still killing the preview job here, aren't we? | |||||
The comment was moved to InformationPanelContent::refreshPreview but I have re-added it here as well. meven: The comment was moved to InformationPanelContent::refreshPreview but I have re-added it here as… | |||||
173 | if (m_previewJob) { | 179 | if (m_previewJob) { | ||
174 | m_previewJob->kill(); | 180 | m_previewJob->kill(); | ||
175 | } | 181 | } | ||
176 | 182 | | |||
183 | m_preview->setCursor(Qt::ArrowCursor); | ||||
184 | m_usePhonon = false; | ||||
177 | setNameLabelText(m_item.text()); | 185 | setNameLabelText(m_item.text()); | ||
178 | if (InformationPanelSettings::previewsShown()) { | 186 | if (InformationPanelSettings::previewsShown()) { | ||
179 | 187 | | |||
180 | const QUrl itemUrl = m_item.url(); | 188 | const QUrl itemUrl = m_item.url(); | ||
181 | const bool isSearchUrl = itemUrl.scheme().contains(QStringLiteral("search")) && m_item.localPath().isEmpty(); | 189 | const bool isSearchUrl = itemUrl.scheme().contains(QStringLiteral("search")) && m_item.localPath().isEmpty(); | ||
182 | if (isSearchUrl) { | 190 | if (isSearchUrl) { | ||
183 | m_preview->show(); | 191 | m_preview->show(); | ||
184 | 192 | | |||
Show All 26 Lines | 198 | } else { | |||
211 | 219 | | |||
212 | connect(m_previewJob.data(), &KIO::PreviewJob::gotPreview, | 220 | connect(m_previewJob.data(), &KIO::PreviewJob::gotPreview, | ||
213 | this, &InformationPanelContent::showPreview); | 221 | this, &InformationPanelContent::showPreview); | ||
214 | connect(m_previewJob.data(), &KIO::PreviewJob::failed, | 222 | connect(m_previewJob.data(), &KIO::PreviewJob::failed, | ||
215 | this, &InformationPanelContent::showIcon); | 223 | this, &InformationPanelContent::showIcon); | ||
216 | 224 | | |||
217 | const QString mimeType = m_item.mimetype(); | 225 | const QString mimeType = m_item.mimetype(); | ||
218 | const bool isVideo = mimeType.startsWith(QLatin1String("video/")); | 226 | const bool isVideo = mimeType.startsWith(QLatin1String("video/")); | ||
219 | const bool usePhonon = mimeType.startsWith(QLatin1String("audio/")) || isVideo; | 227 | m_usePhonon = mimeType.startsWith(QLatin1String("audio/")) || isVideo; | ||
220 | 228 | | |||
221 | if (usePhonon) { | 229 | if (m_usePhonon) { | ||
230 | // change the cursor | ||||
231 | m_preview->setCursor(Qt::PointingHandCursor); | ||||
222 | 232 | | |||
223 | if (InformationPanelSettings::previewsAutoPlay() && isVideo) { | 233 | if (InformationPanelSettings::previewsAutoPlay() && isVideo) { | ||
224 | // hides the preview now to avoid flickering when the autoplay video starts | 234 | // hides the preview now to avoid flickering when the autoplay video starts | ||
225 | m_preview->hide(); | 235 | m_preview->hide(); | ||
226 | } else { | 236 | } else { | ||
227 | // the video won't play before the preview is displayed | 237 | // the video won't play before the preview is displayed | ||
228 | m_preview->show(); | 238 | m_preview->show(); | ||
239 | m_preview->installEventFilter(m_phononWidget); | ||||
229 | } | 240 | } | ||
230 | 241 | | |||
231 | m_phononWidget->show(); | 242 | m_phononWidget->show(); | ||
232 | m_phononWidget->setUrl(m_item.targetUrl(), isVideo ? PhononWidget::MediaKind::Video : PhononWidget::MediaKind::Audio); | 243 | m_phononWidget->setUrl(m_item.targetUrl(), isVideo ? PhononWidget::MediaKind::Video : PhononWidget::MediaKind::Audio); | ||
233 | m_phononWidget->setVideoSize(m_preview->size()); | 244 | m_phononWidget->setVideoSize(m_preview->size()); | ||
234 | } else { | 245 | } else { | ||
235 | // When we don't need it, hide the phonon widget first to avoid flickering | 246 | // When we don't need it, hide the phonon widget first to avoid flickering | ||
236 | m_phononWidget->hide(); | 247 | m_phononWidget->hide(); | ||
237 | m_preview->show(); | 248 | m_preview->show(); | ||
249 | m_preview->removeEventFilter(m_phononWidget); | ||||
238 | } | 250 | } | ||
239 | } | 251 | } | ||
240 | } else { | 252 | } else { | ||
241 | m_preview->hide(); | 253 | m_preview->hide(); | ||
242 | m_phononWidget->hide(); | 254 | m_phononWidget->hide(); | ||
243 | } | 255 | } | ||
244 | } | 256 | } | ||
245 | 257 | | |||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Line(s) | |||||
318 | void InformationPanelContent::showPreview(const KFileItem& item, | 330 | void InformationPanelContent::showPreview(const KFileItem& item, | ||
319 | const QPixmap& pixmap) | 331 | const QPixmap& pixmap) | ||
320 | { | 332 | { | ||
321 | m_outdatedPreviewTimer->stop(); | 333 | m_outdatedPreviewTimer->stop(); | ||
322 | Q_UNUSED(item); | 334 | Q_UNUSED(item); | ||
323 | 335 | | |||
324 | QPixmap p = pixmap; | 336 | QPixmap p = pixmap; | ||
325 | KIconLoader::global()->drawOverlays(item.overlays(), p, KIconLoader::Desktop); | 337 | KIconLoader::global()->drawOverlays(item.overlays(), p, KIconLoader::Desktop); | ||
338 | | ||||
339 | if (m_usePhonon) { | ||||
340 | // adds a play arrow | ||||
341 | auto icon = QIcon::fromTheme(QStringLiteral("media-playback-start")); | ||||
342 | | ||||
343 | // border of the arrow | ||||
344 | auto pixborder = icon.pixmap(PLAY_ARROW_SIZE, PLAY_ARROW_SIZE); | ||||
elvisangelaccio: Please always use camelCase. | |||||
345 | // inner arrow | ||||
346 | auto pixicon = icon.pixmap(PLAY_ARROW_SIZE - PLAY_ARROW_BORDER_SIZE, PLAY_ARROW_SIZE - PLAY_ARROW_BORDER_SIZE); | ||||
elvisangelaccio: Is it possible to not hardcode these numbers? | |||||
347 | | ||||
348 | QImage img = pixborder.toImage(); | ||||
349 | for (int i=0; i<pixborder.width(); i++) { | ||||
350 | for (int j=0; j<pixborder.height(); j++) { | ||||
351 | if (qAlpha(img.pixel(i,j)) != 0) { | ||||
352 | // invert the color | ||||
353 | QColor c = img.pixelColor(i,j); | ||||
elvisangelaccio: Coding style: opening brace should go to the end of previous line. | |||||
354 | c.setRed(255 - c.red()); | ||||
355 | c.setGreen(255 - c.green()); | ||||
356 | c.setBlue(255 - c.blue()); | ||||
357 | img.setPixelColor(i,j, c); | ||||
358 | } | ||||
359 | } | ||||
360 | } | ||||
361 | | ||||
362 | pixborder = QPixmap::fromImage(img); | ||||
363 | | ||||
364 | QPainter painter(&p); | ||||
365 | | ||||
366 | painter.drawPixmap(static_cast<int>(p.width() / 2 - pixborder.width() / 2 / devicePixelRatio()), | ||||
367 | static_cast<int>(p.height() / 2 - pixborder.height() / 2 / devicePixelRatio()), | ||||
368 | pixborder); | ||||
369 | | ||||
370 | painter.drawPixmap(static_cast<int>(p.width() / 2 - pixicon.width() / 2 / devicePixelRatio()), | ||||
371 | static_cast<int>(p.height() / 2 - pixicon.height() / 2 / devicePixelRatio()), | ||||
372 | pixicon); | ||||
373 | } | ||||
374 | | ||||
326 | m_preview->setPixmap(p); | 375 | m_preview->setPixmap(p); | ||
327 | } | 376 | } | ||
328 | 377 | | |||
329 | void InformationPanelContent::markOutdatedPreview() | 378 | void InformationPanelContent::markOutdatedPreview() | ||
330 | { | 379 | { | ||
331 | KIconEffect *iconEffect = KIconLoader::global()->iconEffect(); | 380 | KIconEffect *iconEffect = KIconLoader::global()->iconEffect(); | ||
332 | QPixmap disabledPixmap = iconEffect->apply(m_preview->pixmap(), | 381 | QPixmap disabledPixmap = iconEffect->apply(m_preview->pixmap(), | ||
333 | KIconLoader::Desktop, | 382 | KIconLoader::Desktop, | ||
▲ Show 20 Lines • Show All 72 Lines • Show Last 20 Lines |
Why remove this comment? We are still killing the preview job here, aren't we?