#include "proxypluginwrappers.h" #include "gilock.h" #include #include #include "pythonwrapperutilities.h" #include "sipApiAccess.h" #include #include namespace boost { // See bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2852624 #if (_MSC_VER == 1900) template<> const volatile MOBase::IOrganizer* get_pointer(const volatile MOBase::IOrganizer* p) { return p; } template<> const volatile MOBase::IModInterface* get_pointer(const volatile MOBase::IModInterface* p) { return p; } template<> const volatile MOBase::IPluginGame* get_pointer(const volatile MOBase::IPluginGame* p) { return p; } template<> const volatile MOBase::IProfile* get_pointer(const volatile MOBase::IProfile* p) { return p; } template<> const volatile MOBase::IModList* get_pointer(const volatile MOBase::IModList* p) { return p; } template<> const volatile MOBase::IPluginList* get_pointer(const volatile MOBase::IPluginList* p) { return p; } template<> const volatile MOBase::IDownloadManager* get_pointer(const volatile MOBase::IDownloadManager* p) { return p; } template<> const volatile MOBase::IModRepositoryBridge* get_pointer(const volatile MOBase::IModRepositoryBridge* p) { return p; } #endif } using namespace MOBase; #define COMMON_I_PLUGIN_WRAPPER_DEFINITIONS(class_name) \ bool class_name::init(MOBase::IOrganizer *moInfo) \ { \ return basicWrapperFunctionImplementation(this, "init", boost::python::ptr(moInfo)); \ } \ \ QString class_name::name() const \ { \ return basicWrapperFunctionImplementation(this, "name"); \ } \ \ QString class_name::author() const \ { \ return basicWrapperFunctionImplementation(this, "author"); \ } \ \ QString class_name::description() const \ { \ return basicWrapperFunctionImplementation(this, "description"); \ } \ \ MOBase::VersionInfo class_name::version() const \ { \ return basicWrapperFunctionImplementation(this, "version"); \ } \ \ bool class_name::isActive() const \ { \ return basicWrapperFunctionImplementation(this, "isActive"); \ } \ \ QList class_name::settings() const \ { \ return basicWrapperFunctionImplementation>(this, "settings"); \ } /// end COMMON_I_PLUGIN_WRAPPER_DEFINITIONS ///////////////////////////// /// IPlugin Wrapper COMMON_I_PLUGIN_WRAPPER_DEFINITIONS(IPluginWrapper) /// end IPlugin Wrapper ///////////////////////////////////// /// IPluginDiagnose Wrapper COMMON_I_PLUGIN_WRAPPER_DEFINITIONS(IPluginDiagnoseWrapper) std::vector IPluginDiagnoseWrapper::activeProblems() const { return basicWrapperFunctionImplementation>(this, "activeProblems"); } QString IPluginDiagnoseWrapper::shortDescription(unsigned int key) const { return basicWrapperFunctionImplementation(this, "shortDescription", key); } QString IPluginDiagnoseWrapper::fullDescription(unsigned int key) const { return basicWrapperFunctionImplementation(this, "fullDescription", key); } bool IPluginDiagnoseWrapper::hasGuidedFix(unsigned int key) const { return basicWrapperFunctionImplementation(this, "hasGuidedFix", key); } void IPluginDiagnoseWrapper::startGuidedFix(unsigned int key) const { basicWrapperFunctionImplementation(this, "startGuidedFix", key); } /// end IPluginDiagnose Wrapper ///////////////////////////////////// /// IPluginFileMapper Wrapper COMMON_I_PLUGIN_WRAPPER_DEFINITIONS(IPluginFileMapperWrapper) MappingType IPluginFileMapperWrapper::mappings() const { return basicWrapperFunctionImplementation(this, "mappings"); } /// end IPluginFileMapper Wrapper ///////////////////////////////////// /// IPluginGame Wrapper QString IPluginGameWrapper::gameName() const { return basicWrapperFunctionImplementation(this, "gameName"); } void IPluginGameWrapper::initializeProfile(const QDir & directory, ProfileSettings settings) const { basicWrapperFunctionImplementation(this, "initializeProfile", directory, settings); } QString IPluginGameWrapper::savegameExtension() const { return basicWrapperFunctionImplementation(this, "savegameExtension"); } QString IPluginGameWrapper::savegameSEExtension() const { return basicWrapperFunctionImplementation(this, "savegameSEExtension"); } bool IPluginGameWrapper::isInstalled() const { return basicWrapperFunctionImplementation(this, "isInstalled"); } QIcon IPluginGameWrapper::gameIcon() const { return basicWrapperFunctionImplementation(this, "gameIcon"); } QDir IPluginGameWrapper::gameDirectory() const { return basicWrapperFunctionImplementation(this, "gameDirectory"); } QDir IPluginGameWrapper::dataDirectory() const { return basicWrapperFunctionImplementation(this, "dataDirectory"); } void IPluginGameWrapper::setGamePath(const QString & path) { basicWrapperFunctionImplementation(this, "setGamePath", path); } QDir IPluginGameWrapper::documentsDirectory() const { return basicWrapperFunctionImplementation(this, "documentsDirectory"); } QDir IPluginGameWrapper::savesDirectory() const { return basicWrapperFunctionImplementation(this, "savesDirectory"); } QList IPluginGameWrapper::executables() const { return basicWrapperFunctionImplementation>(this, "executables"); } QList IPluginGameWrapper::executableForcedLoads() const { return basicWrapperFunctionImplementation>(this, "executableForcedLoads"); } QString IPluginGameWrapper::steamAPPId() const { return basicWrapperFunctionImplementation(this, "steamAPPId"); } QStringList IPluginGameWrapper::primaryPlugins() const { return basicWrapperFunctionImplementation(this, "primaryPlugins"); } QStringList IPluginGameWrapper::gameVariants() const { return basicWrapperFunctionImplementation(this, "gameVariants"); } void IPluginGameWrapper::setGameVariant(const QString & variant) { basicWrapperFunctionImplementation(this, "setGameVariant", variant); } QString IPluginGameWrapper::binaryName() const { return basicWrapperFunctionImplementation(this, "binaryName"); } QString IPluginGameWrapper::gameShortName() const { return basicWrapperFunctionImplementation(this, "gameShortName"); } QStringList IPluginGameWrapper::primarySources() const { return basicWrapperFunctionImplementation(this, "primarySources"); } QStringList IPluginGameWrapper::validShortNames() const { return basicWrapperFunctionImplementation(this, "validShortNames"); } QString IPluginGameWrapper::gameNexusName() const { return basicWrapperFunctionImplementation(this, "gameNexusName"); } QStringList IPluginGameWrapper::iniFiles() const { return basicWrapperFunctionImplementation(this, "iniFiles"); } QStringList IPluginGameWrapper::DLCPlugins() const { return basicWrapperFunctionImplementation(this, "DLCPlugins"); } QStringList IPluginGameWrapper::CCPlugins() const { return basicWrapperFunctionImplementation(this, "CCPlugins"); } IPluginGame::LoadOrderMechanism IPluginGameWrapper::loadOrderMechanism() const { return basicWrapperFunctionImplementation(this, "loadOrderMechanism"); } IPluginGame::SortMechanism IPluginGameWrapper::sortMechanism() const { return basicWrapperFunctionImplementation(this, "sortMechanism"); } int IPluginGameWrapper::nexusModOrganizerID() const { return basicWrapperFunctionImplementation(this, "nexusModOrganizerID"); } int IPluginGameWrapper::nexusGameID() const { return basicWrapperFunctionImplementation(this, "nexusGameID"); } bool IPluginGameWrapper::looksValid(QDir const & dir) const { return basicWrapperFunctionImplementation(this, "looksValid", dir); } QString IPluginGameWrapper::gameVersion() const { return basicWrapperFunctionImplementation(this, "gameVersion"); } QString IPluginGameWrapper::getLauncherName() const { return basicWrapperFunctionImplementation(this, "getLauncherName"); } COMMON_I_PLUGIN_WRAPPER_DEFINITIONS(IPluginGameWrapper) std::map IPluginGameWrapper::featureList() const { return basicWrapperFunctionImplementation>(this, "_featureList"); } /// end IPluginGame Wrapper ///////////////////////////////////// /// IPluginInstaller macro #define COMMON_I_PLUGIN_INSTALLER_WRAPPER_DEFINITIONS(class_name) \ unsigned int class_name::priority() const { return basicWrapperFunctionImplementation(this, "priority"); } \ bool class_name::isManualInstaller() const { return basicWrapperFunctionImplementation(this, "isManualInstaller"); } \ bool class_name::isArchiveSupported(std::shared_ptr tree) const { return basicWrapperFunctionImplementation(this, "isArchiveSupported", tree); } /// end IPluginInstaller macro ///////////////////////////////////// /// IPluginInstaller Wrapper COMMON_I_PLUGIN_WRAPPER_DEFINITIONS(IPluginInstallerSimpleWrapper) COMMON_I_PLUGIN_INSTALLER_WRAPPER_DEFINITIONS(IPluginInstallerSimpleWrapper) IPluginInstaller::EInstallResult IPluginInstallerSimpleWrapper::install( GuessedValue& modName, std::shared_ptr& tree, QString& version, int& nexusID) { namespace bpy = boost::python; using return_type = std::variant< IPluginInstaller::EInstallResult, std::shared_ptr, std::tuple, QString, int>> ; auto ret = basicWrapperFunctionImplementation(this, "install", boost::ref(modName), tree, version, nexusID); return std::visit([&](auto const& t) { using type = std::decay_t; if constexpr (std::is_same_v) { return t; } else if constexpr (std::is_same_v>) { tree = t; return IPluginInstaller::RESULT_SUCCESS; } else if constexpr (std::is_same_v, QString, int>>) { tree = std::get<1>(t); version = std::get<2>(t); nexusID = std::get<3>(t); return std::get<0>(t); } }, ret); } /// end IPluginInstallerSimple Wrapper ///////////////////////////////////// /// IPluginInstallerCustom Wrapper COMMON_I_PLUGIN_WRAPPER_DEFINITIONS(IPluginInstallerCustomWrapper) COMMON_I_PLUGIN_INSTALLER_WRAPPER_DEFINITIONS(IPluginInstallerCustomWrapper) bool IPluginInstallerCustomWrapper::isArchiveSupported(const QString &archiveName) const { return basicWrapperFunctionImplementation(this, "isArchiveSupported", archiveName); } std::set IPluginInstallerCustomWrapper::supportedExtensions() const { return basicWrapperFunctionImplementation>(this, "supportedExtensions"); } IPluginInstaller::EInstallResult IPluginInstallerCustomWrapper::install( GuessedValue &modName, QString gameName, const QString &archiveName, const QString &version, int modID) { // Note: This requires far more less trouble than the "Simple" installer version since 1) there is no tree // and 2) there version and modId cannot be modified: return basicWrapperFunctionImplementation( this, "install", boost::ref(modName), gameName, archiveName, version, modID); } /// end IPluginInstallerCustom Wrapper ///////////////////////////// /// IPluginModPage Wrapper COMMON_I_PLUGIN_WRAPPER_DEFINITIONS(IPluginModPageWrapper) QString IPluginModPageWrapper::displayName() const { return basicWrapperFunctionImplementation(this, "displayName"); } QIcon IPluginModPageWrapper::icon() const { return basicWrapperFunctionImplementation(this, "icon"); } QUrl IPluginModPageWrapper::pageURL() const { return basicWrapperFunctionImplementation(this, "pageURL"); } bool IPluginModPageWrapper::useIntegratedBrowser() const { return basicWrapperFunctionImplementation(this, "useIntegratedBrowser"); } bool IPluginModPageWrapper::handlesDownload(const QUrl & pageURL, const QUrl & downloadURL, MOBase::ModRepositoryFileInfo & fileInfo) const { return basicWrapperFunctionImplementation(this, "handlesDownload", pageURL, downloadURL, fileInfo); } void IPluginModPageWrapper::setParentWidget(QWidget * widget) { basicWrapperFunctionImplementationWithDefault(this, &IPluginModPageWrapper::setParentWidget_Default, "setParentWidget", widget); } /// end IPluginModPage Wrapper ///////////////////////////// /// IPluginPreview Wrapper COMMON_I_PLUGIN_WRAPPER_DEFINITIONS(IPluginPreviewWrapper) std::set IPluginPreviewWrapper::supportedExtensions() const { return basicWrapperFunctionImplementation>(this, "supportedExtensions"); } QWidget *IPluginPreviewWrapper::genFilePreview(const QString &fileName, const QSize &maxSize) const { // This is complicated, so we can't use the basic implementation try { GILock lock; boost::python::override implementation = this->get_override("genFilePreview"); if (!implementation) throw pyexcept::MissingImplementation(this->className, "genFilePreview"); boost::python::object pyVersion = implementation(fileName, maxSize); // We need responsibility for deleting the QWidget to be transferred to C++ sipAPIAccess::sipAPI()->api_transfer_to(pyVersion.ptr(), Py_None); return boost::python::extract(pyVersion)(); } catch (const boost::python::error_already_set&) { throw pyexcept::PythonError(); } catch (pyexcept::MissingImplementation const& missingImplementation) { throw missingImplementation; } catch (...) { throw pyexcept::UnknownException(); } } /// end IPluginPreview Wrapper ///////////////////////////// /// IPluginTool Wrapper COMMON_I_PLUGIN_WRAPPER_DEFINITIONS(IPluginToolWrapper) QString IPluginToolWrapper::displayName() const { return basicWrapperFunctionImplementation(this, "displayName"); } QString IPluginToolWrapper::tooltip() const { return basicWrapperFunctionImplementation(this, "tooltip"); } QIcon IPluginToolWrapper::icon() const { return basicWrapperFunctionImplementation(this, "icon"); } void IPluginToolWrapper::setParentWidget(QWidget *parent) { basicWrapperFunctionImplementationWithDefault(this, &IPluginToolWrapper::setParentWidget_Default, "setParentWidget", parent); } void IPluginToolWrapper::display() const { basicWrapperFunctionImplementation(this, "display"); } /// end IPluginTool Wrapper