Skip to content

Commit

Permalink
New dev module system (#5690)
Browse files Browse the repository at this point in the history
* initial functional draft

* add ugly name thing for now
  • Loading branch information
RensDofferhoff authored Oct 9, 2024
1 parent d96a35d commit 2145695
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 28 deletions.
3 changes: 1 addition & 2 deletions Desktop/analysis/analyses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,7 @@ void Analyses::removeAnalysesOfDynamicModule(Modules::DynamicModule * module)

void Analyses::refreshAnalysesOfDynamicModule(Modules::DynamicModule * module)
{
//Log::log() << "void Analyses::refreshAnalysesOfDynamicModule(" << module->toString() << ")" << std::endl;

Log::log() << "void Analyses::refreshAnalysesOfDynamicModule(" << module->toString() << ")" << std::endl;

for(auto & keyval : _analysisMap)
if(keyval.second->dynamicModule() == module)
Expand Down
104 changes: 99 additions & 5 deletions Desktop/components/JASP/Widgets/FileMenu/PrefsAdvanced.qml
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,6 @@ ScrollView
KeyNavigation.tab: githubPatCustomToken
}




Item
{
id: githubPatCustomTokenItem
Expand Down Expand Up @@ -170,7 +167,7 @@ ScrollView
text: preferencesModel.githubPatCustom
onEditingFinished: preferencesModel.githubPatCustom = text

nextEl: generateMarkdown
nextEl: directLibpathDevModEnabled

height: browseDeveloperFolderButton.height
anchors
Expand All @@ -182,7 +179,7 @@ ScrollView

textInput.echoMode: TextInput.Password

KeyNavigation.tab: generateMarkdown
KeyNavigation.tab: directLibpathDevModEnabled
}
}

Expand All @@ -197,6 +194,103 @@ ScrollView
KeyNavigation.tab: cleanModulesFolder

}


CheckBox
{
id: directLibpathDevModEnabled
label: qsTr("Enable direct libpath mode")
checked: preferencesModel.directLibpathEnabled
onCheckedChanged: preferencesModel.directLibpathEnabled = checked
toolTip: qsTr("To use JASP Modules enable this option.")
visible: preferencesModel.developerMode

KeyNavigation.tab: directLibpathFolder
}

Item
{
id: directLibpath
enabled: preferencesModel.directLibpathEnabled
width: parent.width
height: cranRepoUrl.height
visible: preferencesModel.developerMode && preferencesModel.directLibpathEnabled

Label
{
id: directLibPathLabel
text: qsTr("DevModule libpath:")

anchors
{
left: parent.left
verticalCenter: parent.verticalCenter
leftMargin: jaspTheme.subOptionOffset
}
}

PrefsTextInput
{
id: directLibpathFolder

text: preferencesModel.directLibpathFolder
onEditingFinished: preferencesModel.directLibpathFolder = text

nextEl: moduleName

height: browseDeveloperFolderButton.height
anchors
{
left: directLibPathLabel.right
right: parent.right
margins: jaspTheme.generalAnchorMargin
}

KeyNavigation.tab: moduleName
}
}

Item {

id: directDevMod
enabled: preferencesModel.directLibpathEnabled
width: parent.width
height: cranRepoUrl.height
visible: preferencesModel.developerMode && preferencesModel.directLibpathEnabled

Label
{
id: directDevModName
text: qsTr("Developer module name:")

anchors
{
left: parent.left
verticalCenter: parent.verticalCenter
leftMargin: jaspTheme.subOptionOffset
}
}

PrefsTextInput
{
id: moduleName

text: preferencesModel.directDevModName
onEditingFinished: preferencesModel.directDevModName = text

nextEl: cleanModulesFolder

height: browseDeveloperFolderButton.height
anchors
{
left: directDevModName.right
right: parent.right
margins: jaspTheme.generalAnchorMargin
}

KeyNavigation.tab: cleanModulesFolder
}
}

RoundedButton
{
Expand Down
2 changes: 1 addition & 1 deletion Desktop/components/JASP/Widgets/ModulesMenu.qml
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ FocusScope
focus: currentIndex === -1
activeFocusOnTab: false

readonly property bool folderSelected: preferencesModel.developerFolder != ""
readonly property bool folderSelected: preferencesModel.developerFolder != "" || (preferencesModel.directLibpathEnabled && preferencesModel.directLibpathFolder != "")
}

QTC.ToolSeparator
Expand Down
16 changes: 16 additions & 0 deletions Desktop/gui/preferencesmodel.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ GET_PREF_FUNC_BOOL( checkUpdates, Settings::CHECK_UPDATES )
GET_PREF_FUNC_INT( maxScaleLevels, Settings::MAX_SCALE_LEVELS )
GET_PREF_FUNC_BOOL( pdfLandscape, Settings::PDF_LANDSCAPE )
GET_PREF_FUNC_INT( pdfPageSize, Settings::PDF_PAGESIZE )
GET_PREF_FUNC_BOOL( directLibpathEnabled, Settings::DIRECT_LIBPATH_ENABLED )
GET_PREF_FUNC_STR( directLibpathFolder, Settings::DIRECT_LIBPATH_FOLDER )
GET_PREF_FUNC_STR( directDevModName, Settings::DIRECT_DEVMOD_NAME )


int PreferencesModel::maxEngines() const
{
Expand Down Expand Up @@ -314,6 +318,9 @@ SET_PREF_FUNCTION( bool, setCheckUpdates, checkUpdates, checkUpdatesCha
SET_PREF_FUNCTION( int, setMaxScaleLevels, maxScaleLevels, maxScaleLevelsChanged, Settings::MAX_SCALE_LEVELS )
SET_PREF_FUNCTION( bool, setPdfLandscape, pdfLandscape, pdfLandscapeChanged, Settings::PDF_LANDSCAPE )
SET_PREF_FUNCTION( int, setPdfPageSize, pdfPageSize, pdfPageSizeChanged, Settings::PDF_PAGESIZE )
SET_PREF_FUNCTION( bool, setDirectLibpathEnabled, directLibpathEnabled, directLibpathEnabledChanged, Settings::DIRECT_LIBPATH_ENABLED )
SET_PREF_FUNCTION( QString, setDirectDevModName, directDevModName, directDevModNameChanged, Settings::DIRECT_DEVMOD_NAME )


void PreferencesModel::setGithubPatCustom(QString newPat)
{
Expand Down Expand Up @@ -551,3 +558,12 @@ QStringList PreferencesModel::_splitValues(const QString &values) const
return QStringList(orderedValues.begin(), orderedValues.end());

}

void PreferencesModel::setDirectLibpathFolder(QString libpath)
{
if (libpath != "")
{
Settings::setValue(Settings::DIRECT_LIBPATH_FOLDER, libpath);
emit directLibpathFolderChanged();
}
}
14 changes: 13 additions & 1 deletion Desktop/gui/preferencesmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ class PreferencesModel : public PreferencesModelBase
Q_PROPERTY(int defaultPPI READ defaultPPI WRITE setDefaultPPI NOTIFY defaultPPIChanged )
Q_PROPERTY(bool developerMode READ developerMode WRITE setDeveloperMode NOTIFY developerModeChanged )
Q_PROPERTY(QString developerFolder READ developerFolder WRITE setDeveloperFolder NOTIFY developerFolderChanged )
Q_PROPERTY(bool directLibpathEnabled READ directLibpathEnabled WRITE setDirectLibpathEnabled NOTIFY directLibpathEnabledChanged )
Q_PROPERTY(QString directLibpathFolder READ directLibpathFolder WRITE setDirectLibpathFolder NOTIFY directLibpathFolderChanged )
Q_PROPERTY(QString directDevModName READ directDevModName WRITE setDirectDevModName NOTIFY directDevModNameChanged )
Q_PROPERTY(int thresholdScale READ thresholdScale WRITE setThresholdScale NOTIFY thresholdScaleChanged )
Q_PROPERTY(bool logToFile READ logToFile WRITE setLogToFile NOTIFY logToFileChanged )
Q_PROPERTY(int logFilesMax READ logFilesMax WRITE setLogFilesMax NOTIFY logFilesMaxChanged )
Expand Down Expand Up @@ -146,7 +149,10 @@ class PreferencesModel : public PreferencesModelBase
QVariantList pdfPageSizeModel() const { return _pdfPageSizeModel; }
int pdfPageSize() const;
bool pdfLandscape() const;

bool directLibpathEnabled() const;
QString directLibpathFolder() const;
QString directDevModName() const;

bool checkUpdatesAskUser() const;
void setCheckUpdatesAskUser(bool newCheckUpdatesAskUser);

Expand Down Expand Up @@ -213,6 +219,9 @@ public slots:
void setMaxScaleLevels( int maxScaleLevels);
void setPdfPageSize( int pdfPageSize);
void setPdfLandscape( bool pdfLandscape);
void setDirectLibpathEnabled( bool setDirectLibpathEnabled);
void setDirectLibpathFolder( QString libpath);
void setDirectDevModName( QString name);

signals:
void fixedDecimalsChanged( bool fixedDecimals);
Expand Down Expand Up @@ -268,6 +277,9 @@ public slots:
void maxScaleLevelsChanged( int maxScaleLevels);
void pdfPageSizeChanged( int pdfPageSize);
void pdfLandscapeChanged( bool pdfLandscape);
void directLibpathEnabledChanged( bool directLibpathEnabled);
void directLibpathFolderChanged();
void directDevModNameChanged( QString name);

private slots:
void dataLabelNAChangedSlot(QString label);
Expand Down
21 changes: 19 additions & 2 deletions Desktop/modules/dynamicmodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,24 @@ DynamicModule::DynamicModule(QObject * parent) : QObject(parent), _isDeveloperMo
}


///This constructor is meant specifically for the development module from a libpath *it*!
DynamicModule::DynamicModule(QObject * parent, QString libpath) : QObject(parent), _isDeveloperMod(true), _isLibpathDevMod(true)
{
_modulePackage = fq(libpath + "/" + Settings::value(Settings::DIRECT_DEVMOD_NAME).toString() + "/");
_moduleFolder = QFileInfo(libpath + "/");
_name = extractPackageNameFromFolder(_modulePackage);

if(_name == "") _name = defaultDevelopmentModuleName();

Log::log() << "Development Module is constructed with name: '" << _name << "' and will intialized from libpath: " << _moduleFolder.absoluteFilePath().toStdString() << std::endl;

_developmentModuleName = _name;

loadDescriptionFromFolder(_modulePackage);
setInstalled(true);
}


void DynamicModule::initialize()
{

Expand All @@ -112,7 +130,6 @@ void DynamicModule::initialize()
// else if(!_moduleFolder.isWritable()) throw std::runtime_error(_moduleFolder.absolutePath().toStdString() + " is not writable!");

setInitialized(true);

auto checkForExistence = [&](std::string name, bool isFile = false)
{
QString modPath = _moduleFolder.absolutePath() + "/" + nameQ() + "/" + QString::fromStdString(name);
Expand Down Expand Up @@ -499,7 +516,7 @@ std::string DynamicModule::generateModuleUninstallingR()
std::string DynamicModule::moduleInstFolder() const
{
//Because in a developer mod everything is loaded directly from the source folder we give an actual inst folder:
if(_isDeveloperMod) return _modulePackage + "/inst";
if(_isDeveloperMod && !_isLibpathDevMod) return _modulePackage + "/inst";
//But after install this is in a R-library and therefore there is no more inst folder:
else return moduleRLibrary().toStdString() + "/" + _name + "/";
}
Expand Down
6 changes: 6 additions & 0 deletions Desktop/modules/dynamicmodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ class DynamicModule : public QObject
///This constructor is meant specifically for the development module and only *it*!
explicit DynamicModule(QObject * parent);

///This constructor is meant specifically for development modules initialized form a libpaths
explicit DynamicModule(QObject *parent, QString libpath);


~DynamicModule() override
{
for(auto * entry : _menuEntries)
Expand Down Expand Up @@ -165,6 +169,7 @@ class DynamicModule : public QObject
bool installing() const { return _installing; }
bool initialized() const { return _initialized; }
bool isBundled() const { return _bundled; }
bool isLibpathDevMod() const { return _isLibpathDevMod; }

void initialize();
void loadDescriptionQml(const QString & descriptionTxt, const QUrl & url);
Expand Down Expand Up @@ -242,6 +247,7 @@ public slots:
bool _installing = false,
_installed = false,
_isDeveloperMod = false,
_isLibpathDevMod = false,
_initialized = false,
_bundled = false,
_isCommon = false,
Expand Down
39 changes: 24 additions & 15 deletions Desktop/modules/dynamicmodules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ void DynamicModules::uninstallModule(const std::string & moduleName)
unloadModule(moduleName);
_modules[moduleName]->setInstalled(false);

if(_modules[moduleName]->isBundled())
if(_modules[moduleName]->isBundled() || _modules[moduleName]->isLibpathDevMod())
removeFolder = false;

for(int i=int(_moduleNames.size()) - 1; i>=0; i--)
Expand Down Expand Up @@ -530,27 +530,24 @@ void DynamicModules::uninstallJASPDeveloperModule()

void DynamicModules::installJASPDeveloperModule()
{
if(Settings::value(Settings::DEVELOPER_FOLDER).toString() == "")
bool directLibpathEnabled = PreferencesModel::prefs()->directLibpathEnabled();
QString modulePath = directLibpathEnabled ? PreferencesModel::prefs()->directLibpathFolder() : Settings::value(Settings::DEVELOPER_FOLDER).toString();
if(modulePath == "")
{
MessageForwarder::showWarning(tr("Select a folder"), tr("To install a development module you need to select the folder you want to watch and load, you can do this under the filemenu, Preferences->Advanced."));
return;
}
else if(!QDir(Settings::value(Settings::DEVELOPER_FOLDER).toString()).exists())
else if(!QDir(modulePath).exists())
{
MessageForwarder::showWarning(tr("Select an exisiting folder"), tr("To install a development module you need to select and existing folder, you selected '$1' but it doesn't exist.").arg(Settings::value(Settings::DEVELOPER_FOLDER).toString()));
MessageForwarder::showWarning(tr("Select an exisiting folder"), tr("To install a development module you need to select and existing folder, you selected '$1' but it doesn't exist.").arg(modulePath));
return;
}

setDevelopersModuleInstallButtonEnabled(false);

try
{

_devModSourceDirectory = QDir(Settings::value(Settings::DEVELOPER_FOLDER).toString());

DynamicModule * devMod = new DynamicModule(this);

devMod->loadDescriptionFromFolder(fq(_devModSourceDirectory.absolutePath()));
DynamicModule * devMod = directLibpathEnabled ? new DynamicModule(this, modulePath) : new DynamicModule(this);

std::string origin = devMod->modulePackage(),
name = devMod->name(),
Expand All @@ -563,11 +560,14 @@ void DynamicModules::installJASPDeveloperModule()
else if(_modules.count(name) > 0 && _modules[name] != devMod)
replaceModule(devMod);

DynamicModule::developmentModuleFolderCreate();

_modules[name] = devMod;

registerForInstalling(name);
if(directLibpathEnabled) {
initializeModule(devMod);
}
else {
DynamicModule::developmentModuleFolderCreate();
registerForInstalling(name);
}
}
catch(ModuleException & e)
{
Expand Down Expand Up @@ -603,8 +603,14 @@ void DynamicModules::startWatchingDevelopersModule()
if(dir == "icons") iconsFound = true;
}
}
else if(entry.isDir() && entry.fileName().toLower() == "qml")
qmlFound = true;
else if(entry.isDir() && entry.fileName().toLower() == "icons")
iconsFound = true;
else if(entry.isDir() && entry.fileName().toUpper() == "R")
rFound = true;
else if(entry.isFile() && DynamicModule::isDescriptionFile(entry.fileName()))
descFound = entry.fileName();

if(!(descFound != "" && rFound && qmlFound && iconsFound))
{
Expand Down Expand Up @@ -756,7 +762,10 @@ void DynamicModules::regenerateDeveloperModuleRPackage()
throw std::runtime_error("void DynamicModules::regenerateDeveloperModuleRPackage() called but the development module is not initialized...");

auto * devMod = _modules[developmentModuleName()];
devMod->setStatus(moduleStatus::installModPkgNeeded);
if(devMod->isLibpathDevMod())
emit dynamicModuleChanged(devMod);
else
devMod->setStatus(moduleStatus::installModPkgNeeded);
}

QString DynamicModules::moduleDirectoryQ(const QString & moduleName) const
Expand Down
5 changes: 4 additions & 1 deletion Desktop/utilities/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,10 @@ const Settings::Setting Settings::Values[] = {
{"checkUpdatesLastTime", -1 },
{"maxScaleLevels", 100 },
{"pdfLandscape", false },
{"pdfPageSize", int(pdfPageSize::A4) }
{"pdfPageSize", int(pdfPageSize::A4) },
{"directLibpathEnabled", false },
{"directLibpathFolder", "" },
{"directDevModName", "" }

};

Expand Down
Loading

0 comments on commit 2145695

Please sign in to comment.