<file>images/badge3.png</file>
<file>images/badge4.png</file>
<file>sounds/snapshot.wav</file>
+ <file>images/app@2x.png</file>
+ <file>images/sort@2x.png</file>
+ <file>images/unwatched@2x.png</file>
+ <file>images/badge@2x.png</file>
+ <file>images/badge3@2x.png</file>
+ <file>images/channels@2x.png</file>
+ <file>images/mark-watched@2x.png</file>
+ <file>images/show-updated@2x.png</file>
+ <file>images/worldwide@2x.png</file>
+ <file>images/badge4@2x.png</file>
+ <file>images/refine-search@2x.png</file>
+ <file>images/search-duration@2x.png</file>
+ <file>images/search-quality@2x.png</file>
+ <file>images/search-time@2x.png</file>
+ <file>images/search-sortBy@2x.png</file>
</qresource>
</RCC>
#include "mac_startup.h"
#endif
#include "fontutils.h"
+#include "iconutils.h"
AboutView::AboutView(QWidget *parent) : View(parent) {
hLayout->setSpacing(30);
QLabel *logo = new QLabel(this);
- logo->setPixmap(QPixmap(":/images/app.png"));
+ logo->setPixmap(IconUtils::pixmap(":/images/app.png"));
hLayout->addWidget(logo, 0, Qt::AlignTop);
QBoxLayout *layout = new QVBoxLayout();
#include "fontutils.h"
#include "channelaggregator.h"
#include "painterutils.h"
+#include "iconutils.h"
static const int ITEM_WIDTH = 128;
static const int ITEM_HEIGHT = 128;
painter->translate(option.rect.topLeft());
const QRect line(0, 0, option.rect.width(), option.rect.height());
- static const QPixmap thumbnail = QPixmap(":/images/channels.png");
+ static const QPixmap thumbnail = IconUtils::pixmap(":/images/channels.png");
QString name = tr("All Videos");
painter->translate(option.rect.topLeft());
const QRect line(0, 0, option.rect.width(), option.rect.height());
- static const QPixmap thumbnail = QPixmap(":/images/unwatched.png");
+ static const QPixmap thumbnail = IconUtils::pixmap(":/images/unwatched.png");
QString name = tr("Unwatched Videos");
#endif
#include "datautils.h"
#include "compatibility/pathsservice.h"
+#include "iconutils.h"
static DownloadManager *downloadManagerInstance = 0;
if (!Activation::instance().isActivated()) {
if (video->duration() >= 60*4) {
QMessageBox msgBox(MainWindow::instance());
- msgBox.setIconPixmap(QPixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
+ msgBox.setIconPixmap(IconUtils::pixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
msgBox.setText(tr("This is just the demo version of %1.").arg(Constants::NAME));
msgBox.setInformativeText(
tr("It can only download videos shorter than %1 minutes so you can test the download functionality.")
QIcon IconUtils::fromResources(const QString &name) {
QIcon icon = QIcon(QString(":/images/%1.png").arg(name));
if (!icon.isNull()) {
- icon.addPixmap(QString(":/images/%1_active.png").arg(name), QIcon::Active);
- icon.addPixmap(QString(":/images/%1_selected.png").arg(name), QIcon::Selected);
- icon.addPixmap(QString(":/images/%1_disabled.png").arg(name), QIcon::Disabled);
+ icon.addPixmap(IconUtils::pixmap(QString(":/images/%1_active.png").arg(name)), QIcon::Active);
+ icon.addPixmap(IconUtils::pixmap(QString(":/images/%1_selected.png").arg(name)), QIcon::Selected);
+ icon.addPixmap(IconUtils::pixmap(QString(":/images/%1_disabled.png").arg(name)), QIcon::Disabled);
}
return icon;
}
action->shortcut().toString(QKeySequence::NativeText) +
")");
}
+
+QPixmap IconUtils::pixmap(const QString &name) {
+ // Check if a "@2x" file exists
+ QString fileName = name;
+ if (qApp->devicePixelRatio() > 1.0) {
+ int dotIndex = fileName.lastIndexOf(QLatin1Char('.'));
+ if (dotIndex != -1) {
+ QString at2xfileName = fileName;
+ at2xfileName.insert(dotIndex, QStringLiteral("@2x"));
+ if (QFile::exists(at2xfileName))
+ fileName = at2xfileName;
+ }
+ }
+
+ return QPixmap(fileName);
+}
static QIcon tintedIcon(const QString &name, const QColor &color, const QSize &size);
static void setupAction(QAction *action);
+ // HiDPI stuff
+ static QPixmap pixmap(const QString &name);
+ static qreal maxSupportedPixelRatio() { return 2.0; }
+
private:
IconUtils() { }
static QImage grayscaled(const QImage &image);
#ifdef Q_OS_MAC
mac::MacMain();
- QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Helvetica Neue");
+ // QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Helvetica Neue");
#endif
QtSingleApplication app(argc, argv);
app.setOrganizationDomain(Constants::ORG_DOMAIN);
app.setApplicationVersion(Constants::VERSION);
app.setAttribute(Qt::AA_DontShowIconsInMenus);
-#ifndef APP_WIN
app.setWheelScrollLines(1);
-#endif
+ app.setAttribute(Qt::AA_UseHighDpiPixmaps);
#ifdef APP_EXTRA
Extra::appSetup(&app);
else title += QLatin1String(" - ") + Constants::NAME;
setWindowTitle(title);
+ statusToolBar->setUpdatesEnabled(false);
+
// dynamic view actions
foreach (QAction* action, viewActions)
showActionInStatusBar(action, false);
adjustStatusBarVisibility();
messageLabel->hide();
+ statusToolBar->setUpdatesEnabled(true);
+
/*
QString desc = metadata.value("description").toString();
if (!desc.isEmpty()) showMessage(desc);
bool MainWindow::confirmQuit() {
if (DownloadManager::instance()->activeItems() > 0) {
QMessageBox msgBox(this);
- msgBox.setIconPixmap(QPixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
+ msgBox.setIconPixmap(IconUtils::pixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
msgBox.setText(tr("Do you want to exit %1 with a download in progress?").arg(Constants::NAME));
msgBox.setInformativeText(tr("If you close %1 now, this download will be cancelled.").arg(Constants::NAME));
msgBox.setModal(true);
#ifdef APP_MAC
if (initialized && mac::CanGoFullScreen(winId())) {
bool isFullscreen = mac::IsFullScreen(winId());
- qDebug() << __PRETTY_FUNCTION__ << isFullscreen << fullscreenFlag;
if (isFullscreen != fullscreenFlag) {
if (compactViewAct->isChecked()) {
compactViewAct->setChecked(false);
void MainWindow::simpleUpdateDialog(const QString &version) {
QMessageBox msgBox(this);
msgBox.setIconPixmap(
- QPixmap(":/images/app.png")
+ IconUtils::pixmap(":/images/app.png")
.scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
msgBox.setText(tr("%1 version %2 is now available.").arg(Constants::NAME, version));
msgBox.setModal(true);
QSlider *slider = MainWindow::instance()->getSlider();
slider->setEnabled(false);
slider->setValue(0);
+#else
+ Phonon::SeekSlider *slider = MainWindow::instance()->getSeekSlider();
#endif
if (snapshotSettings) {
#endif
QMessageBox msgBox(this);
- msgBox.setIconPixmap(QPixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
+ msgBox.setIconPixmap(IconUtils::pixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
msgBox.setText(tr("This is just the demo version of %1.").arg(Constants::NAME));
msgBox.setInformativeText(tr("It allows you to test the application and see if it works for you."));
msgBox.setModal(true);
#include "painterutils.h"
#include "fontutils.h"
+#include "iconutils.h"
PainterUtils::PainterUtils() { }
}
void PainterUtils::paintBadge(QPainter *painter, const QString &text, bool center) {
- static const QPixmap badge1 = QPixmap(":/images/badge.png");
- static const QPixmap badge3 = QPixmap(":/images/badge3.png");
- static const QPixmap badge4 = QPixmap(":/images/badge4.png");
- static const int size = badge1.height();
+ const QPixmap badge1 = IconUtils::pixmap(":/images/badge.png");
+ const QPixmap badge3 = IconUtils::pixmap(":/images/badge3.png");
+ const QPixmap badge4 = IconUtils::pixmap(":/images/badge4.png");
const int textSize = text.size();
else if (textSize == 3) badge = badge3;
else badge = badge4;
+ const int w = badge.width() / badge.devicePixelRatio();
+ const int h = badge.height() / badge.devicePixelRatio();
+
int x = 0;
- if (center) x -= badge.width() / 2;
+ if (center) x -= w / 2;
- QRect rect(x, 0, badge.width(), size);
+ QRect rect(x, 0, w, h);
painter->drawPixmap(rect, badge);
QFont f = painter->font();
}
void PlaylistItemDelegate::createPlayIcon() {
- playIcon = QPixmap(THUMB_WIDTH, THUMB_HEIGHT);
+ qreal maxRatio = IconUtils::maxSupportedPixelRatio();
+ playIcon = QPixmap(THUMB_WIDTH * maxRatio, THUMB_HEIGHT * maxRatio);
+ playIcon.setDevicePixelRatio(maxRatio);
playIcon.fill(Qt::transparent);
- QPixmap tempPixmap(THUMB_WIDTH, THUMB_HEIGHT);
+ QPixmap tempPixmap(THUMB_WIDTH * maxRatio, THUMB_HEIGHT * maxRatio);
+ tempPixmap.setDevicePixelRatio(maxRatio);
tempPixmap.fill(Qt::transparent);
QPainter painter(&tempPixmap);
painter.setRenderHints(QPainter::Antialiasing, true);
// play icon overlayed on the thumb
if (isActive)
- painter->drawPixmap(playIcon.rect(), playIcon);
+ painter->drawPixmap(0, 0, playIcon);
// time
if (video->duration() > 0)
-include(../common.pri)
INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
QT *= network
$END_LICENSE */
#include "refinesearchbutton.h"
-
-static const int refineButtonSize = 48;
+#include "iconutils.h"
RefineSearchButton::RefineSearchButton(QWidget *parent) :
QPushButton(parent) {
hovered = false;
+ const int refineButtonSize = 48;
setMinimumSize(refineButtonSize, refineButtonSize);
setMaximumSize(refineButtonSize, refineButtonSize);
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
- setStyleSheet(
- "background: red url(:/images/refine-search.png) no-repeat center;"
- "border: 0;"
- );
}
void RefineSearchButton::paintBackground() const {
}
void RefineSearchButton::paintEvent(QPaintEvent *) {
- // QPushButton::paintEvent(event);
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing, true);
+ painter.setPen(Qt::NoPen);
painter.setBrush(QColor(0,0,0, hovered ? 192 : 170));
- QPen pen(Qt::white);
- pen.setWidth(2);
- painter.setPen(pen);
painter.drawEllipse(QPoint(width(), height()), width()-2, height()-2);
- QPixmap icon = QPixmap(":/images/refine-search.png");
- painter.drawPixmap(width() - icon.width() - 6, height() - icon.height() - 6,
- icon.width(), icon.height(),
- icon);
+ QPixmap pixmap = IconUtils::pixmap(":/images/refine-search.png");
+ int pw = pixmap.width() / pixmap.devicePixelRatio();
+ int ph = pixmap.height() / pixmap.devicePixelRatio();
+ painter.drawPixmap(width() - pw - 6, height() - ph - 6,
+ pw, ph,
+ pixmap);
}
void RefineSearchButton::enterEvent(QEvent *) {
#ifdef APP_EXTRA
#include "extra.h"
#endif
+#include "iconutils.h"
namespace The {
QHash<QString, QAction*>* globalActions();
QLabel *icon = new QLabel(this);
icon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
QString resource = paramName;
- QPixmap pixmap = QPixmap(":/images/search-" + resource + ".png");
+ QPixmap pixmap = IconUtils::pixmap(":/images/search-" + resource + ".png");
+ /*
QPixmap translucentPixmap(pixmap.size());
translucentPixmap.fill(Qt::transparent);
QPainter painter;
painter.setOpacity(0.5);
painter.drawPixmap(0, 0, pixmap);
painter.end();
- icon->setPixmap(translucentPixmap);
+ */
+ icon->setPixmap(pixmap);
hLayout->addWidget(icon);
QLabel *label = new QLabel(text, this);
- label->setStyleSheet("color: rgba(0, 0, 0, 128);");
hLayout->addWidget(label);
icon->setMaximumHeight(label->height());
#endif
#include "mainwindow.h"
#include "painterutils.h"
+#include "iconutils.h"
namespace The {
QHash<QString, QAction*>* globalActions();
mainLayout->addLayout(hLayout);
QLabel *logo = new QLabel(this);
- logo->setPixmap(QPixmap(":/images/app.png"));
+ logo->setPixmap(IconUtils::pixmap(":/images/app.png"));
hLayout->addWidget(logo, 0, Qt::AlignTop);
hLayout->addSpacing(PADDING);
itemLabel->setAttribute(Qt::WA_DeleteOnClose);
itemLabel->setProperty("recentItem", true);
itemLabel->setMaximumWidth(queryEdit->toWidget()->width() + watchButton->width());
- // itemLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ itemLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
// Make links navigable with the keyboard too
itemLabel->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse);
if (needStatusTip)
return(d->actionList[buttonIndex]);
}
-int SegmentedControl::calculateButtonWidth (void) const {
+int SegmentedControl::calculateButtonWidth() const {
QFontMetrics fontMetrics(font());
int tmpItemWidth, itemWidth = 0;
foreach (QAction *action, d->actionList) {
void SegmentedControl::drawUnselectedButton (QPainter *painter,
const QRect& rect,
const QAction *action) {
- painter->setPen(QPen(QColor(0, 0, 0, 128), 1));
paintButton(painter, rect, action);
}
painter->fillRect(0, 0, width, height, QBrush(gradient));
painter->restore();
- painter->setPen(QPen(QColor(0, 0, 0, 232), 1));
paintButton(painter, rect, action);
}
const int width = rect.width();
painter->save();
- painter->setPen(borderColor);
+ painter->setPen(QPen(borderColor, 1.0 / qApp->devicePixelRatio()));
#if defined(APP_MAC) | defined(APP_WIN)
painter->drawRect(-1, -1, width, height);
#else
const QRect& rect,
const QAction *action);
QAction *hoveredAction(const QPoint& pos) const;
- int calculateButtonWidth(void) const;
+ int calculateButtonWidth() const;
class Private;
Private *d;
connect(reply, SIGNAL(data(QByteArray)), SLOT(setThumbnail(QByteArray)));
}
-void Video::setThumbnail(QByteArray bytes) {
+void Video::setThumbnail(const QByteArray &bytes) {
loadingThumbnail = false;
+ qreal ratio = qApp->devicePixelRatio();
m_thumbnail = QPixmap();
m_thumbnail.loadFromData(bytes);
- if (m_thumbnail.width() > 160)
- m_thumbnail = m_thumbnail.scaledToWidth(160, Qt::SmoothTransformation);
+ m_thumbnail.setDevicePixelRatio(ratio);
+ const int thumbWidth = 160 * ratio;
+ if (m_thumbnail.width() > thumbWidth)
+ m_thumbnail = m_thumbnail.scaledToWidth(thumbWidth, Qt::SmoothTransformation);
+ qDebug() << __PRETTY_FUNCTION__ << m_thumbnail.size();
emit gotThumbnail();
}
-void Video::loadMediumThumbnail() {
- if (m_mediumThumbnailUrl.isEmpty()) return;
- QObject *reply = The::http()->get(m_mediumThumbnailUrl);
- connect(reply, SIGNAL(data(QByteArray)), SIGNAL(gotMediumThumbnail(QByteArray)));
-}
-
void Video::loadStreamUrl() {
if (loadingStreamUrl) {
qDebug() << "Already loading stream URL for" << this->title();
// see you in gotVideoInfo...
}
-void Video::gotVideoInfo(QByteArray data) {
- QString videoInfo = QString::fromUtf8(data);
+void Video::gotVideoInfo(const QByteArray &bytes) {
+ QString videoInfo = QString::fromUtf8(bytes);
// qDebug() << "videoInfo" << videoInfo;
// get video token
emit errorStreamUrl(tr("Network error: %1 for %2").arg(reply->errorString(), reply->url().toString()));
}
-void Video::scrapeWebPage(QByteArray data) {
- QString html = QString::fromUtf8(data);
+void Video::scrapeWebPage(const QByteArray &bytes) {
+ QString html = QString::fromUtf8(bytes);
QRegExp ageGateRE(JsFunctions::instance()->ageGateRE());
if (ageGateRE.indexIn(html) != -1) {
}
}
-void Video::parseJsPlayer(QByteArray bytes) {
+void Video::parseJsPlayer(const QByteArray &bytes) {
QString js = QString::fromUtf8(bytes);
// qWarning() << "jsPlayer" << js;
parseFmtUrlMap(fmtUrlMap, true);
}
-void Video::parseDashManifest(QByteArray bytes) {
+void Video::parseDashManifest(const QByteArray &bytes) {
QFile file(Temporary::filename() + ".mpd");
if (!file.open(QIODevice::WriteOnly))
qWarning() << file.errorString() << file.fileName();
LicenseCC
};
- const QString & title() const { return m_title; }
- void setTitle(const QString &title) { m_title = title; }
+ const QString &title() const { return m_title; }
+ void setTitle(const QString &value) { m_title = value; }
- const QString & description() const { return m_description; }
- void setDescription(const QString &description) { m_description = description; }
+ const QString &description() const { return m_description; }
+ void setDescription(const QString &value) { m_description = value; }
- const QString & channelTitle() const { return m_channelTitle; }
+ const QString &channelTitle() const { return m_channelTitle; }
void setChannelTitle(const QString &value) { m_channelTitle = value; }
- const QString & channelId() const { return m_channelId; }
+ const QString &channelId() const { return m_channelId; }
void setChannelId(const QString &value ) { m_channelId = value; }
- const QString & webpage();
+ const QString &webpage();
void setWebpage(const QString &value);
void loadThumbnail();
- const QPixmap & thumbnail() const { return m_thumbnail; }
+ const QPixmap &thumbnail() const { return m_thumbnail; }
- const QString & thumbnailUrl() { return m_thumbnailUrl; }
- void setThumbnailUrl(const QString &url) { m_thumbnailUrl = url; }
+ const QString &thumbnailUrl() { return m_thumbnailUrl; }
+ void setThumbnailUrl(const QString &value) { m_thumbnailUrl = value; }
- void loadMediumThumbnail();
- const QString & mediumThumbnailUrl() { return m_mediumThumbnailUrl; }
- void setMediumThumbnailUrl(const QString &url) { m_mediumThumbnailUrl = url; }
+ const QString &mediumThumbnailUrl() { return m_mediumThumbnailUrl; }
+ void setMediumThumbnailUrl(const QString &value) { m_mediumThumbnailUrl = value; }
+
+ const QString &largeThumbnailUrl() { return m_largeThumbnailUrl; }
+ void setLargeThumbnailUrl(const QString &value) { m_largeThumbnailUrl = value; }
int duration() const { return m_duration; }
- void setDuration( int duration ) { m_duration = duration; }
+ void setDuration(int value) { m_duration = value; }
QString formattedDuration() const;
int viewCount() const { return m_viewCount; }
- void setViewCount( int viewCount ) { m_viewCount = viewCount; }
+ void setViewCount(int viewCount) { m_viewCount = viewCount; }
- const QDateTime & published() const { return m_published; }
- void setPublished(const QDateTime &published ) { m_published = published; }
+ const QDateTime &published() const { return m_published; }
+ void setPublished(const QDateTime &value) { m_published = value; }
int getDefinitionCode() const { return definitionCode; }
void loadStreamUrl();
- const QUrl & getStreamUrl() { return m_streamUrl; }
+ const QUrl &getStreamUrl() { return m_streamUrl; }
void setId(const QString &value) { videoId = value; }
- const QString & id() const { return videoId; }
+ const QString &id() const { return videoId; }
- void setLicense(License license) { m_license = license; }
+ void setLicense(License value) { m_license = value; }
License license() const { return m_license; }
signals:
void gotThumbnail();
- void gotMediumThumbnail(QByteArray bytes);
- void gotStreamUrl(QUrl streamUrl);
- void errorStreamUrl(QString message);
+ void gotMediumThumbnail(const QByteArray &bytes);
+ void gotLargeThumbnail(const QByteArray &bytes);
+ void gotStreamUrl(const QUrl &streamUrl);
+ void errorStreamUrl(const QString &message);
private slots:
- void setThumbnail(QByteArray bytes);
- void gotVideoInfo(QByteArray);
- void errorVideoInfo(QNetworkReply*);
- void scrapeWebPage(QByteArray);
- void parseJsPlayer(QByteArray bytes);
- void parseDashManifest(QByteArray bytes);
+ void setThumbnail(const QByteArray &bytes);
+ void gotVideoInfo(const QByteArray &bytes);
+ void errorVideoInfo(QNetworkReply *reply);
+ void scrapeWebPage(const QByteArray &bytes);
+ void parseJsPlayer(const QByteArray &bytes);
+ void parseDashManifest(const QByteArray &bytes);
private:
void getVideoInfo();
void captureFunction(const QString &name, const QString &js);
void captureObject(const QString &name, const QString &js);
QString decryptSignature(const QString &s);
- void saveDefinitionForUrl(const QString& url, const VideoDefinition& definition);
+ void saveDefinitionForUrl(const QString &url, const VideoDefinition &definition);
QString m_title;
QString m_description;
QPixmap m_thumbnail;
QString m_thumbnailUrl;
QString m_mediumThumbnailUrl;
+ QString m_largeThumbnailUrl;
int m_duration;
QDateTime m_published;
int m_viewCount;
#include "videosource.h"
#include "video.h"
#include "fontutils.h"
+#include "iconutils.h"
+#include "networkaccess.h"
+
+namespace The {
+NetworkAccess* http();
+}
VideoSourceWidget::VideoSourceWidget(VideoSource *videoSource, QWidget *parent)
: GridWidget(parent),
- videoSource(videoSource) {
+ videoSource(videoSource),
+ lastPixelRatio(0) {
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- connect(videoSource, SIGNAL(gotVideos(QList<Video*>)),
- SLOT(previewVideo(QList<Video*>)), Qt::UniqueConnection);
- videoSource->loadVideos(1, 1);
+ loadPreview();
connect(this, SIGNAL(activated()), SLOT(activate()));
}
emit activated(videoSource);
}
-void VideoSourceWidget::previewVideo(QList<Video*> videos) {
+void VideoSourceWidget::previewVideo(const QList<Video *> &videos) {
videoSource->disconnect();
if (videos.isEmpty()) return;
- video = videos.first();
- connect(video, SIGNAL(gotMediumThumbnail(QByteArray)),
- SLOT(setPixmapData(QByteArray)), Qt::UniqueConnection);
- video->loadMediumThumbnail();
+ Video *video = videos.first();
+ lastPixelRatio = window()->devicePixelRatio();
+ bool needLargeThumb = lastPixelRatio > 1.0 || window()->width() > 2000;
+ QString url = needLargeThumb ? video->largeThumbnailUrl() : video->mediumThumbnailUrl();
+ if (url.isEmpty()) url = video->mediumThumbnailUrl();
+ video->deleteLater();
+ QObject *reply = The::http()->get(url);
+ connect(reply, SIGNAL(data(QByteArray)), SLOT(setPixmapData(QByteArray)));
}
-void VideoSourceWidget::setPixmapData(QByteArray bytes) {
- video->deleteLater();
- video = 0;
+void VideoSourceWidget::setPixmapData(const QByteArray &bytes) {
pixmap.loadFromData(bytes);
+ pixmap.setDevicePixelRatio(lastPixelRatio);
update();
}
+void VideoSourceWidget::loadPreview() {
+ connect(videoSource, SIGNAL(gotVideos(QList<Video*>)),
+ SLOT(previewVideo(QList<Video*>)), Qt::UniqueConnection);
+ videoSource->loadVideos(1, 1);
+}
+
QPixmap VideoSourceWidget::playPixmap() {
const int s = height() / 2;
const int padding = s / 8;
- QPixmap playIcon = QPixmap(s, s);
+
+ qreal ratio = window()->devicePixelRatio();
+ QPixmap playIcon = QPixmap(s * ratio, s * ratio);
+ playIcon.setDevicePixelRatio(ratio);
playIcon.fill(Qt::transparent);
QPainter painter(&playIcon);
QPolygon polygon;
void VideoSourceWidget::paintEvent(QPaintEvent *event) {
GridWidget::paintEvent(event);
if (pixmap.isNull()) return;
+ if (window()->devicePixelRatio() != lastPixelRatio) loadPreview();
QPainter p(this);
- const int w = width();
- const int h = height();
+ qreal ratio = lastPixelRatio;
+ int w = width() * ratio;
+ int h = height() * ratio;
int xOffset = 0;
int xOrigin = 0;
else yOrigin = -hDiff / 2;
p.drawPixmap(xOrigin, yOrigin, pixmap, xOffset, yOffset, w, h);
+ w = width();
+ h = height();
+
if (hovered) {
QPixmap play = playPixmap();
p.save();
p.setOpacity(.5);
p.drawPixmap(
- (w - play.width()) / 2,
- (h * 2/3 - play.height()) / 2,
+ (w - play.width() * ratio) / 2,
+ (h * 2/3 - play.height() * ratio) / 2,
play
);
p.restore();
private slots:
void activate();
- void previewVideo(QList<Video*> videos);
- void setPixmapData(QByteArray bytes);
+ void previewVideo(const QList<Video*> &videos);
+ void setPixmapData(const QByteArray &bytes);
private:
+ void loadPreview();
+
QPixmap playPixmap();
VideoSource *videoSource;
QPixmap pixmap;
- Video *video;
+ qreal lastPixelRatio;
};
#include "datautils.h"
YT3ListParser::YT3ListParser(const QByteArray &bytes) {
-
QScriptEngine engine;
QScriptValue json = engine.evaluate("(" + QString::fromUtf8(bytes) + ")");
QScriptValue thumbnails = snippet.property("thumbnails");
video->setThumbnailUrl(thumbnails.property("medium").property("url").toString());
video->setMediumThumbnailUrl(thumbnails.property("high").property("url").toString());
+ video->setLargeThumbnailUrl(thumbnails.property("standard").property("url").toString());
video->setChannelTitle(snippet.property("channelTitle").toString());
#endif
#include "compatibility/qurlqueryhelper.h"
#include "compatibility/pathsservice.h"
+#include "iconutils.h"
namespace The {
NetworkAccess* http();
channel->checked = query.value(6).toUInt();
channel->loaded = query.value(7).toUInt();
channel->thumbnail = QPixmap(channel->getThumbnailLocation());
+ channel->thumbnail.setDevicePixelRatio(IconUtils::maxSupportedPixelRatio());
channel->maybeLoadfromAPI();
cache.insert(channelId, channel);
}
displayName = snippet.property("title").toString();
description = snippet.property("description").toString();
QScriptValue thumbnails = snippet.property("thumbnails");
- thumbnailUrl = thumbnails.property("default").property("url").toString();
+ thumbnailUrl = thumbnails.property("medium").property("url").toString();
qDebug() << displayName << description << thumbnailUrl;
}
}
if (thumbnailUrl.isEmpty()) return;
loadingThumbnail = true;
-#ifdef Q_OS_WIN
- thumbnailUrl.replace(QLatin1String("https://"), QLatin1String("http://"));
-#endif
-
QUrl url(thumbnailUrl);
QObject *reply = The::http()->get(url);
connect(reply, SIGNAL(data(QByteArray)), SLOT(storeThumbnail(QByteArray)));
void YTChannel::storeThumbnail(const QByteArray &bytes) {
thumbnail.loadFromData(bytes);
- static const int maxWidth = 88;
+ qreal maxRatio = IconUtils::maxSupportedPixelRatio();
+ thumbnail.setDevicePixelRatio(maxRatio);
+ const int maxWidth = 88 * maxRatio;
QDir dir;
dir.mkpath(getThumbnailDir());
if (thumbnail.width() > maxWidth) {
thumbnail = thumbnail.scaledToWidth(maxWidth, Qt::SmoothTransformation);
+ thumbnail.setDevicePixelRatio(maxRatio);
thumbnail.save(getThumbnailLocation(), "JPG");
} else {
QFile file(getThumbnailLocation());