Compare commits

..
Author SHA1 Message Date
Tannin b7edde6fa0 custom installers can now set the installation file (and the ncc installer now does) 2014-12-14 16:30:23 +01:00
Tannin 589325d91b - NCC installer can now discover files in other mods (thanks Reunion!) and knows the script extender version 2014-12-13 16:47:11 +01:00
Tannin 994018a491 minor fixes 2014-12-04 19:25:07 +01:00
Tannin 7c8fafc196 several bugfixes from the bugfix-wc that I forgot to backport 2014-11-26 20:21:33 +01:00
Tannin 29c66c621d - updated staging script to use qt5 and to fetch translations from transifex
- removed call to function unavailable in Windows XP
2014-11-11 23:48:22 +01:00
Tannin 7b5f01b49d - bsa parser will now cancel in case of a read error. Before, when attempting to parse a broken bsa it could take forever and continuously allocate memory
- better error message when bsa parsing fails
- slightly better support for font colors in bbcode converter
- configurator now also uses pyqt5
- bugfix: bsa hashing function converted backslashes to slashes instead of the other way around. hash calculation is still often wrong on folder names...
2014-11-09 14:01:48 +01:00
Tannin a738cef190 - moved the hook-recursion-protection to tls
- some code cleanup and consolidation
- hook.dll will now report all of its own exceptions
- some more logging during startup
- changed the way urls are encoded for download requests
- now displaying (one of the) process name(s) while waiting for a program to end
- bugfix: spawned processes were forced to leave the job
2014-09-29 20:35:35 +02:00
Tannin 2bf3ba0984 plugins can now query the list of masters for a plugin 2014-09-10 20:37:17 +02:00
Tannin b76c4a1869 - re-enabled building of loot_cli and started developing against the new api
- extended set of default categories
- more tolerand bbcode parser
- added a few colors for the bbcode parser
- more fixes to qt5 compatibility
- started work on ability to unloading (and thus re-loading) of plugins
- names of plugins are no longer localizable (because those names are also used to store settings)
- added settings to disable individual diagnosis settings
- path of dependencies is now configured in a .pri file instead of environment variablees
- bugfix: if the modid-input is canceled, the id was saved as -1 and wasn't re-requested from the user
- bugfix: moving files with the SHFileOperation-Api didn't update the vfs correctly (still not perfect but better)
- bugfix: attempt to remove the deleter-file seems to have caused error messages for some users
- bugfix: fixed a couple of cases that might have caused the tutorial to hang
2014-09-08 20:37:23 +02:00
Tannin ae8b6a39b0 - browser dialog now has a hidden url-field (for testing only)
- loot_cli is no longer part of this project. I will probably create a fork of loot that allows command-line usage instead
- loot integration now works with such a modified loot version
- integrated loot will now also integrate incompatibility messages in the MO UI
- overwrite-markers are now updated as the list order is changed
- fnis checker will now always allow the user to ignore fnis errors
- plugin interface now has a function to wait for handles returned from startApplication (which can be job or process handles)
- bugfix: non-mo mods sharing the name with regular mods now have a different internal name
- bugfix: using hotkeys the vanilla game-plugins could be moved
2014-07-27 18:34:32 +02:00
TheBloke 2dc9463951 pythonRunner.pro - formatting/consistency fixes
Same types of fixes as previous commit; missed this file.
2014-07-08 00:28:06 +01:00
TheBloke 1d4a4b485d .pro files - formatting/consistency fixes
Many small formatting changes to the majority of .pro files
 Consistent style for Qt version checking, using greaterThan(QT_MAJOR_VERSION, 4)
  This seems safest, as would continue to work for a future Qt 6 etc.
  Note that this makes redudundant the commit before this one, to organizer.pro
 Consistent indenting
 Moved some file configuration sections to be together with related sections
 Moved some installation-related sections (e.g. OUTDIR/DSTDIR) to be at the bottom,
  immediately before the related POST_LINK install lines.
 Similarly, in some cases separated out CONFIG(debug,.. checks into separate
  LIB/INCLUDE sections (high in file) and installation directory sections (low
   in file)
2014-07-07 23:32:18 +01:00
Tannin d5838c7560 - added pseudo-categories to filter for mo-managed vs. unmanaged mods
- deleted mods are now moved to the recycle bin instead of being deleted permanently
- reduced modinfo dialog for foreign mods
- foreign mods are now displayed with a pseudo-category
- added a signal when a plugin is moved
- bugfix: refreshing of directory structure for mods with bsas didn't work correctly when enabling a mod and on changing display of foreign mods
- bugfix: one mod in the list was assigned the same priority on the directory structure as the data directory
- bugfix: conflicts tab in the mod info dialog offered the hide option for files in bsas
2014-06-16 21:49:57 +02:00
Tannin 9cbf374166 - loot client now only updates the masterlist once per MO session
- new event to notify plugins of changed mod priority
- overwrite now shows up in the "checked" category instead of "unchecked"
- display of "foreign" mods can now be limited to only official content
- bugfix: bsa extraction dialog showed up even if the plugin was disabled
- bugfix: after detection of foreign mods the priority of the overwrite folder could get messed up
- bugfix: when displaying only the context menu for the mod list as a whole, the menu didn't disappear
- bugfix: MO crashed when trying to download via the integrated browser
2014-06-08 15:10:08 +02:00
Tannin f71bfff0e6 Merge 2014-05-28 14:23:11 +02:00
Tannin 8aa2ab4eac small bugfixes 2014-05-28 14:14:28 +02:00
Tannin 46a0ce9e38 - files in bsas are now only displayed in the data tab if they are managed by mo
- number of problems detected by MO is now displayed as a badge on the icon
- rephrased the explanation text on the Archives tab. unchecked plugin-loaded bsas no longer prompt a warning
- bsa extraction is now handled in a plugin
- added a way for plugins to react to mod installation
- re-enabled the automatic fix for asset order problems
- bugfix: In some cases when a download wasn't started successfully the download urls weren't stored in the meta file so no resume was possible
- bugfix: MO tried to resume downloads when it didn't have and download urls
- bugfix: downloads couldn't be paused if the download was already broken on the network layer
- bugfix: download managear did not recognize a file as downloaded if the download completed before signals were hooked up
- bugfix: in-place file replacement was re-broken
2014-05-25 15:39:45 +02:00
Tannin 15e635741c - mod list context menu split into two menus (one for whole list, one for selected mods)
- added option to combine category filters using "or"
- added context menu option for deselecting category filters
- slightly changed ui on the category filters
- added a sample plugin for cpp that can be built without building the rest of MO
- simple installer can now be configured to run without any user interaction
- extended interface for python plugins
- iorganizer implementation moved out of the main window
- nexus requests from plugins will now be identified in the user agent
- bugfix: shortcuts created from MO used the wrong working directory
- bugfix: deactivation of bsas didn't stick
- bugfix: file hiding mechanism wasn't active
- bugfix: executables linked on the toolbar couldn't be removed if the executable was removed first
- bugfix: the endorsement-filter couldn't be combined with other filters
- bugfix: python interface to repository bridge was broken
2014-05-13 21:20:44 +02:00
Tannin f56c605479 - bugfix: endless loop in detection of mod order problems 2014-05-04 16:13:35 +02:00
Tannin 617c76e9f8 - main window now has a small view displaying log messages
- mod list will now be highlighted when grouping is active is active
- download tooltip now supports bbcode markup in the description
- bbcode translator will now translate some named colors
- algorithm for detection of mod order problems is now more sophisticated
- exposed more functionality to python plugins
- updated to qt 4.8.6 dlls
- bugfix: plugin list wasn't
- bugfix: state changes in mod list wasn't always reported
- bugfix: loot client will now create necessary directory
- bugfix: NCC sometimes used wrong source path for extracting
- bugfix: removed noisy debug message
2014-05-04 14:50:01 +02:00
Tannin 96081888f1 Merge with branch1.1 2014-04-05 15:36:42 +02:00
Tannin af5958b0af some fixes towards qt5 compatibility 2014-03-16 20:04:57 +01:00
Tannin b33293e49a - bugfix: elevation dialog didn't offer a "yes" option
- bugfix: python plugins crashed the application when trying to create a nexus bridge
- bugfix: python plugins couldn't register for failed requests correctly
2014-01-29 21:06:55 +01:00
Tannin dc3b60e578 - bugfix: accessing profile without loading one when starting an app through the commandline
- bugfix: locked-dialog was disabled
2014-01-27 21:31:10 +01:00
Tannin d591bc017a Merge with default 2013-12-07 16:55:19 +01:00
Tannin aad5864192 minor text changes 2013-12-07 14:23:51 +01:00
Tannin 7deee938d3 - bugfix: installFile for mods was not a relative path if the downloads directory was non-default
- bugfix: crash after removing the last profile in the list (ordered alphabetically)
- improved subdirs ordering to ensure pythonrunner is compiled before pythonproxy
- translation files for plugins are now generated
- set some texts as un-translatable where it made no sense
- staging script now re-builds MO completely before packaging
- updated qt libraries for packaging to 4.8.5
- added python to the package
2013-11-22 17:45:34 +01:00
Tannin 5d51b2bcc6 added some files missing from the previous commit 2013-11-18 22:03:23 +01:00
Tannin 0566a968e8 - archive.dll now supports querying the crc value of files
- esptk now determines if a esp is a dummy (without records)
- hook.dll no longer creates a log file if noone wrote to it
- nexus id and installtime columns are now hidden by default
- modlist can now be refreshed without saving first (so plugins can replace the modlist.txt as a whole)
- plugins can now query more details about virtualised files
- added style options "plastique" and "cleanlooks"
- "overwrite" is no longer listed with a creation time
- a warning will now be displayed if the user has too many plugins active
- a warning will now be displayed if mods with scripts have an installation order that doesn't match the corresponding esp load order
- nmm importer now has select all/deselect all buttons
- nmm importer no longer tries to unpack missing files from archives (won't work anyway)
- initial support for importing from nmm 0.5 alpha
- removed some broken warning suppresions
- python runner now works with bundled python
- extended qbs build system (still fails to build the main gui application)
- implemented a nsis-based installer
2013-11-18 20:17:14 +01:00
Tannin 14fc674d72 - diagnosis plugins can now request to be re-evaluated
- main application now contains means for plugins to react on some changes (to be extended)
- plugins can now retrieve more information about a mod
- user-agent sent to nexus now automatically contains the current MO version
- included updated russian translation
- problems dialog now refreshes itself after a fix was applied
- fixed new esp/asset ordering diagnosis. May be fully functional now
- bugfix: restoring locked load order could leave MO in an endless loop (not sure if this fix is correct yet)
- bugfix: plugin list was not visually updated after some changes
- bugfix: nmm importer threw away mod ordering
2013-11-06 18:35:27 +01:00
Tannin b7cbdaad1e - added a new diagnosis to detect potential problems in regards to esp vs. asset ordering (not fully functional yet)
- new plugin interfaces to the mod list
- plugins can now query the origin (mod) of a esp/esm
- bugfix: potential access to profile before one was activated
- bugfix: regression in previous (not-yet-released) commit prevented changes to bsa list from being saved
2013-11-01 14:59:25 +01:00
Tannin 25cdcdd2fe - plugin (esp/esm) list is now exposed to plugins (read-only functionality right now)
- integrated fomod installer now supports file dependencies
- bugfix: integrated fomod installer crashed if the installer had no optiosn´´ns
2013-10-16 23:04:03 +02:00
Tannin f06a6d4e55 - added new plugin to test if fnis needs to be run
- some functionality to the plugin interface to enable them to search for files&directories in the virtual FS (rudimentary atm)
- functionality for plugins to react to application being started from MO
- broken ESPs are no longer reported as popup windows but only in the log file
- bugfix: plugins couldn't store persistent data if they had no user-editable settings
2013-10-11 23:03:49 +02:00
Tannin ceab36e5f0 - download progress is now visible in task bar
- esp-tooltip now lists all masters, highlighting the missing ones
- python plugin will now report a problem if the path contains a semicolon
- leak detection now (somewaht) works around the fact that we don't always get a stack trace
- bugfix: mod meta-file is now reliably created if it was missing
- bugfix: parser for nxm-links didn't handle numbers in the mod name
- bugfix: small memory leak
2013-09-28 21:13:57 +02:00
Tannin e158038cfc - esp reader now handles invalid files more gracefully
- files moved will now also be treated as "deleted" in the old location so a newly created file with that same name is not created in overwrite
- introduced a mechanism by which MO can recognize if it crashed before when attempting to load a plugin. That plugin can be blacklisted so it doesn't get loaded again
- plugins can now programaticaly change their settings
- plugins can now store data persistently without exposing that data as settings
- requesting an unset-setting from a plugin is no longer treated as a bug
- clarified warning message for when files are in overwrite directory
- the proxyPython plugin will now discover if python initialization crashed MO on a previous session and give the user a chance to fix it or disable the plugin
- bugfix: GetModuleFileName modified the buffer past the zero termination. While this doesn't violate the API documentation it is different from the regular windows implementation
- bugfix: proxy plugins couldn't access the parent widget
- bugfix: when moving a file from overwrite to a mod the in-memory file structure wasn't updated
- bugfix: name input dialog for profiles allowed names that weren't valid directory names
- bugfix: profile dialog wasn't able to delete profiles if the name started or ended in whitespaces
- bugfix: The name-cells for plugin settings could be changed (without effect)
- removed a few obsolete files from the repository
2013-09-21 19:25:33 +02:00
Tannin d4c424911a - bugfix: testing for missing masters at the wrong time seems to have caused crashes
- bugfix: mod list is now written to a temporary file first. Only on success is the original file overwritten
- bugfix: moving a mod priority to just above the overwrite could cause a crash or error message
- bugfix: versions with a release candidate number weren't sorted correctly (woops)
- bugfix: staging script didn't include archive.dll and dlls.manifest
- installation time on overwrite no longer updates constantly
2013-09-16 22:32:42 +02:00
Tannin fee774db45 - added support for mod page plugins
- re-introduced the integrated browser
- added a plugin to download from the tes alliance page
- the download list now contains the file description
- nexus interface now stores cookies persistently to reduce number of required log-ins
2013-09-15 15:20:00 +02:00
Tannin b9c2a18f86 updated versions 2013-09-05 21:14:08 +02:00
Tannin 224627515a - bugfix: automatically removes a file from old NCC release that was interfering with the current version
- bugfix: fomod installer didn't find fomod files in nested folder
- bugfix: python proxy will now not even try to initialize python if python_dir contains no python.
This is necessary because the python interpreter crashes the application if the path is invalid
2013-09-05 21:04:20 +02:00
14 changed files with 692 additions and 165 deletions
+4
View File
@@ -1,3 +1,7 @@
#include "resource.h"
#ifdef _DEBUG
IDR_LOADER_DLL BINARY MOVEABLE PURE "..\\..\\pythonRunner\\debug\\pythonRunner.dll"
#else // _DEBUG
IDR_LOADER_DLL BINARY MOVEABLE PURE "..\\..\\pythonRunner\\release\\pythonRunner.dll"
#endif // _DEBUG
+9 -10
View File
@@ -8,13 +8,10 @@
TARGET = proxyPython
TEMPLATE = lib
contains(QT_VERSION, "^5.*") {
QT += widgets
}
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += plugins
CONFIG += dll
CONFIG += warn_on
CONFIG(release, debug|release) {
QMAKE_CXXFLAGS += /Zi
@@ -23,6 +20,9 @@ CONFIG(release, debug|release) {
DEFINES += PROXYPYTHON_LIBRARY
# suppress a few warnings caused by boost vs vc++ paranoia
DEFINES += _SCL_SECURE_NO_WARNINGS
SOURCES += proxypython.cpp
HEADERS += proxypython.h \
resource.h
@@ -36,15 +36,14 @@ RC_FILE += \
include(../plugin_template.pri)
INCLUDEPATH += "../../pythonRunner"
INCLUDEPATH += "../../pythonRunner" "$${BOOSTPATH}"
WINPWD = $$PWD
WINPWD ~= s,/,$$QMAKE_DIR_SEP,g
//QMAKE_POST_LINK += SET VS90COMNTOOLS=%VS100COMNTOOLS% $$escape_expand(\\n)
#QMAKE_POST_LINK += SET VS90COMNTOOLS=%VS100COMNTOOLS% $$escape_expand(\\n)
QMAKE_POST_LINK += copy $$(PYTHONPATH)\\lib\\site-packages\\sip.pyd $$quote($$DSTDIR)\\plugins\\data\\ $$escape_expand(\\n)
QMAKE_POST_LINK += copy $$(PYTHONPATH)\\lib\\site-packages\\PyQt4\\QtCore.pyd $$quote($$DSTDIR)\\plugins\\data\\ $$escape_expand(\\n)
QMAKE_POST_LINK += copy $$(PYTHONPATH)\\lib\\site-packages\\PyQt4\\QtGui.pyd $$quote($$DSTDIR)\\plugins\\data\\ $$escape_expand(\\n)
#QMAKE_POST_LINK += copy $$(PYTHONPATH)\\lib\\site-packages\\sip.pyd $$quote($$DSTDIR)\\plugins\\data\\ $$escape_expand(\\n)
#QMAKE_POST_LINK += copy $$(PYTHONPATH)\\lib\\site-packages\\PyQt4\\QtCore.pyd $$quote($$DSTDIR)\\plugins\\data\\PyQt4\\ $$escape_expand(\\n)
#QMAKE_POST_LINK += copy $$(PYTHONPATH)\\lib\\site-packages\\PyQt4\\QtGui.pyd $$quote($$DSTDIR)\\plugins\\data\\PyQt4\\ $$escape_expand(\\n)
+127 -31
View File
@@ -1,16 +1,31 @@
#pragma warning( push )
#pragma warning( disable : 4100 ) // a lot of unreferenced formal parameters from boost libraries
#pragma warning( disable : 4996 ) // strncpy claimed to be unsafe
/*
Copyright (C) 2013 Sebastian Herbord. All rights reserved.
This file is part of python proxy plugin for MO
python proxy plugin 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.
Python proxy plugin 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 python proxy plugin. If not, see <http://www.gnu.org/licenses/>.
*/
#include "proxypython.h"
#pragma warning( pop )
#include <utility.h>
#include <versioninfo.h>
#include <QtPlugin>
#include <QDirIterator>
#include <QWidget>
#include <QMessageBox>
#include <QCoreApplication>
#include "resource.h"
@@ -32,8 +47,6 @@ HMODULE GetOwnModuleHandle()
QString ExtractResource(WORD resourceID, const QString &szFilename)
{
bool success = false;
HMODULE mod = GetOwnModuleHandle();
HRSRC hResource = FindResourceW(mod, MAKEINTRESOURCE(resourceID), L"BINARY");
@@ -85,8 +98,23 @@ typedef IPythonRunner* (*CreatePythonRunner_func)(const MOBase::IOrganizer *moIn
bool ProxyPython::init(IOrganizer *moInfo)
{
m_MOInfo = moInfo;
if (!m_MOInfo->pluginSetting(name(), "enabled").toBool()) {
m_LoadFailure = FAIL_NONE;
return false;
}
m_LoadFailure = FAIL_OTHER;
if (QCoreApplication::applicationDirPath().contains(';')) {
m_LoadFailure = FAIL_SEMICOLON;
return true;
}
QString pythonPath = m_MOInfo->pluginSetting(name(), "python_dir").toString();
if (!pythonPath.isEmpty() && !QFile::exists(pythonPath + "/python.exe")) {
m_LoadFailure = FAIL_WRONGPYTHONPATH;
return true;
}
m_TempRunnerFile = ExtractResource(IDR_LOADER_DLL, "__pythonRunner.dll");
m_RunnerLib = ::LoadLibraryW(ToWString(m_TempRunnerFile).c_str());
@@ -95,8 +123,33 @@ bool ProxyPython::init(IOrganizer *moInfo)
if (CreatePythonRunner == NULL) {
throw MyException("embedded dll is invalid: " + windowsErrorString(::GetLastError()));
}
m_Runner = CreatePythonRunner(moInfo, m_MOInfo->pluginSetting(name(), "python_dir").toString());
m_LoadFailure = FAIL_NONE;
if (m_MOInfo->persistent(name(), "tryInit", false).toBool()) {
if (pythonPath.isEmpty()) {
m_LoadFailure = FAIL_PYTHONDETECTION;
} else {
m_LoadFailure = FAIL_WRONGPYTHONPATH;
}
if (QMessageBox::question(parentWidget(), tr("Python Initialization failed"),
tr("On a previous start the Python Plugin failed to initialize.\n"
"Either the value in Settings->Plugins->ProxyPython->plugin_dir is set incorrectly or it is empty and auto-detection doesn't work "
"for whatever reason.\n"
"Do you want to try initializing python again (at the risk of another crash)?\n"
"Suggestion: Select \"no\", and click the warning sign for further help. Afterwards you have to re-enable the python plugin."),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No) {
m_MOInfo->setPluginSetting(name(), "enabled", false);
return true;
}
}
m_MOInfo->setPersistent(name(), "tryInit", true);
m_Runner = CreatePythonRunner(moInfo, pythonPath);
m_MOInfo->setPersistent(name(), "tryInit", false);
if (m_Runner != NULL) {
m_LoadFailure = FAIL_NONE;
} else {
m_LoadFailure = FAIL_INITFAIL;
}
return true;
} else {
DWORD error = ::GetLastError();
@@ -110,7 +163,7 @@ bool ProxyPython::init(IOrganizer *moInfo)
QString ProxyPython::name() const
{
return tr("Python Proxy");
return "Python Proxy";
}
QString ProxyPython::author() const
@@ -125,7 +178,7 @@ QString ProxyPython::description() const
VersionInfo ProxyPython::version() const
{
return VersionInfo(1, 1, 0, VersionInfo::RELEASE_FINAL);
return VersionInfo(1, 3, 1, VersionInfo::RELEASE_FINAL);
}
bool ProxyPython::isActive() const
@@ -137,6 +190,7 @@ QList<PluginSetting> ProxyPython::settings() const
{
QList<PluginSetting> result;
result.push_back(PluginSetting("python_dir", "Path to your python installation. Leave empty for auto-detection", ""));
result.push_back(PluginSetting("enabled", "Set to true to enable support for python plugins", true));
return result;
}
@@ -156,7 +210,8 @@ QStringList ProxyPython::pluginList(const QString &pluginPath) const
QObject *ProxyPython::instantiate(const QString &pluginName)
{
if (m_Runner != NULL) {
return m_Runner->instantiate(pluginName);
QObject *result = m_Runner->instantiate(pluginName);
return result;
} else {
return NULL;
}
@@ -168,6 +223,14 @@ std::vector<unsigned int> ProxyPython::activeProblems() const
std::vector<unsigned int> result;
if (m_LoadFailure == FAIL_MISSINGDEPENDENCIES) {
result.push_back(PROBLEM_PYTHONMISSING);
} else if (m_LoadFailure == FAIL_WRONGPYTHONPATH) {
result.push_back(PROBLEM_WRONGPYTHONPATH);
} else if (m_LoadFailure == FAIL_PYTHONDETECTION) {
result.push_back(PROBLEM_PYTHONDETECTION);
} else if (m_LoadFailure == FAIL_INITFAIL) {
result.push_back(PROBLEM_INITFAIL);
} else if (m_LoadFailure == FAIL_SEMICOLON) {
result.push_back(PROBLEM_SEMICOLON);
} else if (m_Runner != NULL) {
if (!m_Runner->isPythonInstalled()) {
// don't know how this could happen but wth
@@ -185,11 +248,23 @@ QString ProxyPython::shortDescription(unsigned int key) const
{
switch (key) {
case PROBLEM_PYTHONMISSING: {
return tr("Python not installed or not found");
} break;
return tr("Python not installed or not found");
} break;
case PROBLEM_PYTHONWRONGVERSION: {
return tr("Python version is incompatible");
} break;
return tr("Python version is incompatible");
} break;
case PROBLEM_WRONGPYTHONPATH: {
return tr("Invalid python path");
} break;
case PROBLEM_INITFAIL: {
return tr("Initializing Python failed");
} break;
case PROBLEM_PYTHONDETECTION: {
return tr("Python auto-detection failed");
} break;
case PROBLEM_SEMICOLON: {
return tr("ModOrganizer path contains a semicolon");
} break;
default:
throw MyException(tr("invalid problem key %1").arg(key));
}
@@ -200,29 +275,50 @@ QString ProxyPython::fullDescription(unsigned int key) const
{
switch (key) {
case PROBLEM_PYTHONMISSING: {
return tr("Some plugins require the python interpreter to be installed. "
"These plugins will not even show up in settings-&gt;plugins.<br>"
"If you want to use those plugins, please install the 32-bit version of Python 2.7.x from <a href=\"%1\">%1</a>.").arg(s_DownloadPythonURL);
} break;
return tr("Some MO plugins require the python interpreter to be installed. "
"These plugins will not even show up in settings-&gt;plugins.<br>"
"If you want to use those plugins, please install the 32-bit version of Python 2.7.x from <a href=\"%1\">%1</a>.<br>"
"This is only required to use some extended functionality in MO, you do not need Python to play the game.").arg(s_DownloadPythonURL);
} break;
case PROBLEM_PYTHONWRONGVERSION: {
return tr("Your installed python version has a different version than 2.7. "
"Some plugins may not work.<br>"
"If you have multiple versions of python installed you may have to configure the path to 2.7 "
"in the settings dialog.");
} break;
return tr("Your installed python version has a different version than 2.7. "
"Some MO plugins may not work.<br>"
"If you have multiple versions of python installed you may have to configure the path to 2.7 (32 bit) "
"in the settings dialog.<br>"
"This is only required to use some extended functionality in MO, you do not need Python to play the game.");
} break;
case PROBLEM_WRONGPYTHONPATH: {
return tr("Please set python_dir in Settings->Plugins->ProxyPython to the path of your python 2.7 (32 bit) installation.");
} break;
case PROBLEM_PYTHONDETECTION: {
return tr("The auto-detection of the python path failed. I don't know why this would happen but you can try to fix it "
"by setting python_dir in Settings->Plugins->ProxyPython to the path of your python 2.7 (32 bit) installation.");
} break;
case PROBLEM_INITFAIL: {
return tr("Sorry, I don't know any details. Most likely your python installation is not supported.");
} break;
case PROBLEM_SEMICOLON: {
return tr("The path to Mod Organizer (%1) contains a semicolon. <br>"
"While this is legal on NTFS drives there is a lot of software that doesn't handle it correctly.<br>"
"Unfortunately MO depends on libraries that seem to fall into that group.<br>"
"As a result the python plugin can't be loaded.<br>"
"The only solution I can offer is to remove the semicolon / move MO to a path without a semicolon.").arg(QCoreApplication::applicationDirPath());
} break;
default:
throw MyException(tr("invalid problem key %1").arg(key));
throw MyException(QString("invalid problem key %1").arg(key));
}
}
bool ProxyPython::hasGuidedFix(unsigned int) const
bool ProxyPython::hasGuidedFix(unsigned int key) const
{
return true;
return (key == PROBLEM_PYTHONMISSING) || (key == PROBLEM_PYTHONWRONGVERSION);
}
void ProxyPython::startGuidedFix(unsigned int) const
void ProxyPython::startGuidedFix(unsigned int key) const
{
::ShellExecuteA(NULL, "open", s_DownloadPythonURL, NULL, NULL, SW_SHOWNORMAL);
if ((key == PROBLEM_PYTHONMISSING) || (key == PROBLEM_PYTHONWRONGVERSION)) {
::ShellExecuteA(NULL, "open", s_DownloadPythonURL, NULL, NULL, SW_SHOWNORMAL);
}
}
+28 -1
View File
@@ -1,3 +1,22 @@
/*
Copyright (C) 2013 Sebastian Herbord. All rights reserved.
This file is part of python proxy plugin for MO
python proxy plugin 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.
Python proxy plugin 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 python proxy plugin. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PROXYPYTHON_H
#define PROXYPYTHON_H
@@ -50,17 +69,25 @@ private:
static const unsigned int PROBLEM_PYTHONMISSING = 1;
static const unsigned int PROBLEM_PYTHONWRONGVERSION = 2;
static const unsigned int PROBLEM_WRONGPYTHONPATH = 3;
static const unsigned int PROBLEM_INITFAIL = 4;
static const unsigned int PROBLEM_PYTHONDETECTION = 5;
static const unsigned int PROBLEM_SEMICOLON = 6;
static const char *s_DownloadPythonURL;
const MOBase::IOrganizer *m_MOInfo;
MOBase::IOrganizer *m_MOInfo;
QString m_TempRunnerFile;
HMODULE m_RunnerLib;
IPythonRunner *m_Runner;
enum {
FAIL_NONE,
FAIL_SEMICOLON,
FAIL_NOTINIT,
FAIL_MISSINGDEPENDENCIES,
FAIL_INITFAIL,
FAIL_WRONGPYTHONPATH,
FAIL_PYTHONDETECTION,
FAIL_OTHER
} m_LoadFailure;
+2
View File
@@ -1,4 +1,6 @@
#ifndef Q_MOC_RUN
#include <boost/python.hpp>
#endif
#include <QString>
#include <utility.h>
+16 -16
View File
@@ -1,5 +1,5 @@
//#define HAVE_ROUND
#include "proxypluginwrappers.h"
#include <boost/python.hpp>
#include <utility.h>
#include "error.h"
#include "gilock.h"
@@ -27,63 +27,63 @@ bool IPluginToolWrapper::init(MOBase::IOrganizer *moInfo)
QString IPluginToolWrapper::name() const
{
try {
return this->get_override("name")();
return this->get_override("name")().as<QString>();
} PYCATCH;
}
QString IPluginToolWrapper::author() const
{
try {
return this->get_override("author")();
return this->get_override("author")().as<QString>();
} PYCATCH;
}
QString IPluginToolWrapper::description() const
{
try {
return this->get_override("description")();
return this->get_override("description")().as<QString>();
} PYCATCH;
}
MOBase::VersionInfo IPluginToolWrapper::version() const
{
try {
return this->get_override("version")();
return this->get_override("version")().as<MOBase::VersionInfo>();
} PYCATCH;
}
bool IPluginToolWrapper::isActive() const
{
try {
return this->get_override("isActive")();
return this->get_override("isActive")().as<bool>();
} PYCATCH;
}
QList<MOBase::PluginSetting> IPluginToolWrapper::settings() const
{
try {
return this->get_override("settings")();
return this->get_override("settings")().as<QList<MOBase::PluginSetting>>();
} PYCATCH;
}
QString IPluginToolWrapper::displayName() const
{
try {
return this->get_override("displayName")();
return this->get_override("displayName")().as<QString>();
} PYCATCH;
}
QString IPluginToolWrapper::tooltip() const
{
try {
return this->get_override("tooltip")();
return this->get_override("tooltip")().as<QString>();
} PYCATCH;
}
QIcon IPluginToolWrapper::icon() const
{
try {
return this->get_override("icon")();
return this->get_override("icon")().as<QIcon>();
} PYCATCH;
}
@@ -118,21 +118,21 @@ bool IPluginInstallerCustomWrapper::init(MOBase::IOrganizer *moInfo)
QString IPluginInstallerCustomWrapper::name() const
{
try {
return this->get_override("name")();
return this->get_override("name")().as<QString>();
} PYCATCH;
}
QString IPluginInstallerCustomWrapper::author() const
{
try {
return this->get_override("author")();
return this->get_override("author")().as<QString>();
} PYCATCH;
}
QString IPluginInstallerCustomWrapper::description() const
{
try {
return this->get_override("description")();
return this->get_override("description")().as<QString>();
} PYCATCH;
}
@@ -153,7 +153,7 @@ bool IPluginInstallerCustomWrapper::isActive() const
QList<MOBase::PluginSetting> IPluginInstallerCustomWrapper::settings() const
{
try {
return this->get_override("settings")();
return this->get_override("settings")().as<QList<MOBase::PluginSetting>>();
} PYCATCH;
}
@@ -171,7 +171,7 @@ bool IPluginInstallerCustomWrapper::isManualInstaller() const
} PYCATCH;
}
bool IPluginInstallerCustomWrapper::isArchiveSupported(const DirectoryTree &tree) const
bool IPluginInstallerCustomWrapper::isArchiveSupported(const DirectoryTree &) const
{
try {
//return this->get_override("isArchiveSupported")(tree);
@@ -189,7 +189,7 @@ bool IPluginInstallerCustomWrapper::isArchiveSupported(const QString &archiveNam
std::set<QString> IPluginInstallerCustomWrapper::supportedExtensions() const
{
try {
return this->get_override("supportedExtensions")();
return this->get_override("supportedExtensions")().as<std::set<QString>>();
} PYCATCH;
}
-1
View File
@@ -5,7 +5,6 @@
#include <iplugintool.h>
#include <iplugininstallersimple.h>
#include <iplugininstallercustom.h>
#include <iplugindiagnose.h>
#ifndef Q_MOC_RUN
#include <boost/python.hpp>
+26 -7
View File
@@ -12,6 +12,15 @@ CONFIG += warn_on
DEFINES += PYTHONRUNNER_LIBRARY
# suppress a few warnings caused by boost vs vc++ paranoia
DEFINES += _SCL_SECURE_NO_WARNINGS -DHAVE_ROUND
!include(../LocalPaths.pri) {
message("paths to required libraries need to be set up in LocalPaths.pri")
}
SOURCES += pythonrunner.cpp \
gilock.cpp \
error.cpp \
@@ -25,18 +34,28 @@ HEADERS += pythonrunner.h \
pythonpluginwrapper.h \
proxypluginwrappers.h
CONFIG(debug, debug|release) {
LIBS += -L$$OUT_PWD/../uibase/debug
} else {
LIBS += -L$$OUT_PWD/../uibase/release
QMAKE_CXXFLAGS += /Zi
QMAKE_LFLAGS += /DEBUG
}
INCLUDEPATH += "$(BOOSTPATH)" "$$(PYTHONPATH)/include" "$$(PYTHONPATH)/Lib/site-packages/PyQt4/include"
LIBS += -L"$$(PYTHONPATH)/libs" -L"$(BOOSTPATH)/stage/lib"
INCLUDEPATH += "$${BOOSTPATH}" "$${PYTHONPATH}/include" "$${PYTHONPATH}/Lib/site-packages/PyQt5/include" ../uibase
LIBS += -L"$${PYTHONPATH}/libs" -L"$${BOOSTPATH}/stage/lib"
LIBS += -lpython27
INCLUDEPATH += ../uibase
LIBS += -luibase
CONFIG(debug, debug|release) {
SRCDIR = $$OUT_PWD/debug
DSTDIR = $$PWD/../../outputd
} else {
SRCDIR = $$OUT_PWD/release
DSTDIR = $$PWD/../../output
}
SRCDIR ~= s,/,$$QMAKE_DIR_SEP,g
DSTDIR ~= s,/,$$QMAKE_DIR_SEP,g
QMAKE_POST_LINK += xcopy /y /I $$quote($$SRCDIR\\$${TARGET}*.pdb) $$quote($$DSTDIR)\\plugins $$escape_expand(\\n)
-1
View File
@@ -99,7 +99,6 @@ QList<MOBase::PluginSetting> PythonPluginWrapper::settings() const
try {
boost::python::object l = m_SettingsFunction();
if (!l.is_none()) {
// boost::python::list l = extract<boost::python::list>(temp);
for (int i = 0; i < boost::python::len(l); ++i) {
result.append(extract<MOBase::PluginSetting>(l[i]));
}
+1
View File
@@ -27,6 +27,7 @@ public:
virtual QList<MOBase::PluginSetting> settings() const;
protected:
void reportPythonError() const;
private:
File diff suppressed because it is too large Load Diff
+9 -1
View File
@@ -15,7 +15,15 @@ public:
virtual bool isPythonVersionSupported() const = 0;
};
extern "C" QDLLEXPORT IPythonRunner *CreatePythonRunner(const MOBase::IOrganizer *moInfo, const QString &pythonDir);
#ifdef PYTHONRUNNER_LIBRARY
#define PYDLLEXPORT Q_DECL_EXPORT
#else // PYTHONRUNNER_LIBRARY
#define PYDLLEXPORT Q_DECL_IMPORT
#endif // PYTHONRUNNER_LIBRARY
extern "C" PYDLLEXPORT IPythonRunner *CreatePythonRunner(MOBase::IOrganizer *moInfo, const QString &pythonDir);
#endif // PYTHONRUNNER_H
-12
View File
@@ -1,12 +0,0 @@
#ifndef PYTHONRUNNER_GLOBAL_H
#define PYTHONRUNNER_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(PYTHONRUNNER_LIBRARY)
# define PYTHONRUNNERSHARED_EXPORT Q_DECL_EXPORT
#else
# define PYTHONRUNNERSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // PYTHONRUNNER_GLOBAL_H
+163 -23
View File
@@ -3,7 +3,9 @@
#ifndef Q_MOC_RUN
#pragma warning (push, 0)
#include <boost/python.hpp>
#pragma warning (pop)
#endif
#include <QString>
@@ -11,6 +13,8 @@
#include <imoinfo.h>
#include <igameinfo.h>
#include <imodrepositorybridge.h>
#include <imodinterface.h>
#include <iinstallationmanager.h>
#include "error.h"
#include "gilock.h"
@@ -51,8 +55,6 @@ public:
{ m_Wrapped->requestFiles(modID, userData); }
void requestFileInfo(int modID, int fileID, QVariant userData)
{ m_Wrapped->requestFileInfo(modID, fileID, userData); }
void requestDownloadURL(int modID, int fileID, QVariant userData)
{ m_Wrapped->requestDownloadURL(modID, fileID, userData); }
void requestToggleEndorsement(int modID, bool endorse, QVariant userData)
{ m_Wrapped->requestToggleEndorsement(modID, endorse, userData); }
@@ -63,10 +65,31 @@ public:
Qt::UniqueConnection);
}
void onDescriptionAvailable(boost::python::object callback) {
m_DescriptionAvailableHandler = callback;
connect(m_Wrapped, SIGNAL(descriptionAvailable(int,QVariant,QVariant)),
this, SLOT(descriptionAvailable(int,QVariant,QVariant)),
Qt::UniqueConnection);
}
void onFileInfoAvailable(boost::python::object callback) {
m_FileInfoHandler = callback;
connect(m_Wrapped, SIGNAL(fileInfoAvailable(int,int,QVariant,QVariant)),
this, SLOT(fileInfoAvailable(int,int,QVariant,QVariant)),
Qt::UniqueConnection);
}
void onEndorsementToggled(boost::python::object callback) {
m_EndorsementToggledHandler = callback;
connect(m_Wrapped, SIGNAL(endorsementToggled(int,QVariant,QVariant)),
this, SLOT(endorsementToggled(int,QVariant,QVariant)),
Qt::UniqueConnection);
}
void onRequestFailed(boost::python::object callback) {
m_FailedHandler = callback;
connect(m_Wrapped, SIGNAL(requestFailed(int,QVariant,QString)),
this, SLOT(requestFailed(int,QVariant,QString)),
connect(m_Wrapped, SIGNAL(requestFailed(int,int,QVariant,QString)),
this, SLOT(requestFailed(int,int,QVariant,QString)),
Qt::UniqueConnection);
}
@@ -82,20 +105,78 @@ private slots:
qCritical("no handler connected");
return;
}
// try {
try {
GILock lock;
m_FilesAvailableHandler(modID, userData, resultData);
// } catch (const boost::python::error_already_set&) {
// qDebug("error");
//reportPythonError();
// }
} catch (const boost::python::error_already_set&) {
reportPythonError();
}
}
void requestFailed(int modID, QVariant userData, const QString &errorMessage)
void descriptionAvailable(int modID, QVariant userData, const QVariant resultData)
{
try {
if (m_DescriptionAvailableHandler.is_none()) {
qCritical("no handler connected");
return;
}
try {
GILock lock;
m_DescriptionAvailableHandler(modID, userData, resultData);
} catch (const boost::python::error_already_set&) {
reportPythonError();
}
} catch (const std::exception &e) {
qCritical("failed to report event: %s", e.what());
} catch (...) {
qCritical("failed to report event");
}
}
void fileInfoAvailable(int modID, int fileID, QVariant userData, const QVariant resultData) {
try {
if (m_FileInfoHandler.is_none()) {
qCritical("no handler connected");
return;
}
try {
GILock lock;
m_FileInfoHandler(modID, fileID, userData, resultData);
} catch (const boost::python::error_already_set&) {
reportPythonError();
}
} catch (const std::exception &e) {
qCritical("failed to report event: %s", e.what());
} catch (...) {
qCritical("failed to report event");
}
}
void endorsementToggled(int modID, QVariant userData, const QVariant resultData)
{
try {
if (m_EndorsementToggledHandler.is_none()) {
qCritical("no handler connected");
return;
}
try {
GILock lock;
m_EndorsementToggledHandler(modID, userData, resultData);
} catch (const boost::python::error_already_set&) {
reportPythonError();
}
} catch (const std::exception &e) {
qCritical("failed to report event: %s", e.what());
} catch (...) {
qCritical("failed to report event");
}
}
void requestFailed(int modID, int fileID, QVariant userData, const QString &errorMessage)
{
try {
GILock lock;
m_FailedHandler(modID, userData, errorMessage);
m_FailedHandler(modID, fileID, userData, errorMessage);
} catch (const boost::python::error_already_set&) {
reportPythonError();
}
@@ -105,38 +186,48 @@ private:
MOBase::IModRepositoryBridge *m_Wrapped;
boost::python::object m_FilesAvailableHandler;
boost::python::object m_DescriptionAvailableHandler;
boost::python::object m_FileInfoHandler;
boost::python::object m_EndorsementToggledHandler;
boost::python::object m_FailedHandler;
};
struct IOrganizerWrapper: MOBase::IOrganizer, boost::python::wrapper<MOBase::IOrganizer>
{
virtual MOBase::IGameInfo &gameInfo() const {
MOBase::IGameInfo *result = this->get_override("gameInfo")();
return *result;
}
virtual MOBase::IModRepositoryBridge *createNexusBridge() const {
return this->get_override("createNexusBridge")();
}
/*
static ModRepositoryBridgeWrapper newNexusBridge(IOrganizerWrapper *self) {
return ModRepositoryBridgeWrapper(self->createNexusBridge());
}*/
virtual MOBase::IModRepositoryBridge *createNexusBridge() const { return this->get_override("createNexusBridge")(); }
virtual QString profileName() const { return this->get_override("profileName")(); }
virtual QString profilePath() const { return this->get_override("profilePath")(); }
virtual QString downloadsPath() const { return this->get_override("downloadsPath")(); }
virtual QString overwritePath() const { return this->get_override("overwritePath")(); }
virtual MOBase::VersionInfo appVersion() const { return this->get_override("appVersion")(); }
virtual MOBase::IModInterface *getMod(const QString &name) { return this->get_override("getMod")(name); }
virtual MOBase::IModInterface *createMod(MOBase::GuessedValue<QString> &name) { return this->get_override("createMod")(name); }
virtual bool removeMod(MOBase::IModInterface *mod) { return this->get_override("removeMod")(mod); }
virtual void modDataChanged(MOBase::IModInterface *mod) { this->get_override("modDataChanged")(mod); }
virtual QVariant pluginSetting(const QString &pluginName, const QString &key) const { return this->get_override("pluginSetting")(pluginName, key); }
virtual void setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value) { this->get_override("setPluginSetting")(pluginName, key, value); }
virtual QVariant persistent(const QString &pluginName, const QString &key, const QVariant &def = QVariant()) const { return this->get_override("persistent")(pluginName, key, def); }
virtual void setPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync = true) { this->get_override("setPersistent")(pluginName, key, value, sync); }
virtual QString pluginDataPath() const { return this->get_override("pluginDataPath")(); }
virtual void installMod(const QString &fileName) { this->get_override("installMod")(fileName); }
virtual MOBase::IModInterface *installMod(const QString &fileName) { return this->get_override("installMod")(fileName); }
virtual MOBase::IDownloadManager *downloadManager() { return this->get_override("downloadManager")(); }
virtual MOBase::IPluginList *pluginList() { return this->get_override("pluginList")(); }
virtual MOBase::IModList *modList() { return this->get_override("modList")(); }
virtual QString resolvePath(const QString &fileName) const { return this->get_override("resolvePath")(fileName); }
virtual QStringList listDirectories(const QString &directoryName) const { return this->get_override("listDirectories")(directoryName); }
virtual QStringList findFiles(const QString &path, const std::function<bool(const QString&)> &filter) const { return this->get_override("findFiles")(path, filter); }
virtual QStringList getFileOrigins(const QString &fileName) const { return this->get_override("getFileOrigin")(fileName); }
virtual QList<FileInfo> findFileInfos(const QString &path, const std::function<bool(const FileInfo&)> &filter) const { return this->get_override("findFileInfos")(path, filter); }
virtual HANDLE startApplication(const QString &executable, const QStringList &args = QStringList(), const QString &cwd = "", const QString &profile = "") { return this->get_override("startApplication")(executable, args, cwd, profile); }
virtual bool waitForApplication(HANDLE handle, LPDWORD exitCode = NULL) const { return this->get_override("waitForApplication")(handle, exitCode); }
virtual void refreshModList(bool saveChanges = true) { this->get_override("refreshModList")(saveChanges); }
virtual bool onAboutToRun(const std::function<bool(const QString&)> &func) { return this->get_override("onAboutToRun")(func); }
virtual bool onModInstalled(const std::function<void(const QString&)> &func) { return this->get_override("onModInstalled")(func); }
};
struct IDownloadManagerWrapper: MOBase::IDownloadManager, boost::python::wrapper<MOBase::IDownloadManager>
@@ -144,8 +235,22 @@ struct IDownloadManagerWrapper: MOBase::IDownloadManager, boost::python::wrapper
virtual int startDownloadURLs(const QStringList &urls) { return this->get_override("downloadURLs")(urls); }
virtual int startDownloadNexusFile(int modID, int fileID) { return this->get_override("downloadNexusFile")(modID, fileID); }
virtual QString downloadPath(int id) { return this->get_override("downloadPath")(id); }
private:
boost::python::object m_DownloadCompleteHandler;
};
struct IModRepositoryBridgeWrapper: MOBase::IModRepositoryBridge, boost::python::wrapper<MOBase::IModRepositoryBridge>
{
virtual void requestDescription(int modID, QVariant userData) { this->get_override("requestDescription")(modID, userData); }
virtual void requestFiles(int modID, QVariant userData) { this->get_override("requestFiles")(modID, userData); }
virtual void requestFileInfo(int modID, int fileID, QVariant userData) { this->get_override("requestFileInfo")(modID, fileID, userData); }
virtual void requestDownloadURL(int modID, int fileID, QVariant userData) { this->get_override("requestDownloadURL")(modID, fileID, userData); }
virtual void requestToggleEndorsement(int modID, bool endorse, QVariant userData) { this->get_override("requestToggleEndorsement")(modID, endorse, userData); }
};
struct IInstallationManagerWrapper: MOBase::IInstallationManager, boost::python::wrapper<MOBase::IInstallationManager>
{
virtual QString extractFile(const QString &fileName) { return this->get_override("extractFile")(fileName); }
virtual QStringList extractFiles(const QStringList &files, bool flatten) { return this->get_override("extractFiles")(files, flatten); }
virtual MOBase::IPluginInstaller::EInstallResult installArchive(MOBase::GuessedValue<QString> &modName, const QString &archiveFile) { return this->get_override("installArchive")(modName, archiveFile); }
};
struct IGameInfoWrapper: MOBase::IGameInfo, boost::python::wrapper<MOBase::IGameInfo>
@@ -155,5 +260,40 @@ struct IGameInfoWrapper: MOBase::IGameInfo, boost::python::wrapper<MOBase::IGame
virtual QString binaryName() const { return this->get_override("binaryName")(); }
};
struct IModInterfaceWrapper: MOBase::IModInterface, boost::python::wrapper<MOBase::IModInterface>
{
virtual QString name() const { return this->get_override("name")(); }
virtual QString absolutePath() const { return this->get_override("absolutePath")(); }
virtual void setVersion(const MOBase::VersionInfo &version) { this->get_override("setVersion")(version); }
virtual void setNewestVersion(const MOBase::VersionInfo &version) { this->get_override("setNewestVersion")(version); }
virtual void setIsEndorsed(bool endorsed) { this->get_override("setIsEndorsed")(endorsed); }
virtual void setNexusID(int nexusID) { this->get_override("setNexusID")(nexusID); }
virtual void setInstallationFile(const QString &fileName) { this->get_override("setInstallationFile")(fileName); }
virtual void addNexusCategory(int categoryID) { this->get_override("addNexusCategory")(categoryID); }
virtual bool setName(const QString &name) { return this->get_override("setName")(name); }
virtual bool remove() { return this->get_override("remove")(); }
};
struct IPluginListWrapper: MOBase::IPluginList, boost::python::wrapper<MOBase::IPluginList> {
virtual PluginState state(const QString &name) const { return this->get_override("state")(name); }
virtual int priority(const QString &name) const { return this->get_override("priority")(name); }
virtual int loadOrder(const QString &name) const { return this->get_override("loadOrder")(name); }
virtual bool isMaster(const QString &name) const { return this->get_override("isMaster")(name); }
virtual QStringList masters(const QString &name) const { return this->get_override("masters")(name); }
virtual QString origin(const QString &name) const { return this->get_override("origin")(name); }
virtual bool onRefreshed(const std::function<void ()> &callback) { return this->get_override("onRefreshed")(callback); }
virtual bool onPluginMoved(const std::function<void (const QString &, int, int)> &callback) { return this->get_override("onPluginMoved")(callback); }
};
struct IModListWrapper: MOBase::IModList, boost::python::wrapper<MOBase::IModList> {
virtual QString displayName(const QString &internalName) const { return this->get_override("displayName")(internalName); }
virtual ModStates state(const QString &name) const { return this->get_override("state")(name); }
virtual int priority(const QString &name) const { return this->get_override("priority")(name); }
virtual bool setPriority(const QString &name, int newPriority) { return this->get_override("setPriority")(name, newPriority); }
virtual bool onModStateChanged(const std::function<void (const QString &, ModStates)> &func) { return this->get_override("onModStateChanged")(func); }
virtual bool onModMoved(const std::function<void (const QString &, int, int)> &func) { return this->get_override("onModMoved")(func); }
};
#endif // UIBASEWRAPPERS_H