[UI] Minor tweaks, fixes and better screenshot handling.
This commit is contained in:
parent
772247a17d
commit
56fb9c19dc
|
@ -8,8 +8,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -fstrict-aliasing -Wno-dep
|
||||||
|
|
||||||
option(DEVELOP "Enable runtime QML reloading for developing." OFF)
|
option(DEVELOP "Enable runtime QML reloading for developing." OFF)
|
||||||
|
|
||||||
|
|
||||||
find_package(Qt5Core REQUIRED)
|
find_package(Qt5Core REQUIRED)
|
||||||
|
find_package(Qt5Gui REQUIRED)
|
||||||
find_package(Qt5 REQUIRED Qml Quick Gui Widgets Core)
|
find_package(Qt5 REQUIRED Qml Quick Gui Widgets Core)
|
||||||
|
|
||||||
find_package(Qt5QuickCompiler)
|
find_package(Qt5QuickCompiler)
|
||||||
|
@ -18,14 +18,20 @@ qtquick_compiler_add_resources(qml_QRC src/qml/qml.qrc)
|
||||||
find_package(PkgConfig)
|
find_package(PkgConfig)
|
||||||
pkg_check_modules(MPV REQUIRED mpv)
|
pkg_check_modules(MPV REQUIRED mpv)
|
||||||
|
|
||||||
|
|
||||||
|
include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS})
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
src/mpvobject.cpp
|
src/mpvobject.cpp
|
||||||
|
src/filesavedialog.cpp
|
||||||
|
src/fileopendialog.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(DEVELOP)
|
if(DEVELOP)
|
||||||
set(SOURCES ${SOURCES} runtimeqml/runtimeqml.cpp)
|
set(SOURCES ${SOURCES} runtimeqml/runtimeqml.cpp)
|
||||||
add_definitions(-DQRC_SOURCE_PATH="${PROJECT_SOURCE_DIR}/src/qml")
|
add_definitions(-DQRC_SOURCE_PATH="${PROJECT_SOURCE_DIR}/src/qml")
|
||||||
|
add_definitions(-DQT_QML_DEBUG)
|
||||||
endif(DEVELOP)
|
endif(DEVELOP)
|
||||||
|
|
||||||
add_executable(KittehPlayer ${SOURCES} ${qml_QRC})
|
add_executable(KittehPlayer ${SOURCES} ${qml_QRC})
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
TARGET = KittehPlayer
|
TARGET = KittehPlayer
|
||||||
|
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
QT += qml quickcontrols2 widgets
|
QT += qml quickcontrols2 widgets core-private gui-private
|
||||||
|
SOURCES += src/main.cpp src/mpvobject.cpp src/filesavedialog.cpp src/fileopendialog.cpp
|
||||||
SOURCES += src/main.cpp src/mpvobject.cpp
|
|
||||||
|
|
||||||
CONFIG += release
|
CONFIG += release
|
||||||
CONFIG+=qtquickcompiler
|
CONFIG+=qtquickcompiler
|
||||||
|
@ -13,7 +12,7 @@ PKGCONFIG += mpv
|
||||||
RESOURCES += src/qml/qml.qrc
|
RESOURCES += src/qml/qml.qrc
|
||||||
|
|
||||||
unix {
|
unix {
|
||||||
isEmpty(PREFIX) {
|
isEmpty {
|
||||||
PREFIX = /usr
|
PREFIX = /usr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +29,7 @@ unix {
|
||||||
|
|
||||||
INSTALLS += target
|
INSTALLS += target
|
||||||
|
|
||||||
HEADERS += src/mpvobject.h src/config.h
|
HEADERS += src/mpvobject.h src/config.h src/filesavedialog.h src/fileopendialog.h
|
||||||
|
|
||||||
|
|
||||||
DISTFILES += KittehPlayer.desktop KittehPlayer.png README.md LICENSE.txt
|
DISTFILES += KittehPlayer.desktop KittehPlayer.png README.md LICENSE.txt
|
||||||
|
|
226
src/fileopendialog.cpp
Normal file
226
src/fileopendialog.cpp
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
/* Copyright 2013–2017 Kullo GmbH. All rights reserved. */
|
||||||
|
#include "fileopendialog.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QQuickWindow>
|
||||||
|
|
||||||
|
FileOpenDialog::FileOpenDialog(QQuickItem *parent)
|
||||||
|
: QQuickItem(parent)
|
||||||
|
, m_dlgHelper(init_helper())
|
||||||
|
, m_modality(Qt::WindowModal)
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
|
||||||
|
, m_options(QFileDialogOptions::create())
|
||||||
|
#else
|
||||||
|
, m_options(QSharedPointer<QFileDialogOptions>(new QFileDialogOptions()))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Qt Widgets support must be present, i.e. the main app is a QApplication.
|
||||||
|
* The following line break at compile time, if the main app is a QGuiApplication
|
||||||
|
*/
|
||||||
|
QApplication *appHasQtWidgetsSupport = qobject_cast<QApplication *>(QCoreApplication::instance());
|
||||||
|
Q_ASSERT(appHasQtWidgetsSupport);
|
||||||
|
Q_UNUSED(appHasQtWidgetsSupport);
|
||||||
|
|
||||||
|
if (valid())
|
||||||
|
{
|
||||||
|
connect(m_dlgHelper, &QPlatformFileDialogHelper::accept,
|
||||||
|
this, &FileOpenDialog::accept);
|
||||||
|
connect(m_dlgHelper, &QPlatformFileDialogHelper::reject,
|
||||||
|
this, &FileOpenDialog::reject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileOpenDialog::~FileOpenDialog()
|
||||||
|
{
|
||||||
|
if (m_dlgHelper)
|
||||||
|
m_dlgHelper->hide();
|
||||||
|
delete m_dlgHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileOpenDialog::valid() const
|
||||||
|
{
|
||||||
|
if (m_dlgHelper) return true;
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl FileOpenDialog::fileUrl() const
|
||||||
|
{
|
||||||
|
return fileUrl_;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QUrl> FileOpenDialog::fileUrls() const
|
||||||
|
{
|
||||||
|
return fileUrls_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileOpenDialog::setFileUrl(QUrl fileUrl)
|
||||||
|
{
|
||||||
|
if (fileUrl_ != fileUrl)
|
||||||
|
{
|
||||||
|
fileUrl_ = fileUrl;
|
||||||
|
emit fileUrlChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileOpenDialog::setFileUrls(QList<QUrl> fileUrls)
|
||||||
|
{
|
||||||
|
if (fileUrls_ != fileUrls)
|
||||||
|
{
|
||||||
|
fileUrls_ = fileUrls;
|
||||||
|
emit fileUrlsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FileOpenDialog::filename() const
|
||||||
|
{
|
||||||
|
return filename_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileOpenDialog::setFilename(QString filename)
|
||||||
|
{
|
||||||
|
if (filename_ != filename)
|
||||||
|
{
|
||||||
|
filename_ = filename;
|
||||||
|
emit filenameChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FileOpenDialog::title() const
|
||||||
|
{
|
||||||
|
return title_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileOpenDialog::setTitle(QString title)
|
||||||
|
{
|
||||||
|
if (title_ != title)
|
||||||
|
{
|
||||||
|
title_ = title;
|
||||||
|
emit titleChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList FileOpenDialog::nameFilters() const
|
||||||
|
{
|
||||||
|
return nameFilters_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileOpenDialog::setNameFilters(QStringList nameFilters)
|
||||||
|
{
|
||||||
|
if (nameFilters_ != nameFilters)
|
||||||
|
{
|
||||||
|
nameFilters_ = nameFilters;
|
||||||
|
emit nameFiltersChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileOpenDialog::selectMultiple() const
|
||||||
|
{
|
||||||
|
return selectMultiple_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileOpenDialog::setSelectMultiple(bool selectMultiple)
|
||||||
|
{
|
||||||
|
if (selectMultiple_ != selectMultiple)
|
||||||
|
{
|
||||||
|
selectMultiple_ = selectMultiple;
|
||||||
|
emit selectMultipleChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QPlatformFileDialogHelper* FileOpenDialog::init_helper()
|
||||||
|
{
|
||||||
|
return static_cast<QPlatformFileDialogHelper*>(
|
||||||
|
QGuiApplicationPrivate::platformTheme()->createPlatformDialogHelper(QPlatformTheme::FileDialog)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileOpenDialog::open()
|
||||||
|
{
|
||||||
|
if (!valid()) return;
|
||||||
|
|
||||||
|
QQuickItem *parent = this->parentItem();
|
||||||
|
Q_ASSERT(parent);
|
||||||
|
|
||||||
|
QQuickWindow *window = parent->window();
|
||||||
|
Q_ASSERT(window);
|
||||||
|
|
||||||
|
m_parentWindow = window;
|
||||||
|
|
||||||
|
m_options->setFileMode(selectMultiple_ ? QFileDialogOptions::ExistingFiles : QFileDialogOptions::ExistingFile);
|
||||||
|
m_options->setAcceptMode(QFileDialogOptions::AcceptOpen);
|
||||||
|
m_options->setWindowTitle(title());
|
||||||
|
m_options->setNameFilters(nameFilters());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mac:
|
||||||
|
* Set filename incl. directory via setInitiallySelectedFiles()
|
||||||
|
*
|
||||||
|
* Windows:
|
||||||
|
* Set filename via setInitiallySelectedFiles() and let Windows choose the directory.
|
||||||
|
* Default directory: C:\\Users\XYZ\Downloads
|
||||||
|
*
|
||||||
|
* Gnome:
|
||||||
|
* Set directory via QPlatformFileDialogHelper::setDirectory() and leave
|
||||||
|
* filename empty, since QGtk2FileDialogHelper can not set non-existing filenames.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifdef Q_OS_OSX
|
||||||
|
QString initialSelection = QFileInfo(QDir::homePath(), filename()).absoluteFilePath();
|
||||||
|
//qDebug() << "Initial file:" << initialSelection;
|
||||||
|
m_options->setInitiallySelectedFiles(QList<QUrl>() << QUrl::fromLocalFile(initialSelection));
|
||||||
|
#endif
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
//qDebug() << "Initial filename:" << filename();
|
||||||
|
m_options->setInitiallySelectedFiles(QList<QUrl>() << QUrl::fromLocalFile(filename()));
|
||||||
|
#endif
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
//qDebug() << "Initial directory:" << QDir::homePath();
|
||||||
|
m_dlgHelper->setDirectory(QUrl::fromLocalFile(QDir::homePath()));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_dlgHelper->setOptions(m_options);
|
||||||
|
m_dlgHelper->setFilter(); // applyOptions();
|
||||||
|
|
||||||
|
Qt::WindowFlags flags = Qt::Dialog;
|
||||||
|
if (!title().isEmpty()) flags |= Qt::WindowTitleHint;
|
||||||
|
|
||||||
|
m_visible = m_dlgHelper->show(flags, m_modality, m_parentWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileOpenDialog::close()
|
||||||
|
{
|
||||||
|
if (!valid()) return;
|
||||||
|
|
||||||
|
m_dlgHelper->hide();
|
||||||
|
m_visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileOpenDialog::accept()
|
||||||
|
{
|
||||||
|
if (!valid()) return;
|
||||||
|
|
||||||
|
m_dlgHelper->hide();
|
||||||
|
|
||||||
|
QList<QUrl> selectedUrls = m_dlgHelper->selectedFiles();
|
||||||
|
if (!selectedUrls.empty())
|
||||||
|
{
|
||||||
|
if (selectedUrls.size() == 1)
|
||||||
|
setFileUrl(selectedUrls.at(0));
|
||||||
|
else
|
||||||
|
setFileUrl();
|
||||||
|
|
||||||
|
setFileUrls(selectedUrls);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit accepted();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileOpenDialog::reject()
|
||||||
|
{
|
||||||
|
if (!valid()) return;
|
||||||
|
|
||||||
|
m_dlgHelper->hide();
|
||||||
|
emit rejected();
|
||||||
|
}
|
86
src/fileopendialog.h
Normal file
86
src/fileopendialog.h
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/* Copyright 2013–2017 Kullo GmbH. All rights reserved. */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QQuickItem>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <private/qguiapplication_p.h>
|
||||||
|
#include <QtGui/qpa/qplatformdialoghelper.h>
|
||||||
|
#include <QtGui/qpa/qplatformtheme.h>
|
||||||
|
|
||||||
|
class FileOpenDialog : public QQuickItem
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FileOpenDialog(QQuickItem *parent = 0);
|
||||||
|
~FileOpenDialog();
|
||||||
|
|
||||||
|
Q_PROPERTY(bool valid READ valid NOTIFY validChanged)
|
||||||
|
bool valid() const;
|
||||||
|
|
||||||
|
Q_PROPERTY(QUrl fileUrl READ fileUrl NOTIFY fileUrlChanged)
|
||||||
|
QUrl fileUrl() const;
|
||||||
|
|
||||||
|
Q_PROPERTY(QList<QUrl> fileUrls READ fileUrls NOTIFY fileUrlsChanged)
|
||||||
|
QList<QUrl> fileUrls() const;
|
||||||
|
|
||||||
|
Q_PROPERTY(QString filename READ filename WRITE setFilename NOTIFY filenameChanged)
|
||||||
|
QString filename() const;
|
||||||
|
void setFilename(QString filename);
|
||||||
|
|
||||||
|
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
|
||||||
|
QString title() const;
|
||||||
|
void setTitle(QString title);
|
||||||
|
|
||||||
|
Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters NOTIFY nameFiltersChanged)
|
||||||
|
QStringList nameFilters() const;
|
||||||
|
void setNameFilters(QStringList nameFilters);
|
||||||
|
|
||||||
|
Q_PROPERTY(bool selectMultiple READ selectMultiple WRITE setSelectMultiple NOTIFY selectMultipleChanged)
|
||||||
|
bool selectMultiple() const;
|
||||||
|
void setSelectMultiple(bool selectMultiple);
|
||||||
|
|
||||||
|
Q_INVOKABLE void open();
|
||||||
|
Q_INVOKABLE void close();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void fileUrlChanged();
|
||||||
|
void fileUrlsChanged();
|
||||||
|
void filenameChanged();
|
||||||
|
void titleChanged();
|
||||||
|
void nameFiltersChanged();
|
||||||
|
void accepted();
|
||||||
|
void rejected();
|
||||||
|
void selectMultipleChanged();
|
||||||
|
|
||||||
|
// unused
|
||||||
|
void validChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QPlatformFileDialogHelper* init_helper();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QPlatformFileDialogHelper *m_dlgHelper;
|
||||||
|
QQuickWindow *m_parentWindow;
|
||||||
|
Qt::WindowModality m_modality;
|
||||||
|
bool m_visible;
|
||||||
|
QSharedPointer<QFileDialogOptions> m_options;
|
||||||
|
|
||||||
|
protected Q_SLOTS:
|
||||||
|
virtual void accept();
|
||||||
|
virtual void reject();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setFileUrl(QUrl fileUrl = QUrl());
|
||||||
|
void setFileUrls(QList<QUrl> fileUrls = QList<QUrl>());
|
||||||
|
|
||||||
|
QUrl fileUrl_;
|
||||||
|
QList<QUrl> fileUrls_;
|
||||||
|
QString filename_;
|
||||||
|
QString title_;
|
||||||
|
QStringList nameFilters_;
|
||||||
|
bool selectMultiple_ = false;
|
||||||
|
|
||||||
|
Q_DISABLE_COPY(FileOpenDialog)
|
||||||
|
};
|
208
src/filesavedialog.cpp
Normal file
208
src/filesavedialog.cpp
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
/* Copyright 2013–2017 Kullo GmbH. All rights reserved. */
|
||||||
|
#include "filesavedialog.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QQuickWindow>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
|
||||||
|
FileSaveDialog::FileSaveDialog(QQuickItem *parent)
|
||||||
|
: QQuickItem(parent)
|
||||||
|
, m_dlgHelper(init_helper())
|
||||||
|
, m_modality(Qt::WindowModal)
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
|
||||||
|
, m_options(QFileDialogOptions::create())
|
||||||
|
#else
|
||||||
|
, m_options(QSharedPointer<QFileDialogOptions>(new QFileDialogOptions()))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Qt Widgets support must be present, i.e. the main app is a QApplication.
|
||||||
|
* The following line break at compile time, if the main app is a QGuiApplication
|
||||||
|
*/
|
||||||
|
QApplication *appHasQtWidgetsSupport = qobject_cast<QApplication *>(QCoreApplication::instance());
|
||||||
|
Q_ASSERT(appHasQtWidgetsSupport);
|
||||||
|
Q_UNUSED(appHasQtWidgetsSupport);
|
||||||
|
|
||||||
|
if (valid())
|
||||||
|
{
|
||||||
|
connect(m_dlgHelper, &QPlatformFileDialogHelper::accept,
|
||||||
|
this, &FileSaveDialog::accept);
|
||||||
|
connect(m_dlgHelper, &QPlatformFileDialogHelper::reject,
|
||||||
|
this, &FileSaveDialog::reject);
|
||||||
|
}else{
|
||||||
|
qDebug() << "ERROR: You need the gtk3 platform plugin to use the file save dialog.";
|
||||||
|
qDebug() << "To automatically set gtk3 to QT_QPA_PLATFORMTHEME run the following at the command line";
|
||||||
|
qDebug() << "echo \"export QT_QPA_PLATFORMTHEME=gtk3\">> ~/.profile && source ~/.profile";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSaveDialog::~FileSaveDialog()
|
||||||
|
{
|
||||||
|
if (m_dlgHelper)
|
||||||
|
m_dlgHelper->hide();
|
||||||
|
delete m_dlgHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileSaveDialog::valid() const
|
||||||
|
{
|
||||||
|
if (m_dlgHelper) return true;
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl FileSaveDialog::fileUrl() const
|
||||||
|
{
|
||||||
|
return fileUrl_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSaveDialog::setFileUrl(QUrl fileUrl)
|
||||||
|
{
|
||||||
|
if (fileUrl_ != fileUrl)
|
||||||
|
{
|
||||||
|
fileUrl_ = fileUrl;
|
||||||
|
emit fileUrlChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FileSaveDialog::filename() const
|
||||||
|
{
|
||||||
|
return filename_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSaveDialog::setFilename(QString filename)
|
||||||
|
{
|
||||||
|
if (filename_ != filename)
|
||||||
|
{
|
||||||
|
filename_ = filename;
|
||||||
|
emit filenameChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FileSaveDialog::title() const
|
||||||
|
{
|
||||||
|
return title_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSaveDialog::setTitle(QString title)
|
||||||
|
{
|
||||||
|
if (title_ != title)
|
||||||
|
{
|
||||||
|
title_ = title;
|
||||||
|
emit titleChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList FileSaveDialog::nameFilters() const
|
||||||
|
{
|
||||||
|
return nameFilters_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSaveDialog::setNameFilters(QStringList nameFilters)
|
||||||
|
{
|
||||||
|
if (nameFilters_ != nameFilters)
|
||||||
|
{
|
||||||
|
nameFilters_ = nameFilters;
|
||||||
|
emit nameFiltersChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QPlatformFileDialogHelper* FileSaveDialog::init_helper()
|
||||||
|
{
|
||||||
|
return static_cast<QPlatformFileDialogHelper*>(
|
||||||
|
QGuiApplicationPrivate::platformTheme()->createPlatformDialogHelper(QPlatformTheme::FileDialog)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSaveDialog::open()
|
||||||
|
{
|
||||||
|
if (!valid()) return;
|
||||||
|
|
||||||
|
QQuickItem *parent = this->parentItem();
|
||||||
|
Q_ASSERT(parent);
|
||||||
|
|
||||||
|
QQuickWindow *window = parent->window();
|
||||||
|
Q_ASSERT(window);
|
||||||
|
|
||||||
|
m_parentWindow = window;
|
||||||
|
|
||||||
|
m_options->setFileMode(QFileDialogOptions::AnyFile);
|
||||||
|
m_options->setAcceptMode(QFileDialogOptions::AcceptSave);
|
||||||
|
m_options->setWindowTitle(title());
|
||||||
|
m_options->setNameFilters(nameFilters());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mac:
|
||||||
|
* Set filename incl. directory via setInitiallySelectedFiles()
|
||||||
|
*
|
||||||
|
* Windows:
|
||||||
|
* Set filename via setInitiallySelectedFiles() and let Windows choose the directory.
|
||||||
|
* Default directory: C:\\Users\XYZ\Downloads
|
||||||
|
*
|
||||||
|
* Gnome:
|
||||||
|
* Set directory via QPlatformFileDialogHelper::setDirectory() and leave
|
||||||
|
* filename empty, since QGtk2FileDialogHelper can not set non-existing filenames.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const QString folder = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
|
||||||
|
const QString name = filename();
|
||||||
|
|
||||||
|
#ifdef Q_OS_OSX
|
||||||
|
QUrl initialSelection = QUrl::fromLocalFile(QFileInfo(folder, name).absoluteFilePath());
|
||||||
|
//qDebug() << "Initial file:" << initialSelection;
|
||||||
|
m_options->setInitiallySelectedFiles(QList<QUrl>() << initialSelection);
|
||||||
|
#endif
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
//qDebug() << "Initial filename:" << name;
|
||||||
|
m_options->setInitiallySelectedFiles(QList<QUrl>() << QUrl::fromLocalFile(name));
|
||||||
|
#endif
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 2))
|
||||||
|
// Wohoo, big fix! https://codereview.qt-project.org/91501
|
||||||
|
QUrl initialSelection = QUrl::fromLocalFile(QFileInfo(folder, name).absoluteFilePath());
|
||||||
|
//qDebug() << "Initial file:" << initialSelection;
|
||||||
|
m_options->setInitiallySelectedFiles(QList<QUrl>() << initialSelection);
|
||||||
|
#else
|
||||||
|
//qDebug() << "Initial directory:" << folder;
|
||||||
|
m_dlgHelper->setDirectory(QUrl::fromLocalFile(folder));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_dlgHelper->setOptions(m_options);
|
||||||
|
m_dlgHelper->setFilter(); // applyOptions();
|
||||||
|
|
||||||
|
Qt::WindowFlags flags = Qt::Dialog;
|
||||||
|
if (!title().isEmpty()) flags |= Qt::WindowTitleHint;
|
||||||
|
|
||||||
|
m_visible = m_dlgHelper->show(flags, m_modality, m_parentWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSaveDialog::close()
|
||||||
|
{
|
||||||
|
if (!valid()) return;
|
||||||
|
|
||||||
|
m_dlgHelper->hide();
|
||||||
|
m_visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSaveDialog::accept()
|
||||||
|
{
|
||||||
|
if (!valid()) return;
|
||||||
|
|
||||||
|
m_dlgHelper->hide();
|
||||||
|
|
||||||
|
QList<QUrl> selectedUrls = m_dlgHelper->selectedFiles();
|
||||||
|
if (!selectedUrls.empty())
|
||||||
|
{
|
||||||
|
setFileUrl(selectedUrls.at(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
emit accepted();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSaveDialog::reject()
|
||||||
|
{
|
||||||
|
if (!valid()) return;
|
||||||
|
|
||||||
|
m_dlgHelper->hide();
|
||||||
|
emit rejected();
|
||||||
|
}
|
74
src/filesavedialog.h
Normal file
74
src/filesavedialog.h
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/* Copyright 2013–2017 Kullo GmbH. All rights reserved. */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QQuickItem>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <private/qguiapplication_p.h>
|
||||||
|
#include <QtGui/qpa/qplatformdialoghelper.h>
|
||||||
|
#include <QtGui/qpa/qplatformtheme.h>
|
||||||
|
|
||||||
|
class FileSaveDialog : public QQuickItem
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FileSaveDialog(QQuickItem *parent = 0);
|
||||||
|
~FileSaveDialog();
|
||||||
|
|
||||||
|
Q_PROPERTY(bool valid READ valid NOTIFY validChanged)
|
||||||
|
bool valid() const;
|
||||||
|
|
||||||
|
Q_PROPERTY(QUrl fileUrl READ fileUrl NOTIFY fileUrlChanged)
|
||||||
|
QUrl fileUrl() const;
|
||||||
|
|
||||||
|
Q_PROPERTY(QString filename READ filename WRITE setFilename NOTIFY filenameChanged)
|
||||||
|
QString filename() const;
|
||||||
|
void setFilename(QString filename);
|
||||||
|
|
||||||
|
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
|
||||||
|
QString title() const;
|
||||||
|
void setTitle(QString title);
|
||||||
|
|
||||||
|
Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters NOTIFY nameFiltersChanged)
|
||||||
|
QStringList nameFilters() const;
|
||||||
|
void setNameFilters(QStringList nameFilters);
|
||||||
|
|
||||||
|
Q_INVOKABLE void open();
|
||||||
|
Q_INVOKABLE void close();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void fileUrlChanged();
|
||||||
|
void filenameChanged();
|
||||||
|
void titleChanged();
|
||||||
|
void nameFiltersChanged();
|
||||||
|
void accepted();
|
||||||
|
void rejected();
|
||||||
|
|
||||||
|
// unused
|
||||||
|
void validChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QPlatformFileDialogHelper* init_helper();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QPlatformFileDialogHelper *m_dlgHelper;
|
||||||
|
QQuickWindow *m_parentWindow;
|
||||||
|
Qt::WindowModality m_modality;
|
||||||
|
bool m_visible;
|
||||||
|
QSharedPointer<QFileDialogOptions> m_options;
|
||||||
|
|
||||||
|
protected Q_SLOTS:
|
||||||
|
virtual void accept();
|
||||||
|
virtual void reject();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setFileUrl(QUrl fileUrl);
|
||||||
|
|
||||||
|
QUrl fileUrl_;
|
||||||
|
QString filename_;
|
||||||
|
QString title_;
|
||||||
|
QStringList nameFilters_;
|
||||||
|
|
||||||
|
Q_DISABLE_COPY(FileSaveDialog)
|
||||||
|
};
|
10
src/main.cpp
10
src/main.cpp
|
@ -10,6 +10,9 @@
|
||||||
#include "runtimeqml/runtimeqml.h"
|
#include "runtimeqml/runtimeqml.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "fileopendialog.h"
|
||||||
|
#include "filesavedialog.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
|
@ -25,6 +28,7 @@
|
||||||
|
|
||||||
int main( int argc, char *argv[] )
|
int main( int argc, char *argv[] )
|
||||||
{
|
{
|
||||||
|
setenv("QT_QPA_PLATFORMTHEME", "gtk3", 0);
|
||||||
setenv("QT_QUICK_CONTROLS_STYLE","Desktop",1);
|
setenv("QT_QUICK_CONTROLS_STYLE","Desktop",1);
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
app.setOrganizationName("KittehPlayer");
|
app.setOrganizationName("KittehPlayer");
|
||||||
|
@ -51,9 +55,11 @@ int main( int argc, char *argv[] )
|
||||||
|
|
||||||
qDebug() << newpath;
|
qDebug() << newpath;
|
||||||
setenv("Path", newpath.toUtf8().constData(), 1);
|
setenv("Path", newpath.toUtf8().constData(), 1);
|
||||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
|
QApplication::setAttribute(Qt::AA_UseSoftwareOpenGL );
|
||||||
qmlRegisterType<MpvObject>("player", 1, 0, "MpvObject");
|
qmlRegisterType<MpvObject>("player", 1, 0, "MpvObject");
|
||||||
|
qmlRegisterType<FileOpenDialog>("player", 1, 0, "FileOpenDialog");
|
||||||
|
qmlRegisterType<FileSaveDialog>("player", 1, 0, "FileSaveDialog");
|
||||||
|
|
||||||
std::setlocale(LC_NUMERIC, "C");
|
std::setlocale(LC_NUMERIC, "C");
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
#include <QtCore>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
#include <QOpenGLContext>
|
#include <QOpenGLContext>
|
||||||
|
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
|
@ -211,6 +214,12 @@ void MpvObject::setOption(const QString& name, const QVariant& value)
|
||||||
mpv::qt::set_option_variant(mpv, name, value);
|
mpv::qt::set_option_variant(mpv, name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MpvObject::launchAboutQt()
|
||||||
|
{
|
||||||
|
QApplication *qapp = qobject_cast<QApplication *>(QCoreApplication::instance());
|
||||||
|
qapp->aboutQt();
|
||||||
|
}
|
||||||
|
|
||||||
void MpvObject::on_mpv_events()
|
void MpvObject::on_mpv_events()
|
||||||
{
|
{
|
||||||
while (mpv) {
|
while (mpv) {
|
||||||
|
|
|
@ -39,6 +39,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void launchAboutQt();
|
||||||
void command(const QVariant& params);
|
void command(const QVariant& params);
|
||||||
void setProperty(const QString& name, const QVariant& value);
|
void setProperty(const QString& name, const QVariant& value);
|
||||||
void setOption(const QString& name, const QVariant& value);
|
void setOption(const QString& name, const QVariant& value);
|
||||||
|
|
|
@ -17,6 +17,7 @@ MenuItem {
|
||||||
rightPadding: menuItem.indicator.width
|
rightPadding: menuItem.indicator.width
|
||||||
text: menuItem.text
|
text: menuItem.text
|
||||||
font.family: notoFont.name
|
font.family: notoFont.name
|
||||||
|
font.bold: menuItem.highlighted
|
||||||
opacity: 1
|
opacity: 1
|
||||||
color: menuItem.highlighted ? "#5a50da" : "white"
|
color: menuItem.highlighted ? "#5a50da" : "white"
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
|
|
@ -212,7 +212,7 @@ ApplicationWindow {
|
||||||
|| fileMenuBarItem.opened || playbackMenuBarItem.opened
|
|| fileMenuBarItem.opened || playbackMenuBarItem.opened
|
||||||
|| viewMenuBarItem.opened || audioMenuBarItem.opened
|
|| viewMenuBarItem.opened || audioMenuBarItem.opened
|
||||||
|| screenshotSaveDialog.visible || videoMenuBarItem.opened
|
|| screenshotSaveDialog.visible || videoMenuBarItem.opened
|
||||||
|| subsMenuBarItem.opened
|
|| subsMenuBarItem.opened || aboutMenuBarItem.opened
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideControls(force) {
|
function hideControls(force) {
|
||||||
|
@ -256,26 +256,26 @@ ApplicationWindow {
|
||||||
property bool nyanCat: false
|
property bool nyanCat: false
|
||||||
}
|
}
|
||||||
|
|
||||||
Dialog {
|
FileSaveDialog {
|
||||||
id: screenshotSaveDialog
|
id: screenshotSaveDialog
|
||||||
title: "Save Screenshot To"
|
title: "Save Screenshot To"
|
||||||
standardButtons: StandardButton.Cancel | StandardButton.Open
|
filename: "screenshot.png"
|
||||||
|
nameFilters: ["Images (*.png)", "All files (*)"]
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
player.grabToImage(function (result) {
|
player.grabToImage(function (result) {
|
||||||
result.saveToFile(screenshotFile.text)
|
var filepath = String(screenshotSaveDialog.fileUrl).replace(
|
||||||
|
"file://", '')
|
||||||
|
console.log("Saving screenshot to: " + filepath)
|
||||||
|
result.saveToFile(filepath)
|
||||||
nativeSubs.visible = true
|
nativeSubs.visible = true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
TextField {
|
|
||||||
id: screenshotFile
|
|
||||||
placeholderText: "~/screenshot.jpg"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileDialog {
|
FileOpenDialog {
|
||||||
id: fileDialog
|
id: fileDialog
|
||||||
title: "Please choose a file"
|
title: "Please choose a file"
|
||||||
folder: shortcuts.home
|
nameFilters: ["All files (*)"]
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
player.command(["loadfile", String(fileDialog.fileUrl)])
|
player.command(["loadfile", String(fileDialog.fileUrl)])
|
||||||
fileDialog.close()
|
fileDialog.close()
|
||||||
|
@ -327,7 +327,9 @@ ApplicationWindow {
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: controlsBar.visible ? Qt.ArrowCursor : Qt.BlankCursor
|
cursorShape: controlsBar.visible ? Qt.ArrowCursor : Qt.BlankCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (clickToPause) { player.command(["cycle", "pause"]) }
|
if (appearance.clickToPause) {
|
||||||
|
player.command(["cycle", "pause"])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Timer {
|
Timer {
|
||||||
id: mouseAreaPlayerTimer
|
id: mouseAreaPlayerTimer
|
||||||
|
@ -381,15 +383,22 @@ ApplicationWindow {
|
||||||
MenuBar {
|
MenuBar {
|
||||||
id: menuBar
|
id: menuBar
|
||||||
//width: parent.width
|
//width: parent.width
|
||||||
height: Screen.height / 24
|
height: Screen.height / 32
|
||||||
delegate: MenuBarItem {
|
delegate: MenuBarItem {
|
||||||
id: menuBarItem
|
id: menuBarItem
|
||||||
|
|
||||||
|
padding: 4
|
||||||
|
topPadding: padding
|
||||||
|
leftPadding: padding
|
||||||
|
rightPadding: padding
|
||||||
|
bottomPadding: padding
|
||||||
|
|
||||||
contentItem: Text {
|
contentItem: Text {
|
||||||
|
id: menuBarItemText
|
||||||
text: menuBarItem.text
|
text: menuBarItem.text
|
||||||
font.family: notoFont.name
|
font.family: notoFont.name
|
||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
renderType: Text.NativeRendering
|
font.bold: menuBarItem.highlighted
|
||||||
opacity: 1
|
opacity: 1
|
||||||
color: menuBarItem.highlighted ? "#5a50da" : "white"
|
color: menuBarItem.highlighted ? "#5a50da" : "white"
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
@ -700,6 +709,27 @@ ApplicationWindow {
|
||||||
shortcut: keybinds.nyanCat
|
shortcut: keybinds.nyanCat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Menu {
|
||||||
|
id: aboutMenuBarItem
|
||||||
|
title: "About"
|
||||||
|
width: 120
|
||||||
|
background: Rectangle {
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 10
|
||||||
|
color: "black"
|
||||||
|
opacity: 0.6
|
||||||
|
}
|
||||||
|
delegate: CustomMenuItem {
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
|
||||||
|
Action {
|
||||||
|
text: "Fullscreen"
|
||||||
|
onTriggered: {
|
||||||
|
player.launchAboutQt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Action {
|
Action {
|
||||||
onTriggered: player.skipToNinth(parseInt(shortcut))
|
onTriggered: player.skipToNinth(parseInt(shortcut))
|
||||||
|
@ -771,7 +801,6 @@ ApplicationWindow {
|
||||||
color: "white"
|
color: "white"
|
||||||
font.family: notoFont.name
|
font.family: notoFont.name
|
||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
renderType: Text.NativeRendering
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
opacity: 1
|
opacity: 1
|
||||||
}
|
}
|
||||||
|
@ -797,7 +826,6 @@ ApplicationWindow {
|
||||||
font.family: notoFont.name
|
font.family: notoFont.name
|
||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
anchors.top: audioList.bottom
|
anchors.top: audioList.bottom
|
||||||
renderType: Text.NativeRendering
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
opacity: 1
|
opacity: 1
|
||||||
}
|
}
|
||||||
|
@ -823,7 +851,6 @@ ApplicationWindow {
|
||||||
font.family: notoFont.name
|
font.family: notoFont.name
|
||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
anchors.top: subList.bottom
|
anchors.top: subList.bottom
|
||||||
renderType: Text.NativeRendering
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
opacity: 1
|
opacity: 1
|
||||||
}
|
}
|
||||||
|
@ -873,15 +900,12 @@ ApplicationWindow {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: 10
|
anchors.leftMargin: 10
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.bottomMargin: 4
|
topPadding: 4
|
||||||
anchors.topMargin: 4
|
bottomPadding: 4
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
font.family: notoFont.name
|
font.family: notoFont.name
|
||||||
fontSizeMode: Text.Fit
|
font.pixelSize: 14
|
||||||
minimumPixelSize: 10
|
font.bold: true
|
||||||
font.pixelSize: 72
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
renderType: Text.NativeRendering
|
|
||||||
opacity: 1
|
opacity: 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -912,7 +936,7 @@ ApplicationWindow {
|
||||||
radius: 5
|
radius: 5
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
TextMetrics {
|
TextMetrics {
|
||||||
id: t_metrics
|
id: subTextMetrics
|
||||||
font.family: notoFont.name
|
font.family: notoFont.name
|
||||||
font.pixelSize: nativeSubs.fontInfo.pixelSize
|
font.pixelSize: nativeSubs.fontInfo.pixelSize
|
||||||
text: nativeSubs.text
|
text: nativeSubs.text
|
||||||
|
@ -925,7 +949,6 @@ ApplicationWindow {
|
||||||
color: "white"
|
color: "white"
|
||||||
font.family: notoFont.name
|
font.family: notoFont.name
|
||||||
font.pixelSize: Screen.height / 24
|
font.pixelSize: Screen.height / 24
|
||||||
renderType: Text.NativeRendering
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
anchors.bottom: parent.top
|
anchors.bottom: parent.top
|
||||||
opacity: 1
|
opacity: 1
|
||||||
|
@ -934,10 +957,10 @@ ApplicationWindow {
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
id: subsBackground
|
id: subsBackground
|
||||||
color: Qt.rgba(0, 0, 0, 0.6)
|
color: Qt.rgba(0, 0, 0, 0.6)
|
||||||
width: t_metrics.tightBoundingRect.width + 8
|
width: subTextMetrics.tightBoundingRect.width + 8
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: (nativeSubtitles.width
|
anchors.leftMargin: (nativeSubtitles.width
|
||||||
- t_metrics.tightBoundingRect.width) / 2
|
- subTextMetrics.tightBoundingRect.width) / 2
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: anchors.leftMargin
|
anchors.rightMargin: anchors.leftMargin
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue