Skip to content

Commit

Permalink
Merge pull request #1408 from isanae/portable-shortcuts
Browse files Browse the repository at this point in the history
Fixes for portable shortcuts
  • Loading branch information
Holt59 authored Feb 12, 2021
2 parents 7dc28b1 + 48274f3 commit 607fafa
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 65 deletions.
11 changes: 5 additions & 6 deletions src/commandline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ std::optional<int> CommandLine::runPostApplication(MOApplication& a)
env::Console c;

if (auto i=InstanceManager::singleton().currentInstance()) {
std::cout << i->name().toStdString() << "\n";
std::cout << i->displayName().toStdString() << "\n";
} else {
std::cout << "no instance configured\n";
}
Expand Down Expand Up @@ -289,9 +289,8 @@ std::optional<int> CommandLine::runPostOrganizer(OrganizerCore& core)

return 0;
}
catch (const std::exception &e) {
reportError(
QObject::tr("failed to start shortcut: %1").arg(e.what()));
catch (std::exception&) {
// user was already warned
return 1;
}
}
Expand Down Expand Up @@ -451,7 +450,7 @@ std::optional<QString> CommandLine::instance() const
// note that moshortcut:// overrides -i

if (m_shortcut.isValid() && m_shortcut.hasInstance()) {
return m_shortcut.instance();
return m_shortcut.instanceName();
} else if (m_vm.count("instance")) {
return QString::fromStdString(m_vm["instance"].as<std::string>());
}
Expand Down Expand Up @@ -817,7 +816,7 @@ std::optional<int> RunCommand::runPostOrganizer(OrganizerCore& core)
reportError(
QObject::tr("Executable '%1' not found in instance '%2'.")
.arg(program)
.arg(InstanceManager::singleton().currentInstance()->name()));
.arg(InstanceManager::singleton().currentInstance()->displayName()));

return 1;
}
Expand Down
4 changes: 3 additions & 1 deletion src/envshortcut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,13 @@ Shortcut::Shortcut()
Shortcut::Shortcut(const Executable& exe)
: Shortcut()
{
const auto i = *InstanceManager::singleton().currentInstance();

m_name = exe.title();
m_target = QFileInfo(qApp->applicationFilePath()).absoluteFilePath();

m_arguments = QString("\"moshortcut://%1:%2\"")
.arg(InstanceManager::singleton().currentInstance()->name())
.arg(i.isPortable() ? "" : i.displayName())
.arg(exe.title());

m_description = QString("Run %1 with ModOrganizer").arg(exe.title());
Expand Down
16 changes: 8 additions & 8 deletions src/instancemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Instance::Instance(QString dir, bool portable, QString profileName) :
{
}

QString Instance::name() const
QString Instance::displayName() const
{
if (isPortable())
return QObject::tr("Portable");
Expand Down Expand Up @@ -105,7 +105,7 @@ bool Instance::isActive() const
if (m_portable) {
return i->isPortable();
} else {
return (i->name() == name());
return (i->displayName() == displayName());
}
}

Expand Down Expand Up @@ -822,7 +822,7 @@ SetupInstanceResults selectGame(Instance& instance, PluginContainer& pc)
CreateInstanceDialog dlg(pc, nullptr);

// only show the game page
dlg.setSinglePage<cid::GamePage>(instance.name());
dlg.setSinglePage<cid::GamePage>(instance.displayName());

dlg.show();
dlg.activateWindow();
Expand Down Expand Up @@ -860,7 +860,7 @@ SetupInstanceResults selectVariant(Instance& instance, PluginContainer& pc)
instance.gamePlugin(), instance.gameDirectory());

// only show the variant page
dlg.setSinglePage<cid::VariantsPage>(instance.name());
dlg.setSinglePage<cid::VariantsPage>(instance.displayName());

dlg.show();
dlg.activateWindow();
Expand Down Expand Up @@ -897,7 +897,7 @@ SetupInstanceResults setupInstance(Instance& instance, PluginContainer& pc)

reportError(
QObject::tr("Cannot open instance '%1', failed to read INI file %2.")
.arg(instance.name()).arg(instance.iniPath()));
.arg(instance.displayName()).arg(instance.iniPath()));

return SetupInstanceResults::SelectAnother;
}
Expand All @@ -914,7 +914,7 @@ SetupInstanceResults setupInstance(Instance& instance, PluginContainer& pc)
QObject::tr(
"Cannot open instance '%1', the managed game was not found in the INI "
"file %2. Select the game managed by this instance.")
.arg(instance.name()).arg(instance.iniPath()));
.arg(instance.displayName()).arg(instance.iniPath()));

return selectGame(instance, pc);
}
Expand All @@ -928,7 +928,7 @@ SetupInstanceResults setupInstance(Instance& instance, PluginContainer& pc)
QObject::tr(
"Cannot open instance '%1', the game plugin '%2' doesn't exist. It "
"may have been deleted by an antivirus. Select another instance.")
.arg(instance.name()).arg(instance.gameName()));
.arg(instance.displayName()).arg(instance.gameName()));

return SetupInstanceResults::SelectAnother;
}
Expand All @@ -943,7 +943,7 @@ SetupInstanceResults setupInstance(Instance& instance, PluginContainer& pc)
"Cannot open instance '%1', the game directory '%2' doesn't exist or "
"the game plugin '%3' doesn't recognize it. Select the game managed "
"by this instance.")
.arg(instance.name())
.arg(instance.displayName())
.arg(instance.gameDirectory())
.arg(instance.gameName()));

Expand Down
7 changes: 6 additions & 1 deletion src/instancemanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,14 @@ class Instance
// returns the instance name; this is the directory name or "Portable" for
// portable instances
//
// be careful when using this function to check whether two instances are the
// same, some parts of MO use an empty string to represent portable instances,
// but this function will return "Portable" for them; it's safer to check
// for isPortable() first
//
// can be called without setup()
//
QString name() const;
QString displayName() const;

// returns either:
// 1) the game name from the INI, if readFromIni() was called;
Expand Down
16 changes: 8 additions & 8 deletions src/instancemanagerdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ void InstanceManagerDialog::updateInstances()

// sort first, prepend portable after so it's always on top
std::sort(m_instances.begin(), m_instances.end(), [](auto&& a, auto&& b) {
return (MOBase::naturalCompare(a->name(), b->name()) < 0);
return (MOBase::naturalCompare(a->displayName(), b->displayName()) < 0);
});

if (m.portableInstanceExists()) {
Expand Down Expand Up @@ -249,7 +249,7 @@ void InstanceManagerDialog::updateList()
for (std::size_t i=0; i<m_instances.size(); ++i) {
const auto& ii = *m_instances[i];

auto* item = new QStandardItem(ii.name());
auto* item = new QStandardItem(ii.displayName());
item->setIcon(instanceIcon(m_pc, ii));

m_model->appendRow(item);
Expand Down Expand Up @@ -295,7 +295,7 @@ void InstanceManagerDialog::select(std::size_t i)
void InstanceManagerDialog::select(const QString& name)
{
for (std::size_t i=0; i<m_instances.size(); ++i) {
if (m_instances[i]->name() == name) {
if (m_instances[i]->displayName() == name) {
select(i);
return;
}
Expand All @@ -310,7 +310,7 @@ void InstanceManagerDialog::selectActiveInstance()

if (active) {
for (std::size_t i=0; i<m_instances.size(); ++i) {
if (m_instances[i]->name() == active->name()) {
if (m_instances[i]->displayName() == active->displayName()) {
select(i);

ui->list->scrollTo(
Expand Down Expand Up @@ -340,7 +340,7 @@ void InstanceManagerDialog::openSelectedInstance()
if (to.isPortable()) {
InstanceManager::singleton().setCurrentInstance("");
} else {
InstanceManager::singleton().setCurrentInstance(to.name());
InstanceManager::singleton().setCurrentInstance(to.displayName());
}

if (m_restartOnSelect) {
Expand Down Expand Up @@ -372,7 +372,7 @@ bool InstanceManagerDialog::confirmSwitch(const Instance& to)
const auto r = dlg
.title(tr("Switching instances"))
.main(tr("Mod Organizer must restart to manage the instance '%1'.")
.arg(to.name()))
.arg(to.displayName()))
.content(tr("This confirmation can be disabled in the settings."))
.icon(QMessageBox::Question)
.button({tr("Restart Mod Organizer"), QMessageBox::Ok})
Expand Down Expand Up @@ -401,7 +401,7 @@ void InstanceManagerDialog::rename()

// getting new name
const auto newName = getInstanceName(
this, tr("Rename instance"), "", tr("Instance name"), i->name());
this, tr("Rename instance"), "", tr("Instance name"), i->displayName());

if (newName.isEmpty()) {
return;
Expand Down Expand Up @@ -661,7 +661,7 @@ const Instance* InstanceManagerDialog::singleSelection() const

void InstanceManagerDialog::fillData(const Instance& ii)
{
ui->name->setText(ii.name());
ui->name->setText(ii.displayName());
ui->location->setText(ii.directory());
ui->baseDirectory->setText(ii.baseDirectory());
ui->gameName->setText(ii.gameName());
Expand Down
16 changes: 10 additions & 6 deletions src/moapplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,10 +392,14 @@ void MOApplication::externalMessage(const QString& message)

if (moshortcut.isValid()) {
if(moshortcut.hasExecutable()) {
m_core->processRunner()
.setFromShortcut(moshortcut)
.setWaitForCompletion(ProcessRunner::TriggerRefresh)
.run();
try {
m_core->processRunner()
.setFromShortcut(moshortcut)
.setWaitForCompletion(ProcessRunner::TriggerRefresh)
.run();
} catch(std::exception&) {
// user was already warned
}
}
} else if (isNxmLink(message)) {
MessageDialog::showMessage(tr("Download started"), qApp->activeWindow(), false);
Expand All @@ -414,11 +418,11 @@ void MOApplication::externalMessage(const QString& message)
if (auto i=cl.instance()) {
const auto ci = InstanceManager::singleton().currentInstance();

if (*i != ci->name()) {
if (*i != ci->displayName()) {
reportError(tr(
"This shortcut or command line is for instance '%1', but the current "
"instance is '%2'.")
.arg(*i).arg(ci->name()));
.arg(*i).arg(ci->displayName()));

return;
}
Expand Down
67 changes: 46 additions & 21 deletions src/moshortcut.cpp
Original file line number Diff line number Diff line change
@@ -1,25 +1,5 @@
/*
Copyright (C) 2016 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/


#include "moshortcut.h"

#include "instancemanager.h"

MOShortcut::MOShortcut(const QString& link)
: m_valid(link.startsWith("moshortcut://"))
Expand All @@ -41,6 +21,51 @@ MOShortcut::MOShortcut(const QString& link)
}
}

bool MOShortcut::isValid() const
{
return m_valid;
}

bool MOShortcut::hasInstance() const
{
return m_hasInstance;
}

bool MOShortcut::hasExecutable() const
{
return m_hasExecutable;
}

QString MOShortcut::instanceDisplayName() const
{
return (m_instance == "" ? QObject::tr("Portable") : m_instance);
}

const QString& MOShortcut::instanceName() const
{
return m_instance;
}

const QString& MOShortcut::executableName() const
{
return m_executable;
}

bool MOShortcut::isForInstance(const Instance& i) const
{
if (!m_hasInstance) {
// no instance name was specified, so the current one is fine
return true;
}

if (m_instance == "") {
// empty instance name means portable
return i.isPortable();
} else {
return (i.displayName() == m_instance);
}
}

QString MOShortcut::toString() const
{
if (m_hasInstance) {
Expand Down
33 changes: 27 additions & 6 deletions src/moshortcut.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,42 @@

#include <QString>

class Instance;

class MOShortcut
{
public:
MOShortcut(const QString& link={});

/// true iff intialized using a valid moshortcut link
bool isValid() const { return m_valid; }
// true if initialized using a valid moshortcut link
//
bool isValid() const;

// whether an instance name was given
//
bool hasInstance() const;

// whether an executable name was given
//
bool hasExecutable() const;

bool hasInstance() const { return m_hasInstance; }
// name of the instance given, "Portable" for portable; undefined if
// hasInstance() returns false
//
QString instanceDisplayName() const;

bool hasExecutable() const { return m_hasExecutable; }
// name of the instance given, empty for portable; undefined if hasInstance()
// returns false
//
const QString& instanceName() const;

const QString& instance() const { return m_instance; }
// name of the executable given
//
const QString& executableName() const;

const QString& executable() const { return m_executable; }
// whether this shortcut is for the given instance
//
bool isForInstance(const Instance& i) const;

QString toString() const;

Expand Down
Loading

0 comments on commit 607fafa

Please sign in to comment.