Merge pull request #923 from andreasb242/scripting

Scripting
presentation
andreasb242 7 years ago committed by GitHub
commit a071b52ca6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      CMakeLists.txt
  2. 2
      debian/control
  3. 4
      readme/LinuxBuild.md
  4. 7
      src/control/Control.cpp
  5. 52
      src/control/settings/Settings.cpp
  6. 15
      src/control/settings/Settings.h
  7. 5
      src/enums/ActionType.enum.h
  8. 10
      src/enums/generated/ActionType.generated.cpp
  9. 6
      src/gui/dialog/ButtonConfigGui.cpp
  10. 2
      src/gui/dialog/ButtonConfigGui.h
  11. 69
      src/gui/dialog/PluginDialog.cpp
  12. 39
      src/gui/dialog/PluginDialog.h
  13. 73
      src/gui/dialog/PluginDialogEntry.cpp
  14. 40
      src/gui/dialog/PluginDialogEntry.h
  15. 3
      src/gui/dialog/SettingsDialog.cpp
  16. 65
      src/plugin/Plugin.cpp
  17. 45
      src/plugin/Plugin.h
  18. 39
      src/plugin/PluginController.cpp
  19. 10
      src/plugin/PluginController.h
  20. 3
      src/util/XournalTypeList.h
  21. 1
      ui/main.glade
  22. 137
      ui/plugin.glade
  23. 155
      ui/pluginEntry.glade

@ -121,9 +121,7 @@ pkg_check_modules (Lua "lua5.3")
if (Lua_FOUND)
message("Enable Xournal++ Plugins")
add_includes_ldflags ("${Lua_LDFLAGS}" "${Lua_INCLUDE_DIRS}")
## Plugins are not yet ready - therefore disabled at the moment
# set (ENABLE_PLUGINS "true")
set (ENABLE_PLUGINS "true")
endif ()
configure_file (
@ -207,6 +205,10 @@ install (DIRECTORY ui
DESTINATION "share/xournalpp"
COMPONENT xournalpp
)
install (DIRECTORY plugins
DESTINATION "share/xournalpp"
COMPONENT xournalpp
)
# Install desktop shortcuts for Linux
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")

2
debian/control vendored

@ -3,7 +3,7 @@ Maintainer: Andreas Butti <andreasbutti@gmail.com>
Section: misc
Priority: optional
Standards-Version: 3.9.2
Build-Depends: debhelper (>= 9), cmake, git, libgtk-3-dev, libpoppler-glib-dev, libxml2-dev, portaudio19-dev, libsndfile-dev
Build-Depends: debhelper (>= 9), cmake, git, libgtk-3-dev, libpoppler-glib-dev, libxml2-dev, portaudio19-dev, libsndfile-dev, liblua5.3-dev
Homepage: https://github.com/xournalpp/xournalpp/
Package: xournalpp

@ -4,6 +4,8 @@
Please create pull requests (or file issues) if you have more precise dependencies.
Lua is needed for plugins, if it is missing, the plugins will be disabled.
### For Fedora/CentOS/RHEL:
```bash
sudo dnf install cmake gtk3-devel libxml2-devel cppunit-devel portaudio-devel libsndfile-devel \
@ -13,7 +15,7 @@ poppler-glib-devel texlive-scheme-basic texlive-dvipng 'tex(standalone.cls)' get
### For Ubuntu/Debian:
````bash
sudo apt-get install cmake libgtk-3-dev libpoppler-glib-dev portaudio19-dev libsndfile-dev \
libcppunit-dev dvipng texlive libxml2-dev
libcppunit-dev dvipng texlive libxml2-dev liblua5.3-dev
````
### For OpenSuse:

@ -997,6 +997,13 @@ void Control::actionPerformed(ActionType type, ActionGroup group, GdkEvent* even
// nothing to do here
break;
// Plugin menu
case ACTION_PLUGIN_MANAGER:
this->pluginController->showPluginManager();
break;
// Menu Help
case ACTION_HELP:
XojMsgBox::showHelp(getGtkWindow());

@ -131,6 +131,9 @@ void Settings::loadDefault()
this->audioOutputDevice = -1;
this->audioGain = 1.0;
this->pluginEnabled = "";
this->pluginDisabled = "";
inTransaction = false;
}
@ -392,6 +395,14 @@ void Settings::parseItem(xmlDocPtr doc, xmlNodePtr cur)
{
this->defaultSaveName = (const char*) value;
}
else if (xmlStrcmp(name, (const xmlChar*) "pluginEnabled") == 0)
{
this->pluginEnabled = (const char*) value;
}
else if (xmlStrcmp(name, (const xmlChar*) "pluginDisabled") == 0)
{
this->pluginDisabled = (const char*) value;
}
else if (xmlStrcmp(name, (const xmlChar*) "pageTemplate") == 0)
{
this->pageTemplate = (const char*) value;
@ -858,6 +869,9 @@ void Settings::save()
WRITE_DOUBLE_PROP(audioSampleRate);
WRITE_DOUBLE_PROP(audioGain);
WRITE_STRING_PROP(pluginEnabled);
WRITE_STRING_PROP(pluginDisabled);
xmlNodePtr xmlFont;
xmlFont = xmlNewChild(root, NULL, (const xmlChar*) "property", NULL);
xmlSetProp(xmlFont, (const xmlChar*) "name", (const xmlChar*) "font");
@ -2035,6 +2049,44 @@ void Settings::setAudioGain(double gain)
save();
}
string Settings::getPluginEnabled()
{
XOJ_CHECK_TYPE(Settings);
return this->pluginEnabled;
}
void Settings::setPluginEnabled(string pluginEnabled)
{
XOJ_CHECK_TYPE(Settings);
if (this->pluginEnabled == pluginEnabled)
{
return;
}
this->pluginEnabled = pluginEnabled;
save();
}
string Settings::getPluginDisabled()
{
XOJ_CHECK_TYPE(Settings);
return this->pluginDisabled;
}
void Settings::setPluginDisabled(string pluginEnabled)
{
XOJ_CHECK_TYPE(Settings);
if (this->pluginDisabled == pluginDisabled)
{
return;
}
this->pluginDisabled = pluginDisabled;
save();
}
//////////////////////////////////////////////////
SAttribute::SAttribute()

@ -329,6 +329,12 @@ public:
double getAudioGain();
void setAudioGain(double gain);
string getPluginEnabled();
void setPluginEnabled(string pluginEnabled);
string getPluginDisabled();
void setPluginDisabled(string pluginEnabled);
/**
* Get name, e.g. "cm"
*/
@ -676,6 +682,15 @@ private:
*/
double audioGain;
/**
* List of enabled plugins (only the one which are not enabled by default)
*/
string pluginEnabled;
/**
* List of disabled plugins (only the one which are not disabled by default)
*/
string pluginDisabled;
/**
* "Transaction" running, do not save until the end is reached

@ -183,9 +183,8 @@ enum ActionType
ACTION_SET_LAYOUT_T2B,
ACTION_SET_LAYOUT_B2T,
// Plugin Menu
ACTION_PLUGIN_MANAGER = 700,
// Menu Help
ACTION_ABOUT = 800,

@ -652,6 +652,11 @@ ActionType ActionType_fromString(string value)
return ACTION_SET_LAYOUT_B2T;
}
if (value == "ACTION_PLUGIN_MANAGER")
{
return ACTION_PLUGIN_MANAGER;
}
if (value == "ACTION_ABOUT")
{
return ACTION_ABOUT;
@ -1325,6 +1330,11 @@ string ActionType_toString(ActionType value)
return "ACTION_SET_LAYOUT_B2T";
}
if (value == ACTION_PLUGIN_MANAGER)
{
return "ACTION_PLUGIN_MANAGER";
}
if (value == ACTION_ABOUT)
{
return "ACTION_ABOUT";

@ -22,7 +22,7 @@ void addToolToList(GtkListStore* typeModel, const char* icon, const char* name,
gtk_list_store_set(typeModel, &iter, 1, name, 2, action, -1);
}
ButtonConfigGui::ButtonConfigGui(SettingsDialog* dlg, GladeSearchpath* gladeSearchPath, GtkWidget* w, Settings* settings, int button, bool withDevice)
ButtonConfigGui::ButtonConfigGui(GladeSearchpath* gladeSearchPath, GtkWidget* w, Settings* settings, int button, bool withDevice)
: GladeGui(gladeSearchPath, "settingsButtonConfig.glade", "offscreenwindow")
{
XOJ_INIT_TYPE(ButtonConfigGui);
@ -208,8 +208,6 @@ void ButtonConfigGui::loadSettings()
gtk_combo_box_set_active(GTK_COMBO_BOX(cbDevice), 0);
int i = 0;
for (InputDevice& dev : this->deviceList->getDeviceList())
{
if (cfg->device == dev.getName())
@ -225,9 +223,9 @@ void ButtonConfigGui::loadSettings()
}
}
// Not implemented! This is not a dialog!
void ButtonConfigGui::show(GtkWindow* parent)
{
// Not implemented! This is not a dialog!
}
void ButtonConfigGui::saveSettings()

@ -23,7 +23,7 @@ class SettingsDialog;
class ButtonConfigGui : public GladeGui
{
public:
ButtonConfigGui(SettingsDialog* dlg, GladeSearchpath* gladeSearchPath, GtkWidget* w, Settings* settings, int button, bool withDevice);
ButtonConfigGui(GladeSearchpath* gladeSearchPath, GtkWidget* w, Settings* settings, int button, bool withDevice);
virtual ~ButtonConfigGui();
public:

@ -0,0 +1,69 @@
#include "PluginDialog.h"
#include "PluginDialogEntry.h"
#include "control/settings/Settings.h"
#include "plugin/PluginController.h"
PluginDialog::PluginDialog(GladeSearchpath* gladeSearchPath, Settings* settings)
: GladeGui(gladeSearchPath, "plugin.glade", "pluginDialog"),
settings(settings)
{
XOJ_INIT_TYPE(PluginDialog);
}
PluginDialog::~PluginDialog()
{
XOJ_CHECK_TYPE(PluginDialog);
for (PluginDialogEntry* p : this->plugins)
{
delete p;
}
this->plugins.clear();
XOJ_RELEASE_TYPE(PluginDialog);
}
void PluginDialog::loadPluginList(PluginController* pc)
{
XOJ_CHECK_TYPE(PluginDialog);
GtkWidget* pluginBox = get("pluginBox");
for (Plugin* p : pc->getPlugins())
{
this->plugins.push_back(new PluginDialogEntry(p, getGladeSearchPath(), pluginBox));
}
}
void PluginDialog::saveSettings()
{
XOJ_CHECK_TYPE(PluginDialog);
string pluginEnabled;
string pluginDisabled;
// Save plugin settings
for (PluginDialogEntry* bcg : this->plugins)
{
bcg->saveSettings(pluginEnabled, pluginDisabled);
}
settings->setPluginEnabled(pluginEnabled);
settings->setPluginDisabled(pluginDisabled);
}
void PluginDialog::show(GtkWindow* parent)
{
XOJ_CHECK_TYPE(PluginDialog);
gtk_window_set_transient_for(GTK_WINDOW(this->window), parent);
int returnCode = gtk_dialog_run(GTK_DIALOG(this->window));
gtk_widget_hide(this->window);
if (returnCode == 2)
{
saveSettings();
}
}

@ -0,0 +1,39 @@
/*
* Xournal++
*
* Plugin manage dialog
*
* @author Xournal++ Team
* https://github.com/xournalpp/xournalpp
*
* @license GNU GPLv2 or later
*/
#pragma once
#include "gui/GladeGui.h"
class PluginController;
class PluginDialogEntry;
class Settings;
class PluginDialog : public GladeGui
{
public:
PluginDialog(GladeSearchpath* gladeSearchPath, Settings* settings);
virtual ~PluginDialog();
public:
void loadPluginList(PluginController* pc);
virtual void show(GtkWindow* parent);
private:
void saveSettings();
private:
XOJ_TYPE_ATTRIB;
Settings* settings;
vector<PluginDialogEntry*> plugins;
};

@ -0,0 +1,73 @@
#include "PluginDialogEntry.h"
#include "plugin/Plugin.h"
#include <i18n.h>
PluginDialogEntry::PluginDialogEntry(Plugin* plugin, GladeSearchpath* gladeSearchPath, GtkWidget* w)
: GladeGui(gladeSearchPath, "pluginEntry.glade", "offscreenwindow"),
plugin(plugin)
{
XOJ_INIT_TYPE(PluginDialogEntry);
GtkWidget* pluginMainBox = get("pluginMainBox");
gtk_container_remove(GTK_CONTAINER(getWindow()), pluginMainBox);
gtk_container_add(GTK_CONTAINER(w), pluginMainBox);
gtk_widget_show_all(pluginMainBox);
loadSettings();
}
PluginDialogEntry::~PluginDialogEntry()
{
XOJ_CHECK_TYPE(PluginDialogEntry);
XOJ_RELEASE_TYPE(PluginDialogEntry);
}
void PluginDialogEntry::loadSettings()
{
XOJ_CHECK_TYPE(PluginDialogEntry);
gtk_label_set_text(GTK_LABEL(get("pluginName")), plugin->getName().c_str());
gtk_label_set_text(GTK_LABEL(get("lbAuthor")), plugin->getAuthor().c_str());
gtk_label_set_text(GTK_LABEL(get("lbVersion")), plugin->getVersion().c_str());
gtk_label_set_text(GTK_LABEL(get("lbDefaultText")), plugin->isDefaultEnabled() ? _("default enabled") : _("default disabled"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(get("cbEnabled")), plugin->isEnabled());
}
void PluginDialogEntry::show(GtkWindow* parent)
{
// Not implemented! This is not a dialog!
}
void PluginDialogEntry::saveSettings(string& pluginEnabled, string& pluginDisabled)
{
XOJ_CHECK_TYPE(PluginDialogEntry);
bool state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(get("cbEnabled")));
if (state == plugin->isDefaultEnabled())
{
return;
}
if (state)
{
if (!pluginEnabled.empty())
{
pluginEnabled += ",";
}
pluginEnabled += plugin->getName();
}
else
{
if (!pluginDisabled.empty())
{
pluginDisabled += ",";
}
pluginDisabled += plugin->getName();
}
}

@ -0,0 +1,40 @@
/*
* Xournal++
*
* Configuration of a single plugin
*
* @author Xournal++ Team
* https://github.com/xournalpp/xournalpp
*
* @license GNU GPLv2 or later
*/
#pragma once
#include "gui/GladeGui.h"
class Settings;
class Plugin;
class PluginDialog;
class PluginDialogEntry : public GladeGui
{
public:
PluginDialogEntry(Plugin* plugin, GladeSearchpath* gladeSearchPath, GtkWidget* w);
virtual ~PluginDialogEntry();
public:
void loadSettings();
void saveSettings(string& pluginEnabled, string& pluginDisabled);
// Not implemented! This is not a dialog!
virtual void show(GtkWindow* parent);
private:
XOJ_TYPE_ATTRIB;
/**
* Plugin instance
*/
Plugin* plugin;
};

@ -65,6 +65,7 @@ SettingsDialog::~SettingsDialog()
{
delete bcg;
}
this->buttonConfigs.clear();
// DO NOT delete settings!
this->settings = NULL;
@ -76,7 +77,7 @@ void SettingsDialog::initMouseButtonEvents(const char* hbox, int button, bool wi
{
XOJ_CHECK_TYPE(SettingsDialog);
this->buttonConfigs.push_back(new ButtonConfigGui(this, getGladeSearchPath(), get(hbox), settings, button, withDevice));
this->buttonConfigs.push_back(new ButtonConfigGui(getGladeSearchPath(), get(hbox), settings, button, withDevice));
}
void SettingsDialog::initMouseButtonEvents()

@ -39,7 +39,6 @@ Plugin::Plugin(Control* control, string name, string path)
XOJ_INIT_TYPE(Plugin);
loadIni();
loadScript();
}
Plugin::~Plugin()
@ -89,7 +88,7 @@ void Plugin::registerToolbar()
{
XOJ_CHECK_TYPE(Plugin);
if (!this->valid)
if (!this->valid || !this->enabled)
{
return;
}
@ -124,7 +123,7 @@ void Plugin::registerMenu(GtkWindow* mainWindow, GtkWidget* menu)
{
XOJ_CHECK_TYPE(Plugin);
if (menuEntries.empty())
if (menuEntries.empty() || !this->enabled)
{
// No entries - nothing to do
return;
@ -180,6 +179,54 @@ string Plugin::getName()
return name;
}
/**
* Author of the plugin
*/
string Plugin::getAuthor()
{
XOJ_CHECK_TYPE(Plugin);
return author;
}
/**
* Plugin version
*/
string Plugin::getVersion()
{
XOJ_CHECK_TYPE(Plugin);
return version;
}
/**
* The plugin is enabled
*/
bool Plugin::isEnabled()
{
XOJ_CHECK_TYPE(Plugin);
return enabled;
}
/**
* The plugin is enabled
*/
void Plugin::setEnabled(bool enabled)
{
this->enabled = enabled;
}
/**
* The plugin is default enabled
*/
bool Plugin::isDefaultEnabled()
{
XOJ_CHECK_TYPE(Plugin);
return defaultEnabled;
}
/**
* @return Flag to check if init ui is currently running
*/
@ -243,6 +290,12 @@ void Plugin::loadIni()
LOAD_FROM_INI(mainfile, "plugin", "mainfile");
string defaultEnabledStr;
LOAD_FROM_INI(defaultEnabledStr, "default", "enabled");
defaultEnabled = defaultEnabledStr == "true";
enabled = defaultEnabled;
g_key_file_free(config);
this->valid = true;
@ -313,6 +366,12 @@ void Plugin::loadScript()
return;
}
if (!this->enabled)
{
return;
}
// Create Lua state variable
lua = luaL_newstate();

@ -75,6 +75,11 @@ public:
virtual ~Plugin();
public:
/**
* Load the plugin script
*/
void loadScript();
/**
* Check if this plugin is valid
*/
@ -100,6 +105,31 @@ public:
*/
string getName();
/**
* Author of the plugin
*/
string getAuthor();
/**
* Plugin version
*/
string getVersion();
/**
* The plugin is enabled
*/
bool isEnabled();
/**
* The plugin is enabled
*/
void setEnabled(bool enabled);
/**
* The plugin is default enabled
*/
bool isDefaultEnabled();
/**
* @return Flag to check if init ui is currently running
*/
@ -123,11 +153,6 @@ private:
*/
void loadIni();
/**
* Load the plugin script
*/
void loadScript();
/**
* Execute lua function
*/
@ -177,6 +202,16 @@ private:
*/
string mainfile;
/**
* The plugin is enabled
*/
bool enabled = false;
/**
* The plugin is default enabled
*/
bool defaultEnabled = false;
/**
* Lua engine
*/

@ -2,12 +2,15 @@
#include "Plugin.h"
#include "control/Control.h"
#include "gui/dialog/PluginDialog.h"
#include "gui/GladeSearchpath.h"
#include <StringUtils.h>
#include <config-features.h>
#include <algorithm>
PluginController::PluginController(Control* control)
: control(control)
@ -62,6 +65,10 @@ void PluginController::loadPluginsFrom(string path)
return;
}
Settings* settings = control->getSettings();
vector<string> pluginEnabled = StringUtils::split(settings->getPluginEnabled(), ',');
vector<string> pluginDisabled = StringUtils::split(settings->getPluginDisabled(), ',');
const gchar* file;
while ((file = g_dir_read_name(dir)) != NULL)
{
@ -77,6 +84,17 @@ void PluginController::loadPluginsFrom(string path)
continue;
}
if (p->isDefaultEnabled())
{
p->setEnabled(!(std::find(pluginDisabled.begin(), pluginDisabled.end(), p->getName()) != pluginDisabled.end()));
}
else
{
p->setEnabled(std::find(pluginEnabled.begin(), pluginEnabled.end(), p->getName()) != pluginEnabled.end());
}
p->loadScript();
this->plugins.push_back(p);
}
g_dir_close(dir);
@ -98,6 +116,18 @@ void PluginController::registerToolbar()
#endif
}
/**
* Show Plugin manager Dialog
*/
void PluginController::showPluginManager()
{
XOJ_CHECK_TYPE(PluginController);
PluginDialog dlg(control->getGladeSearchPath(), control->getSettings());
dlg.loadPluginList(this);
dlg.show(control->getGtkWindow());
}
/**
* Register menu stuff
*/
@ -121,4 +151,13 @@ void PluginController::registerMenu()
#endif
}
/**
* Return the plugin list
*/
vector<Plugin*>& PluginController::getPlugins()
{
XOJ_CHECK_TYPE(PluginController);
return plugins;
}

@ -35,11 +35,21 @@ public:
*/
void registerToolbar();
/**
* Show Plugin manager Dialog
*/
void showPluginManager();
/**
* Register menu stuff
*/
void registerMenu();
/**
* Return the plugin list
*/
vector<Plugin*>& getPlugins();
private:
XOJ_TYPE_ATTRIB;

@ -283,6 +283,9 @@ XOJ_DECLARE_TYPE(LayoutMapper, 273);
XOJ_DECLARE_TYPE(PluginController, 274);
XOJ_DECLARE_TYPE(Plugin, 275);
XOJ_DECLARE_TYPE(MenuEntry, 276);
XOJ_DECLARE_TYPE(PluginDialog, 277);
XOJ_DECLARE_TYPE(PluginDialogEntry, 278);

@ -1568,6 +1568,7 @@
<property name="can_focus">False</property>
<property name="label" translatable="yes">Plugin _Manager</property>
<property name="use_underline">True</property>
<signal name="activate" handler="ACTION_PLUGIN_MANAGER" swapped="no"/>
</object>
</child>
</object>

@ -0,0 +1,137 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.0"/>
<object class="GtkAdjustment" id="adjustment1">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">1</property>
</object>
<object class="GtkDialog" id="pluginDialog">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Plugin Manager</property>
<property name="modal">True</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">dialog</property>
<child>
<placeholder/>
</child>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button1">
<property name="label">gtk-close</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button2">
<property name="label">gtk-ok</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<accelerator key="Return" signal="activate"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<property name="min_content_height">300</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="pluginBox">
<property name="name">pluginBox</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Plugin changes are only applied after Xournal++ restart</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="1">button1</action-widget>
<action-widget response="2">button2</action-widget>
</action-widgets>
</object>
</interface>

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkOffscreenWindow" id="offscreenwindow">
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkBox" id="pluginMainBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="pluginName">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">pluginName</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Author: </property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="lbAuthor">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Author</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Version: </property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="lbVersion">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">1.2.3</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<child>
<object class="GtkCheckButton" id="cbEnabled">
<property name="label" translatable="yes">enabled,</property>
<property name="name">cbEnabled</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="lbDefaultText">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">default enabled / disabled</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkSeparator">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
Loading…
Cancel
Save