aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--launcher/FileSystem.cpp149
-rw-r--r--launcher/FileSystem.h5
-rw-r--r--launcher/ui/MainWindow.cpp88
3 files changed, 156 insertions, 86 deletions
diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp
index 4a8f4bd3..90f0313f 100644
--- a/launcher/FileSystem.cpp
+++ b/launcher/FileSystem.cpp
@@ -49,6 +49,7 @@
#include "StringUtils.h"
#if defined Q_OS_WIN32
+#define WIN32_LEAN_AND_MEAN
#include <objbase.h>
#include <objidl.h>
#include <shlguid.h>
@@ -339,12 +340,12 @@ QString getDesktopDir()
}
// Cross-platform Shortcut creation
-bool createShortCut(QString location, QString dest, QStringList args, QString name, QString icon)
+bool createShortcut(QString destination, QString target, QStringList args, QString name, QString icon)
{
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
- location = PathCombine(location, name + ".desktop");
+ destination = PathCombine(destination, name + ".desktop");
- QFile f(location);
+ QFile f(destination);
f.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream stream(&f);
@@ -356,10 +357,13 @@ bool createShortCut(QString location, QString dest, QStringList args, QString na
<< "\n";
stream << "Type=Application"
<< "\n";
- stream << "TryExec=" << dest.toLocal8Bit() << "\n";
- stream << "Exec=" << dest.toLocal8Bit() << argstring.toLocal8Bit() << "\n";
+ stream << "TryExec=" << target.toLocal8Bit() << "\n";
+ stream << "Exec=" << target.toLocal8Bit() << argstring.toLocal8Bit() << "\n";
stream << "Name=" << name.toLocal8Bit() << "\n";
- stream << "Icon=" << icon.toLocal8Bit() << "\n";
+ if (!icon.isEmpty())
+ {
+ stream << "Icon=" << icon.toLocal8Bit() << "\n";
+ }
stream.flush();
f.close();
@@ -368,24 +372,121 @@ bool createShortCut(QString location, QString dest, QStringList args, QString na
return true;
#elif defined Q_OS_WIN
- // TODO: Fix
- // QFile file(PathCombine(location, name + ".lnk"));
- // WCHAR *file_w;
- // WCHAR *dest_w;
- // WCHAR *args_w;
- // file.fileName().toWCharArray(file_w);
- // dest.toWCharArray(dest_w);
-
- // QString argStr;
- // for (int i = 0; i < args.count(); i++)
- // {
- // argStr.append(args[i]);
- // argStr.append(" ");
- // }
- // argStr.toWCharArray(args_w);
-
- // return SUCCEEDED(CreateLink(file_w, dest_w, args_w));
- return false;
+ QFileInfo targetInfo(target);
+
+ if (!targetInfo.exists())
+ {
+ qWarning() << "Target file does not exist!";
+ return false;
+ }
+
+ target = targetInfo.absoluteFilePath();
+
+ if (target.length() >= MAX_PATH)
+ {
+ qWarning() << "Target file path is too long!";
+ return false;
+ }
+
+ if (!icon.isEmpty() && icon.length() >= MAX_PATH)
+ {
+ qWarning() << "Icon path is too long!";
+ return false;
+ }
+
+ destination += ".lnk";
+
+ if (destination.length() >= MAX_PATH)
+ {
+ qWarning() << "Destination path is too long!";
+ return false;
+ }
+
+ QString argStr;
+ int argCount = args.count();
+ for (int i = 0; i < argCount; i++)
+ {
+ if (args[i].contains(' '))
+ {
+ argStr.append('"').append(args[i]).append('"');
+ }
+ else
+ {
+ argStr.append(args[i]);
+ }
+
+ if (i < argCount - 1)
+ {
+ argStr.append(" ");
+ }
+ }
+
+ if (argStr.length() >= MAX_PATH)
+ {
+ qWarning() << "Arguments string is too long!";
+ return false;
+ }
+
+ WCHAR wsz[MAX_PATH];
+
+ // ...yes, you need to initialize the entire COM stack to make a shortcut in Windows
+ CoInitialize(nullptr);
+
+ HRESULT hres;
+ IShellLink* psl;
+
+ hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
+ if (SUCCEEDED(hres))
+ {
+ wmemset(wsz, 0, MAX_PATH);
+ target.toWCharArray(wsz);
+ psl->SetPath(wsz);
+
+ wmemset(wsz, 0, MAX_PATH);
+ argStr.toWCharArray(wsz);
+ psl->SetArguments(wsz);
+
+ wmemset(wsz, 0, MAX_PATH);
+ targetInfo.absolutePath().toWCharArray(wsz);
+ psl->SetWorkingDirectory(wsz);
+
+ if (!icon.isEmpty())
+ {
+ wmemset(wsz, 0, MAX_PATH);
+ icon.toWCharArray(wsz);
+ psl->SetIconLocation(wsz, 0);
+ }
+
+ IPersistFile* ppf;
+ hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);
+ if (SUCCEEDED(hres))
+ {
+ wmemset(wsz, 0, MAX_PATH);
+ destination.toWCharArray(wsz);
+ hres = ppf->Save(wsz, TRUE);
+ if (FAILED(hres))
+ {
+ qWarning() << "IPresistFile->Save() failed";
+ qWarning() << "hres = " << hres;
+ }
+ ppf->Release();
+ }
+ else
+ {
+ qWarning() << "Failed to query IPersistFile interface from IShellLink instance";
+ qWarning() << "hres = " << hres;
+ }
+ psl->Release();
+ }
+ else
+ {
+ qWarning() << "Failed to create IShellLink instance";
+ qWarning() << "hres = " << hres;
+ }
+
+ CoUninitialize();
+
+ return SUCCEEDED(hres);
#else
qWarning("Desktop Shortcuts not supported on your platform!");
return false;
diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h
index b7e175fd..23cc575b 100644
--- a/launcher/FileSystem.h
+++ b/launcher/FileSystem.h
@@ -156,4 +156,9 @@ QString getDesktopDir();
// Overrides one folder with the contents of another, preserving items exclusive to the first folder
// Equivalent to doing QDir::rename, but allowing for overrides
bool overrideFolder(QString overwritten_path, QString override_path);
+
+/**
+ * Creates a shortcut to the specified target file at the specified destination path.
+ */
+bool createShortcut(QString destination, QString target, QStringList args, QString name, QString icon);
}
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp
index 419bb9bd..1ad9713a 100644
--- a/launcher/ui/MainWindow.cpp
+++ b/launcher/ui/MainWindow.cpp
@@ -39,6 +39,7 @@
#include "Application.h"
#include "BuildConfig.h"
+#include "FileSystem.h"
#include "MainWindow.h"
@@ -739,9 +740,9 @@ public:
actionCreateInstanceShortcut = TranslatedAction(MainWindow);
actionCreateInstanceShortcut->setObjectName(QStringLiteral("actionCreateInstanceShortcut"));
- actionCreateInstanceShortcut.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Create shortcut"));
+ actionCreateInstanceShortcut.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Create Shortcut"));
actionCreateInstanceShortcut.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Creates a shortcut on your desktop to launch the selected instance."));
- actionCreateInstanceShortcut->setShortcut(QKeySequence(tr("Ctrl+D")));
+ //actionCreateInstanceShortcut->setShortcut(QKeySequence(tr("Ctrl+D"))); // TODO
//actionCreateInstanceShortcut->setIcon(APPLICATION->getThemedIcon("copy")); // TODO
all_actions.append(&actionCreateInstanceShortcut);
@@ -793,7 +794,7 @@ public:
}
}
- instanceToolBar->addAction(actionCreateInstanceShortcut);
+ instanceToolBar->addAction(actionCreateInstanceShortcut); // TODO find better position for this
all_toolbars.append(&instanceToolBar);
MainWindow->addToolBar(Qt::RightToolBarArea, instanceToolBar);
@@ -2087,76 +2088,39 @@ void MainWindow::on_actionKillInstance_triggered()
}
}
-#ifdef Q_OS_WIN
-#define WIN32_LEAN_AND_MEAN
-#include "windows.h"
-#include "winnls.h"
-#include "shobjidl.h"
-#include "objbase.h"
-#include "objidl.h"
-#include "shlguid.h"
-#endif
-
void MainWindow::on_actionCreateInstanceShortcut_triggered()
{
if (m_selectedInstance)
{
- auto desktopDir = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
- if (desktopDir.isEmpty()) {
+ auto desktopPath = FS::getDesktopDir();
+ if (desktopPath.isEmpty()) {
// TODO come up with an alternative solution (open "save file" dialog)
- QMessageBox::critical(this, tr("Create instance shortcut"), tr("Couldn't find desktop!"));
+ QMessageBox::critical(this, tr("Create instance shortcut"), tr("Couldn't find desktop?!"));
return;
}
-#if defined(Q_OS_WIN)
- // Windows
- WCHAR wsz[MAX_PATH];
-
- // ...yes, you need to initialize the entire COM stack to make a shortcut in Windows.
- // I hate it.
- CoInitialize(nullptr);
-
- HRESULT hres;
- IShellLink* psl;
-
- hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
- if (SUCCEEDED(hres))
- {
- IPersistFile* ppf;
-
- QApplication::applicationFilePath().left(MAX_PATH - 1).toWCharArray(wsz);
- psl->SetPath(wsz);
-
- wmemset(wsz, 0, MAX_PATH);
- QStringLiteral("--launch %1").arg(m_selectedInstance->id()).left(MAX_PATH - 1).toWCharArray(wsz);
- psl->SetArguments(wsz);
-
- // TODO set icon
-
- hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);
-
- if (SUCCEEDED(hres))
- {
- wmemset(wsz, 0, MAX_PATH);
-
- desktopDir
- .append('/')
- .append(QStringLiteral("%1.lnk").arg(m_selectedInstance->name()))
- .left(MAX_PATH - 1).toWCharArray(wsz);
-
- hres = ppf->Save(wsz, TRUE);
- ppf->Release();
- }
- psl->Release();
- }
-
- CoUninitialize();
-#elif defined(Q_OS_LINUX)
- // Linux
-#elif defined(Q_OS_MACOS)
+#if defined(Q_OS_MACOS)
// macOSX
// TODO actually write this path
QMessageBox::critical(this, tr("Create instance shortcut"), tr("Not supported on macOSX yet!"));
+#else
+ QString iconPath;
+
+#if defined(Q_OS_WIN)
+ // TODO
+ // need to convert icon to ICO format and save it somewhere...
+ iconPath = "";
+#elif defined(Q_OS_UNIX)
+ iconPath = ""; // TODO get instance icon path
+#endif
+ if (FS::createShortcut(FS::PathCombine(desktopPath, m_selectedInstance->name()),
+ QApplication::applicationFilePath(), { "--launch", m_selectedInstance->id() }, m_selectedInstance->name(), iconPath)) {
+ QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!"));
+ }
+ else
+ {
+ QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!"));
+ }
#endif
}
}