1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-11-06 19:12:30 +01:00

Add edit menu entry

This commit is contained in:
Elias Steurer 2023-11-16 13:27:50 +01:00
parent 99e427b6cb
commit 893844f023
8 changed files with 129 additions and 73 deletions

View File

@ -185,6 +185,7 @@ set(RESOURCES
assets/icons/icon_widgets.svg
assets/icons/icon_window.svg
assets/icons/item_banner_new.svg
assets/icons/icon_edit.svg
assets/icons/monitor_setup.svg
assets/icons/steam_default_avatar.png
assets/images/Early_Access.png

View File

@ -58,7 +58,8 @@ class Util : public QObject {
Q_PROPERTY(QString debugMessages READ debugMessages NOTIFY debugMessagesChanged)
public:
Util();
Util(
const std::shared_ptr<GlobalVariables>& globalVariables);
~Util();
QString debugMessages() const { return m_debugMessages; }
@ -82,6 +83,7 @@ public slots:
void openFolderInExplorer(const QString& url) const;
QString toLocal(const QString& url) const;
bool exportProject(QString contentPath, QString exportFileName);
bool openGodotEditor(QString contentPath) const;
bool importProject(QString archivePath, QString extractionPath);
void requestAllLicenses();
void requestDataProtection();
@ -124,6 +126,7 @@ private:
QFuture<void> m_requestAllLicensesFuture;
std::unique_ptr<QArchive::DiskCompressor> m_compressor;
std::unique_ptr<QArchive::DiskExtractor> m_extractor;
const std::shared_ptr<GlobalVariables>& m_globalVariables;
};
}

View File

@ -34,9 +34,11 @@ namespace ScreenPlay {
class Wizards : public QObject {
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("CPP ONLY")
public:
explicit Wizards(const std::shared_ptr<GlobalVariables>& globalVariables, QObject* parent = nullptr);
Wizards() { }
explicit Wizards(
const std::shared_ptr<GlobalVariables>& globalVariables,
QObject* parent = nullptr);
enum class WizardResult {
Ok,

View File

@ -25,23 +25,23 @@ Item {
function checkIsContentInstalled() {
if (App.installedListModel.count === 0) {
loaderHelp.active = true;
gridView.footerItem.isVisible = true;
gridView.visible = false;
navWrapper.visible = false;
loaderHelp.active = true
gridView.footerItem.isVisible = true
gridView.visible = false
navWrapper.visible = false
} else {
loaderHelp.active = false;
gridView.footerItem.isVisible = false;
refresh = false;
gridView.contentY = -82;
gridView.visible = true;
navWrapper.visible = true;
loaderHelp.active = false
gridView.footerItem.isVisible = false
refresh = false
gridView.contentY = -82
gridView.visible = true
navWrapper.visible = true
}
}
StackView.onActivated: {
navWrapper.state = "in";
checkIsContentInstalled();
navWrapper.state = "in"
checkIsContentInstalled()
}
Action {
@ -51,12 +51,12 @@ Item {
Connections {
function onInstalledLoadingFinished() {
checkIsContentInstalled();
checkIsContentInstalled()
}
function onCountChanged(count) {
if (count === 0)
checkIsContentInstalled();
checkIsContentInstalled()
}
target: App.installedListModel
@ -71,7 +71,7 @@ Item {
Connections {
function onSortChanged() {
gridView.positionViewAtBeginning();
gridView.positionViewAtBeginning()
}
target: App.installedListFilter
@ -128,12 +128,12 @@ Item {
}
onContentYChanged: {
if (contentY <= -180)
gridView.headerItem.isVisible = true;
gridView.headerItem.isVisible = true
else
gridView.headerItem.isVisible = false;
gridView.headerItem.isVisible = false
//Pull to refresh
if (contentY <= -180 && !refresh && !isDragging)
App.installedListModel.reset();
App.installedListModel.reset()
}
anchors {
@ -150,11 +150,11 @@ Item {
opacity: 0
onIsVisibleChanged: {
if (isVisible) {
txtHeader.color = Material.accent;
txtHeader.text = qsTr("Refreshing!");
txtHeader.color = Material.accent
txtHeader.text = qsTr("Refreshing!")
} else {
txtHeader.color = "gray";
txtHeader.text = qsTr("Pull to refresh!");
txtHeader.color = "gray"
txtHeader.text = qsTr("Pull to refresh!")
}
}
@ -162,7 +162,7 @@ Item {
interval: 150
running: true
onTriggered: {
animFadeIn.start();
animFadeIn.start()
}
}
@ -206,7 +206,7 @@ Item {
interval: 400
running: true
onTriggered: {
animFadeInTxtFooter.start();
animFadeInTxtFooter.start()
}
}
@ -236,15 +236,23 @@ Item {
isScrolling: gridView.isScrolling
onOpenContextMenu: function (position) {
// Set the menu to the current item informations
contextMenu.publishedFileID = delegate.publishedFileID;
contextMenu.absoluteStoragePath = delegate.absoluteStoragePath;
contextMenu.fileName = delegate.customTitle;
const pos = delegate.mapToItem(root, position.x, position.y);
contextMenu.publishedFileID = delegate.publishedFileID
contextMenu.absoluteStoragePath = delegate.absoluteStoragePath
contextMenu.fileName = delegate.customTitle
contextMenu.type = delegate.type
print(delegate.publishedFileID)
if(contextMenu.godotItem)
contextMenu.godotItem.destroy()
const pos = delegate.mapToItem(root, position.x, position.y)
// Disable duplicate opening. The can happen if we
// call popup when we are in the closing animtion.
if (contextMenu.visible || contextMenu.opened)
return;
contextMenu.popup(pos.x, pos.y);
return
if (delegate.type === InstalledType.GodotWallpaper) {
contextMenu.godotItem = editGodotWallpaperComp.createObject()
contextMenu.insertItem(0, contextMenu.godotItem)
}
contextMenu.popup(pos.x, pos.y)
}
}
@ -252,21 +260,37 @@ Item {
snapMode: ScrollBar.SnapOnRelease
}
}
Component {
id: editGodotWallpaperComp
MenuItem {
text: qsTr("Edit Wallpaper")
objectName: "editWallpaper"
enabled: contextMenu.type === InstalledType.GodotWallpaper
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_edit.svg"
onClicked: {
App.util.openGodotEditor(contextMenu.absoluteStoragePath)
}
}
}
Menu {
id: contextMenu
objectName: "installedItemContextMenu"
// Must be var to support 64-bit size!
property var publishedFileID: 0
property var type: 0
property url absoluteStoragePath
property string fileName
// We need to dynamically add this menu item
// if it is a Godot Wallpaper, see onOpenContextMenu
property var godotItem
MenuItem {
text: qsTr("Open containing folder")
objectName: "openFolder"
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_folder_open.svg"
onClicked: {
App.util.openFolderInExplorer(contextMenu.absoluteStoragePath);
App.util.openFolderInExplorer(contextMenu.absoluteStoragePath)
}
}
@ -275,10 +299,12 @@ Item {
objectName: enabled ? "removeItem" : "removeWorkshopItem"
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_import_export_.svg"
onClicked: {
exportFileDialog.absoluteStoragePath = contextMenu.absoluteStoragePath;
let urlFileName = QCore.StandardPaths.writableLocation(QCore.StandardPaths.DesktopLocation) + "/" + contextMenu.fileName + ".screenplay";
exportFileDialog.currentFile = urlFileName;
exportFileDialog.open();
exportFileDialog.absoluteStoragePath = contextMenu.absoluteStoragePath
let urlFileName = QCore.StandardPaths.writableLocation(
QCore.StandardPaths.DesktopLocation) + "/"
+ contextMenu.fileName + ".screenplay"
exportFileDialog.currentFile = urlFileName
exportFileDialog.open()
}
}
@ -286,18 +312,21 @@ Item {
text: enabled ? qsTr("Remove Item") : qsTr("Remove via Workshop")
objectName: enabled ? "removeItem" : "removeWorkshopItem"
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_delete.svg"
enabled: contextMenu.publishedFileID === 0 || !App.settings.steamVersion
enabled: contextMenu.publishedFileID === 0
|| !App.settings.steamVersion
onClicked: {
deleteDialog.open();
deleteDialog.open()
}
}
MenuItem {
text: qsTr("Open Workshop Page")
enabled: contextMenu.publishedFileID !== 0 && App.settings.steamVersion
enabled: contextMenu.publishedFileID !== 0
&& App.settings.steamVersion
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_steam.svg"
onClicked: {
Qt.openUrlExternally("steam://url/CommunityFilePage/" + contextMenu.publishedFileID);
Qt.openUrlExternally(
"steam://url/CommunityFilePage/" + contextMenu.publishedFileID)
}
}
}
@ -310,8 +339,9 @@ Item {
modalSource: root.modalSource
anchors.centerIn: Overlay.overlay
onAccepted: {
root.sidebar.clear();
App.installedListModel.deinstallItemAt(contextMenu.absoluteStoragePath);
root.sidebar.clear()
App.installedListModel.deinstallItemAt(
contextMenu.absoluteStoragePath)
}
}
@ -320,7 +350,7 @@ Item {
fileMode: FileDialog.SaveFile
property string absoluteStoragePath
onAccepted: {
exportFileProgressDialog.open();
exportFileProgressDialog.open()
}
}
@ -333,7 +363,9 @@ Item {
modalSource: root.modalSource
closePolicy: Popup.NoAutoClose
onOpened: {
const success = App.util.exportProject(exportFileDialog.absoluteStoragePath, exportFileDialog.currentFile);
const success = App.util.exportProject(
exportFileDialog.absoluteStoragePath,
exportFileDialog.currentFile)
}
onClosed: exportProgressBar.value = 0
ColumnLayout {
@ -358,10 +390,10 @@ Item {
id: exportConnections
target: App.util
function onCompressionProgressChanged(file, proc, total, br, bt) {
exportProgressBar.value = (br * 100 / bt);
exportProgressBar.value = (br * 100 / bt)
}
function onCompressionFinished() {
exportFileProgressDialog.close();
exportFileProgressDialog.close()
}
}
}
@ -381,28 +413,31 @@ Item {
anchors.fill: parent
property string filePath
onEntered: function (drag) {
dropPopup.open();
dropPopup.open()
}
onDropped: function (drop) {
dropPopup.close();
dropArea.enabled = false;
dropPopup.close()
dropArea.enabled = false
if (drop.urls.length > 1) {
importProjectErrorDialog.title = qsTr("We only support adding one item at once.");
importProjectErrorDialog.open();
return;
importProjectErrorDialog.title = qsTr(
"We only support adding one item at once.")
importProjectErrorDialog.open()
return
}
var file = ""; // Convert url to string
file = "" + drop.urls[0];
var file = ""
// Convert url to string
file = "" + drop.urls[0]
if (!file.endsWith('.screenplay')) {
importProjectErrorDialog.title = qsTr("File type not supported. We only support '.screenplay' files.");
importProjectErrorDialog.open();
return;
importProjectErrorDialog.title = qsTr(
"File type not supported. We only support '.screenplay' files.")
importProjectErrorDialog.open()
return
}
importDialog.open();
dropArea.filePath = file;
importDialog.open()
dropArea.filePath = file
}
onExited: {
dropPopup.close();
dropPopup.close()
}
Util.Dialog {
@ -423,9 +458,11 @@ Item {
closePolicy: Popup.NoAutoClose
onClosed: importProgressBar.value = 0
onOpened: {
const success = App.util.importProject(dropArea.filePath, App.globalVariables.localStoragePath);
print("finished", success);
dropArea.filePath = "";
const success = App.util.importProject(
dropArea.filePath,
App.globalVariables.localStoragePath)
print("finished", success)
dropArea.filePath = ""
}
ColumnLayout {
width: parent.width
@ -447,10 +484,10 @@ Item {
id: importConnections
target: App.util
function onExtractionProgressChanged(file, proc, total, br, bt) {
importProgressBar.value = (br * 100 / bt);
importProgressBar.value = (br * 100 / bt)
}
function onExtractionFinished() {
importDialog.close();
importDialog.close()
}
}
}
@ -466,8 +503,8 @@ Item {
modal: true
onOpened: fileDropAnimation.state = "fileDrop"
onClosed: {
fileDropAnimation.state = "";
dropArea.enabled = true;
fileDropAnimation.state = ""
dropArea.enabled = true
}
Util.FileDropAnimation {

View File

@ -14,6 +14,7 @@ Item {
property string screenId
property url absoluteStoragePath
property int type: InstalledType.Unknown
// Must be var to make it work wit 64bit ints
property var publishedFileID: 0
property int itemIndex
property bool isScrolling: false

View File

@ -138,10 +138,9 @@ void App::init()
using std::make_shared, std::make_unique;
// Util should be created as first so we redirect qDebugs etc. into the log
m_util = make_unique<Util>();
m_globalVariables = make_shared<GlobalVariables>();
m_monitorListModel = make_shared<MonitorListModel>();
m_util = make_unique<Util>(m_globalVariables);
m_profileListModel = make_shared<ProfileListModel>(m_globalVariables);
m_settings = make_shared<Settings>(m_globalVariables);
m_installedListModel = make_shared<InstalledListModel>(m_globalVariables, m_settings);

View File

@ -22,7 +22,9 @@ namespace ScreenPlay {
/*!
Constructor
*/
ProfileListModel::ProfileListModel(const std::shared_ptr<GlobalVariables>& globalVariables, QObject* parent)
ProfileListModel::ProfileListModel(
const std::shared_ptr<GlobalVariables>& globalVariables,
QObject* parent)
: QAbstractListModel(parent)
, m_globalVariables { globalVariables }
{

View File

@ -23,8 +23,10 @@ namespace ScreenPlay {
/*!
\brief Constructor.
*/
Util::Util()
Util::Util(
const std::shared_ptr<GlobalVariables>& globalVariables)
: QObject(nullptr)
, m_globalVariables { globalVariables }
{
m_extractor = std::make_unique<QArchive::DiskExtractor>();
m_compressor = std::make_unique<QArchive::DiskCompressor>();
@ -144,6 +146,15 @@ bool Util::exportProject(QString contentPath, QString exportFileName)
return true;
}
bool Util::openGodotEditor(QString contentPath) const
{
const QList<QString> godotCmd = { "--editor", "--path", toLocal(contentPath) };
QProcess process;
process.setProgram(m_globalVariables->godotEditorExecutablePath().toString());
process.setArguments(godotCmd);
return process.startDetached();
}
/*!
\brief Imports a given project from a .screenplay zip file. The argument extractionPath
must be copied otherwise it will get reset in qml before extracting.