summaryrefslogtreecommitdiffstats
path: root/src/libs/installer/createshortcutoperation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/installer/createshortcutoperation.cpp')
-rw-r--r--src/libs/installer/createshortcutoperation.cpp125
1 files changed, 82 insertions, 43 deletions
diff --git a/src/libs/installer/createshortcutoperation.cpp b/src/libs/installer/createshortcutoperation.cpp
index 754ba317e..2c2e96eff 100644
--- a/src/libs/installer/createshortcutoperation.cpp
+++ b/src/libs/installer/createshortcutoperation.cpp
@@ -41,6 +41,7 @@ using namespace QInstaller;
#ifdef Q_OS_WIN
#include <qt_windows.h>
#include <shlobj.h>
+#include <Intshcut.h>
#ifndef PIDLIST_ABSOLUTE
typedef ITEMIDLIST *PIDLIST_ABSOLUTE;
@@ -93,39 +94,62 @@ static QString takeArgument(const QString argument, QStringList *arguments)
static bool createLink(const QString &fileName, const QString &linkName, QString workingDir,
const QString &arguments = QString(), const QString &iconPath = QString(),
- const QString &iconId = QString())
+ const QString &iconId = QString(), const QString &description = QString())
{
#ifdef Q_OS_WIN
- bool success = QFile::link(fileName, linkName);
+ // CoInitialize cleanup object
+ DeCoInitializer _;
- if (!success)
- return success;
+ IUnknown *iunkn = NULL;
- if (workingDir.isEmpty())
- workingDir = QFileInfo(fileName).absolutePath();
- workingDir = QDir::toNativeSeparators(workingDir);
+ if (fileName.toLower().startsWith(QLatin1String("http:"))
+ || fileName.toLower().startsWith(QLatin1String("ftp:"))) {
+ IUniformResourceLocator *iurl = NULL;
+ if (FAILED(CoCreateInstance(CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER,
+ IID_IUniformResourceLocator, (LPVOID*)&iurl))) {
+ return false;
+ }
- // CoInitialize cleanup object
- DeCoInitializer _;
+ if (FAILED(iurl->SetURL((wchar_t *)fileName.utf16(), IURL_SETURL_FL_GUESS_PROTOCOL))) {
+ iurl->Release();
+ return false;
+ }
+ iunkn = iurl;
+ } else {
+ bool success = QFile::link(fileName, linkName);
+
+ if (!success) {
+ return success;
+ }
+
+ if (workingDir.isEmpty())
+ workingDir = QFileInfo(fileName).absolutePath();
+ workingDir = QDir::toNativeSeparators(workingDir);
- IShellLink *psl = NULL;
- if (FAILED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl)))
- return success;
+ IShellLink *psl = NULL;
+ if (FAILED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+ IID_IShellLink, (LPVOID*)&psl))) {
+ return success;
+ }
- // TODO: implement this server side, since there's not Qt equivalent to set working dir and arguments
- psl->SetPath((wchar_t *)QDir::toNativeSeparators(fileName).utf16());
- psl->SetWorkingDirectory((wchar_t *)workingDir.utf16());
- if (!arguments.isNull())
- psl->SetArguments((wchar_t*)arguments.utf16());
- if (!iconPath.isNull())
- psl->SetIconLocation((wchar_t*)(iconPath.utf16()), iconId.toInt());
+ // TODO: implement this server side, since there's not Qt equivalent to set working dir and arguments
+ psl->SetPath((wchar_t *)QDir::toNativeSeparators(fileName).utf16());
+ psl->SetWorkingDirectory((wchar_t *)workingDir.utf16());
+ if (!arguments.isNull())
+ psl->SetArguments((wchar_t*)arguments.utf16());
+ if (!iconPath.isNull())
+ psl->SetIconLocation((wchar_t*)(iconPath.utf16()), iconId.toInt());
+ if (!description.isNull())
+ psl->SetDescription((wchar_t*)(description.utf16()));
+ iunkn = psl;
+ }
IPersistFile *ppf = NULL;
- if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (void **)&ppf))) {
+ if (SUCCEEDED(iunkn->QueryInterface(IID_IPersistFile, (void **)&ppf))) {
ppf->Save((wchar_t*)QDir::toNativeSeparators(linkName).utf16(), true);
ppf->Release();
}
- psl->Release();
+ iunkn->Release();
PIDLIST_ABSOLUTE pidl; // Force start menu cache update
if (SUCCEEDED(SHGetFolderLocation(0, CSIDL_STARTMENU, 0, 0, &pidl))) {
@@ -137,7 +161,7 @@ static bool createLink(const QString &fileName, const QString &linkName, QString
CoTaskMemFree(pidl);
}
- return success;
+ return true;
#else
Q_UNUSED(arguments)
Q_UNUSED(workingDir)
@@ -152,13 +176,17 @@ static bool createLink(const QString &fileName, const QString &linkName, QString
// -- CreateShortcutOperation
-CreateShortcutOperation::CreateShortcutOperation()
+CreateShortcutOperation::CreateShortcutOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
+ , m_optionalArgumentsRead(false)
{
setName(QLatin1String("CreateShortcut"));
}
void CreateShortcutOperation::backup()
{
+ ensureOptionalArgumentsRead();
+
QDir linkPath(QFileInfo(arguments().at(1)).absolutePath());
QStringList directoriesToCreate;
@@ -171,25 +199,38 @@ void CreateShortcutOperation::backup()
setValue(QLatin1String("createddirs"), directoriesToCreate);
}
-bool CreateShortcutOperation::performOperation()
+void CreateShortcutOperation::ensureOptionalArgumentsRead()
{
+ if (m_optionalArgumentsRead)
+ return;
+
+ m_optionalArgumentsRead = true;
+
QStringList args = arguments();
- const QString iconId = takeArgument(QString::fromLatin1("iconId="), &args);
- const QString iconPath = takeArgument(QString::fromLatin1("iconPath="), &args);
- const QString workingDir = takeArgument(QString::fromLatin1("workingDirectory="), &args);
+ m_iconId = takeArgument(QString::fromLatin1("iconId="), &args);
+ m_iconPath = takeArgument(QString::fromLatin1("iconPath="), &args);
+ m_workingDir = takeArgument(QString::fromLatin1("workingDirectory="), &args);
+ m_description = takeArgument(QString::fromLatin1("description="), &args);
+
+ setArguments(args);
+}
+
+bool CreateShortcutOperation::performOperation()
+{
+ ensureOptionalArgumentsRead();
- if (args.count() != 2 && args.count() != 3) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("2 or 3"),
- tr(" (optional: 'workingDirectory=...', 'iconPath=...', 'iconId=...')")));
+ if (!checkArgumentCount(2, 3, tr("<target> <link location> [target arguments] "
+ "[\"workingDirectory=...\"] [\"iconPath=...\"] [\"iconId=...\"] "
+ "[\"description=...\"]"))) {
return false;
}
+ QStringList args = arguments();
+
const QString linkTarget = args.at(0);
const QString linkLocation = args.at(1);
- const QString targetArguments = args.value(2); //used value because it could be not existing
+ const QString targetArguments = args.value(2); // value() used since it's optional
const QString linkPath = QFileInfo(linkLocation).absolutePath().trimmed();
const bool created = QDir(linkPath).exists() || QDir::root().mkpath(linkPath);
@@ -199,11 +240,11 @@ bool CreateShortcutOperation::performOperation()
#if defined(Q_OS_WIN) && !defined(Q_CC_MINGW)
char msg[128];
if (strerror_s(msg, sizeof msg, errno) != 0) {
- setErrorString(tr("Could not create folder %1: %2.").arg(QDir::toNativeSeparators(linkPath),
+ setErrorString(tr("Cannot create directory \"%1\": %2").arg(QDir::toNativeSeparators(linkPath),
QString::fromLocal8Bit(msg)));
}
#else
- setErrorString(tr("Could not create folder %1: %2.").arg(QDir::toNativeSeparators(linkPath),
+ setErrorString(tr("Cannot create directory \"%1\": %2").arg(QDir::toNativeSeparators(linkPath),
QString::fromLocal8Bit(strerror(errno))));
#endif
return false;
@@ -213,15 +254,16 @@ bool CreateShortcutOperation::performOperation()
QString errorString;
if (QFile::exists(linkLocation) && !deleteFileNowOrLater(linkLocation, &errorString)) {
setError(UserDefinedError);
- setErrorString(tr("Failed to overwrite %1: %2").arg(QDir::toNativeSeparators(linkLocation),
+ setErrorString(tr("Failed to overwrite \"%1\": %2").arg(QDir::toNativeSeparators(linkLocation),
errorString));
return false;
}
- const bool linked = createLink(linkTarget, linkLocation, workingDir, targetArguments, iconPath, iconId);
+ const bool linked = createLink(linkTarget, linkLocation, m_workingDir, targetArguments, m_iconPath, m_iconId,
+ m_description);
if (!linked) {
setError(UserDefinedError);
- setErrorString(tr("Could not create link %1: %2").arg(QDir::toNativeSeparators(linkLocation),
+ setErrorString(tr("Cannot create link \"%1\": %2").arg(QDir::toNativeSeparators(linkLocation),
qt_error_string()));
return false;
}
@@ -230,6 +272,8 @@ bool CreateShortcutOperation::performOperation()
bool CreateShortcutOperation::undoOperation()
{
+ ensureOptionalArgumentsRead();
+
const QString &linkLocation = arguments().at(1);
if (!deleteFileNowOrLater(linkLocation) )
qDebug() << "Cannot delete:" << linkLocation;
@@ -271,8 +315,3 @@ bool CreateShortcutOperation::testOperation()
{
return true;
}
-
-Operation *CreateShortcutOperation::clone() const
-{
- return new CreateShortcutOperation();
-}