Commit 7902174f authored by Boudewijn Rempt's avatar Boudewijn Rempt

Fix loading script actions

And make it possible for script actions to now show up in the
menu.
parent 0c3b6da3
......@@ -28,7 +28,6 @@ Action::Action(QObject *parent)
, d(new Private)
{
d->action = new KisAction(this);
d->action->setProperty("menu", "tools/scripts");
connect(d->action, SIGNAL(triggered(bool)), SIGNAL(triggered(bool)));
}
......@@ -38,7 +37,6 @@ Action::Action(const QString &name, QAction *action, QObject *parent)
{
d->action = action;
d->action->setObjectName(name);
d->action->setProperty("menu", "tools/scripts");
connect(d->action, SIGNAL(triggered(bool)), SIGNAL(triggered(bool)));
}
......@@ -122,18 +120,13 @@ void Action::setShortcut(QString value)
bool Action::isVisible() const
{
if (!d->action) return false;
return d->action->property("menu").toString() == "tools/scripts";
return d->action->isVisible();
}
void Action::setVisible(bool value)
{
if (!d->action) return;
if (value) {
d->action->setProperty("menu", "tools/scripts");
}
else {
d->action->setProperty("menu", "");
}
d->action->setVisible(value);
}
bool Action::isEnabled() const
......@@ -158,3 +151,14 @@ void Action::trigger()
{
d->action->trigger();
}
void Action::setMenu(const QString menu)
{
d->action->setProperty("menu", menu);
}
QString Action::menu() const
{
return d->action->property("menu").toString();
}
......@@ -45,7 +45,7 @@ public:
*/
Action(const QString &name, QAction *action, QObject *parent = 0);
~Action() override;
bool operator==(const Action &other) const;
bool operator!=(const Action &other) const;
......@@ -131,6 +131,18 @@ public Q_SLOTS:
*/
void trigger();
/**
* @brief setMenu determines in which menu the action will be placed. The default is tools/scripts
* @param menu the menu where the action should go, / -separated to drill down the hierarchy
*/
void setMenu(const QString menu);
/**
* @return the menu in which this action is to be placed.
*/
QString menu() const;
Q_SIGNALS:
/**
......
......@@ -50,6 +50,7 @@
#include <brushengine/kis_paintop_preset.h>
#include <kis_brush_server.h>
#include <KoResourceServerProvider.h>
#include <kis_action_registry.h>
#include "View.h"
#include "Document.h"
......@@ -314,9 +315,19 @@ Window* Krita::openWindow()
}
Action *Krita::createAction(const QString &text)
Action *Krita::createAction(const QString &id, const QString &text)
{
KisAction *action = new KisAction(text, this);
action->setObjectName(id);
KisActionRegistry *actionRegistry = KisActionRegistry::instance();
actionRegistry->propertizeAction(action->objectName(), action);
bool ok; // We will skip this check
int activationFlags = actionRegistry->getActionProperty(id, "activationFlags").toInt(&ok, 2);
int activationConditions = actionRegistry->getActionProperty(id, "activationConditions").toInt(&ok, 2);
action->setActivationFlags((KisAction::ActivationFlags) activationFlags);
action->setActivationConditions((KisAction::ActivationConditions) activationConditions);
KisPart::instance()->addScriptAction(action);
return new Action(action->objectName(), action);
}
......
......@@ -236,11 +236,13 @@ public Q_SLOTS:
/**
* @brief createAction creates an action with the given text and passes it to Krita. Every newly created
* mainwindow will create an instance of this action.
* mainwindow will create an instance of this action. This means that actions need to be created in the
* setup phase of the plugin, not on the fly.
* @param id the unique id for this action
* @param text the user-visible text
* @return the Action you can connect a slot to.
*/
Action *createAction(const QString &text);
Action *createAction(const QString &name, const QString &text);
/**
* @brief addExtension add the given plugin to Krita. There will be a single instance of each Extension in the Krita process.
......
......@@ -208,7 +208,7 @@ void KisPart::removeDocument(KisDocument *document)
KisMainWindow *KisPart::createMainWindow()
{
KisMainWindow *mw = new KisMainWindow();
Q_FOREACH(QAction *action, d->scriptActions) {
Q_FOREACH(KisAction *action, d->scriptActions) {
mw->viewManager()->scriptManager()->addAction(action);
}
dbgUI <<"mainWindow" << (void*)mw << "added to view" << this;
......
......@@ -78,16 +78,11 @@ public:
*/
KisAction *actionByName(const QString &name) const;
void registerOperationUIFactory(KisOperationUIFactory* factory);
void registerOperation(KisOperation* operation);
void runOperation(const QString &id);
void runOperationFromConfiguration(KisOperationConfigurationSP config);
/**
* Update actions handled by kis_action_manager to set enabled.
* This is used to grey out buttons that can't be pressed.
......
......@@ -46,8 +46,6 @@ void KisCategorizedItemDelegate::paint(QPainter* painter, const QStyleOptionView
if(!index.data(__CategorizedListModelBase::IsHeaderRole).toBool()) {
QStyleOptionViewItem sovi(option);
if (index.data(__CategorizedListModelBase::isLockableRole).toBool()) {
const int iconSize = qMax(16, m_minimumItemHeight - 2);
......
......@@ -41,6 +41,9 @@ KisPaletteView::KisPaletteView(QWidget *parent)
verticalHeader()->setVisible(false);
setItemDelegate(new KisPaletteDelegate());
setDragEnabled(true);
setDragDropMode(QAbstractItemView::InternalMove);
KisConfig cfg;
QPalette pal(palette());
pal.setColor(QPalette::Base, cfg.getMDIBackgroundColor());
......
......@@ -20,10 +20,13 @@
#include <QMenu>
#include <KisPart.h>
#include <kactionmenu.h>
#include <klocalizedstring.h>
#include <kactionmenu.h>
#include <kactioncollection.h>
#include <kis_action.h>
#include <kis_action_manager.h>
#include "KisViewManager.h"
......@@ -32,15 +35,16 @@ struct KisScriptManager::Private {
Private()
: actionCollection(0)
, actionManager(0)
, view(0)
, viewManager(0)
, scriptMenu(0)
{
}
KActionCollection *actionCollection;
KisActionManager *actionManager;
KisViewManager *view;
KisViewManager *viewManager;
KActionMenu *scriptMenu;
KActionMenu *hiddenMenu;
};
......@@ -48,7 +52,7 @@ KisScriptManager::KisScriptManager(KisViewManager *view)
: QObject(view)
, d(new Private())
{
d->view = view;
d->viewManager = view;
}
KisScriptManager::~KisScriptManager()
......@@ -62,19 +66,25 @@ void KisScriptManager::setup(KActionCollection * ac, KisActionManager *actionMan
d->actionCollection = ac;
d->actionManager = actionManager;
d->scriptMenu = new KActionMenu(i18n("Scripts"),this);
d->scriptMenu = new KActionMenu(i18n("Scripts"), this);
d->actionCollection->addAction("scripts", d->scriptMenu);
d->hiddenMenu = new KActionMenu("hidden", this);
}
void KisScriptManager::updateGUI()
{
if (!d->view) return;
if (!d->viewManager) return;
}
void KisScriptManager::addAction(QAction *action)
void KisScriptManager::addAction(KisAction *action)
{
Q_ASSERT(d->actionCollection);
if (action->property("menu").toString().toLower() == "tools/scripts") {
d->actionManager->addAction(action->objectName(), action);
if (action->property("menu").toString() != "None") {
// XXX: find the right menu and add it there.
d->scriptMenu->addAction(action);
}
else {
d->hiddenMenu->addAction(action);
action->setShortcutContext(Qt::ApplicationShortcut);
}
}
......@@ -23,7 +23,7 @@
#include <kritaui_export.h>
class QAction;
class KisAction;
class KisActionManager;
class KisViewManager;
......@@ -42,7 +42,7 @@ public:
void setup(KActionCollection * ac, KisActionManager *actionManager);
void updateGUI();
void addAction(QAction *action);
void addAction(KisAction *action);
private:
struct Private;
......
......@@ -140,7 +140,6 @@ KisActionRegistry *KisActionRegistry::instance()
KisActionRegistry::KisActionRegistry()
: d(new KisActionRegistry::Private(this))
{
d->loadActionFiles();
KConfigGroup cg = KSharedConfig::openConfig()->group("Shortcut Schemes");
QString schemeName = cg.readEntry("Current Scheme", "Default");
loadShortcutScheme(schemeName);
......@@ -226,7 +225,6 @@ void KisActionRegistry::applyShortcutScheme(const KConfigBase *config)
void KisActionRegistry::updateShortcut(const QString &name, QAction *action)
{
const ActionInfoItem &info = d->actionInfo(name);
action->setShortcuts(info.effectiveShortcuts());
action->setProperty("defaultShortcuts", qVariantFromValue(info.defaultShortcuts()));
......@@ -246,7 +244,7 @@ QList<QString> KisActionRegistry::registeredShortcutIds() const
bool KisActionRegistry::propertizeAction(const QString &name, QAction * a)
{
if (!d->actionInfoList.contains(name)) {
dbgAction << "No XML data found for action" << name;
qDebug() << "No XML data found for action" << name;
return false;
}
......@@ -302,7 +300,6 @@ void KisActionRegistry::Private::loadActionFiles()
QStringList actionDefinitions =
KoResourcePaths::findAllResources("kis_actions", "*.action", KoResourcePaths::Recursive);
// Extract actions all XML .action files.
Q_FOREACH (const QString &actionDefinition, actionDefinitions) {
QDomDocument doc;
......@@ -342,7 +339,7 @@ void KisActionRegistry::Private::loadActionFiles()
}
else if (actionInfoList.contains(name)) {
// errAction << "NOT COOL: Duplicated action name from xml data: " << name;
errAction << "NOT COOL: Duplicated action name from xml data: " << name;
}
else {
......@@ -358,7 +355,6 @@ void KisActionRegistry::Private::loadActionFiles()
info.categoryName = categoryName;
info.collectionName = collectionName;
// dbgAction << "default shortcut for" << name << " - " << info.defaultShortcut;
actionInfoList.insert(name,info);
}
}
......
......@@ -77,6 +77,10 @@ install_pykrita_plugin(assignprofiledialog)
install_pykrita_plugin(scripter)
#install_pykrita_plugin(highpass)
install_pykrita_plugin(tenbrushes)
install( FILES
tenbrushes/tenbrushes.action
DESTINATION ${DATA_INSTALL_DIR}/krita/actions)
install_pykrita_plugin(palette_docker)
# if(PYTHON_VERSION_MAJOR VERSION_EQUAL 3)
......
......@@ -38,7 +38,7 @@ class AssignProfileDialog(Extension):
doc.setColorProfile(self.cmbProfile.currentText())
def setup(self):
action = Application.createAction("Assign Profile to Image")
action = Application.createAction("assing_profile_to_image", "Assign Profile to Image")
action.triggered.connect(self.assignProfile)
Scripter.addExtension(AssignProfileDialog(Application))
......@@ -13,7 +13,7 @@ class HelloExtension(Extension):
def setup(self):
qDebug("Hello Setup")
action = Krita.instance().createAction("hello")
action = Krita.instance().createAction("hello_python", "hello")
action.triggered.connect(hello)
Scripter.addExtension(HelloExtension(Krita.instance()))
......
......@@ -9,7 +9,7 @@ class HighpassExtension(Extension):
super().__init__(parent)
def setup(self):
action = Application.createAction("High Pass")
action = Application.createAction("high_pass_filter", "High Pass")
action.triggered.connect(self.showDialog)
def showDialog(self):
......
......@@ -10,7 +10,7 @@ class ScripterExtension(Extension):
super().__init__(parent)
def setup(self):
action = Krita.instance().createAction("Scripter")
action = Krita.instance().createAction("python_scripter", "Scripter")
action.triggered.connect(self.initialize)
def initialize(self):
......
<?xml version="1.0" encoding="UTF-8"?>
<ActionCollection version="2" name="Scripts">
<Actions category="Scripts">
<text>Ten Brushes</text>
<Action name="activate_preset_1">
<icon></icon>
<text>Activate Brush Preset 1</text>
<whatsThis></whatsThis>
<toolTip></toolTip>
<iconText></iconText>
<activationFlags>10000</activationFlags>
<activationConditions>0</activationConditions>
<shortcut>ctrl+alt+1</shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
<Action name="activate_preset_2">
<icon></icon>
<text>Activate Brush Preset 2</text>
<whatsThis></whatsThis>
<toolTip></toolTip>
<iconText></iconText>
<activationFlags>10000</activationFlags>
<activationConditions>0</activationConditions>
<shortcut>ctrl+alt+2</shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
<Action name="activate_preset_3">
<icon></icon>
<text>Activate Brush Preset 3</text>
<whatsThis></whatsThis>
<toolTip></toolTip>
<iconText></iconText>
<activationFlags>10000</activationFlags>
<activationConditions>0</activationConditions>
<shortcut>ctrl+alt+3</shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
<Action name="activate_preset_4">
<icon></icon>
<text>Activate Brush Preset 4</text>
<whatsThis></whatsThis>
<toolTip></toolTip>
<iconText></iconText>
<activationFlags>10000</activationFlags>
<activationConditions>0</activationConditions>
<shortcut>ctrl+alt+4</shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
<Action name="activate_preset_5">
<icon></icon>
<text>Activate Brush Preset 5</text>
<whatsThis></whatsThis>
<toolTip></toolTip>
<iconText></iconText>
<activationFlags>10000</activationFlags>
<activationConditions>0</activationConditions>
<shortcut>ctrl+alt+5</shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
<Action name="activate_preset_6">
<icon></icon>
<text>Activate Brush Preset 6</text>
<whatsThis></whatsThis>
<toolTip></toolTip>
<iconText></iconText>
<activationFlags>10000</activationFlags>
<activationConditions>0</activationConditions>
<shortcut>ctrl+alt+6</shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
<Action name="activate_preset_7">
<icon></icon>
<text>Activate Brush Preset 7</text>
<whatsThis></whatsThis>
<toolTip></toolTip>
<iconText></iconText>
<activationFlags>10000</activationFlags>
<activationConditions>0</activationConditions>
<shortcut>ctrl+alt+7</shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
<Action name="activate_preset_8">
<icon></icon>
<text>Activate Brush Preset 8</text>
<whatsThis></whatsThis>
<toolTip></toolTip>
<iconText></iconText>
<activationFlags>10000</activationFlags>
<activationConditions>0</activationConditions>
<shortcut>ctrl+alt+8</shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
<Action name="activate_preset_9">
<icon></icon>
<text>Activate Brush Preset</text>
<whatsThis></whatsThis>
<toolTip></toolTip>
<iconText></iconText>
<activationFlags>10000</activationFlags>
<activationConditions>0</activationConditions>
<shortcut>ctrl+alt+9</shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
<Action name="activate_preset_0">
<icon></icon>
<text>Activate Brush Preset 10</text>
<whatsThis></whatsThis>
<toolTip></toolTip>
<iconText></iconText>
<activationFlags>10000</activationFlags>
<activationConditions>0</activationConditions>
<shortcut>ctrl+alt+0</shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
</Actions>
</ActionCollection>
......@@ -10,11 +10,11 @@ class DropButton(QPushButton):
self.setFixedSize(64, 64)
self.setIconSize(QSize(64, 64))
self.preset = None
def selectPreset(self):
self.preset = self.presetChooser.currentPreset().name()
self.setIcon(QIcon(QPixmap.fromImage(self.presetChooser.currentPreset().image())))
class TenBrushesExtension(Extension):
......@@ -22,12 +22,12 @@ class TenBrushesExtension(Extension):
super().__init__(parent)
self.buttons = []
self.actions = []
def setup(self):
action = Application.createAction("Ten Brushes")
action = Application.createAction("ten_brushes", "Ten Brushes")
action.setToolTip("Assign ten brush presets to ten shortcuts.")
action.triggered.connect(self.showDialog)
# Read the ten selected brush presets from the settings
selectedPresets = Application.readSetting("", "tenbrushes", "").split(',')
allPresets = Application.resources("preset")
......@@ -35,9 +35,9 @@ class TenBrushesExtension(Extension):
j = 0
self.actions = []
for i in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']:
action = Application.createAction("Activate Preset " + i)
action.setVisible(False)
action.setShortcut("CTRL+" + i)
action = Application.createAction("activate_preset_" + i, "Activate Preset " + i)
#action.setVisible(False)
action.setMenu("None")
action.triggered.connect(self.activatePreset)
if j < len(selectedPresets) and selectedPresets[j] in allPresets:
action.preset = selectedPresets[j]
......@@ -46,59 +46,60 @@ class TenBrushesExtension(Extension):
self.actions.append(action)
j = j + 1
def activatePreset(self):
print("activatePreset", self.sender().preset)
allPresets = Application.resources("preset")
if Application.activeWindow() and len(Application.activeWindow().views()) > 0 and self.sender().preset in allPresets:
Application.activeWindow().views()[0].activateResource(allPresets[self.sender().preset])
def showDialog(self):
self.dialog = QDialog(Application.activeWindow().qwindow())
self.buttonBox = QDialogButtonBox(self.dialog)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.dialog.reject)
vbox = QVBoxLayout(self.dialog)
hbox = QHBoxLayout(self.dialog)
self.presetChooser = PresetChooser(self.dialog)
allPresets = Application.resources("preset")
j = 0
self.buttons = []
self.buttons = []
for i in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']:
buttonBox = QVBoxLayout()
button = DropButton(self.dialog)
button.setObjectName(i)
button.clicked.connect(button.selectPreset)
button.presetChooser = self.presetChooser
if self.actions[j] and self.actions[j].preset and self.actions[j].preset in allPresets:
p = allPresets[self.actions[j].preset];
button.preset = p.name()
button.setIcon(QIcon(QPixmap.fromImage(p.image())))
buttonBox.addWidget(button)
label = QLabel("Ctrl+" + i)
label = QLabel("Ctrl+Alt+" + i)
label.setAlignment(Qt.AlignHCenter)
buttonBox.addWidget(label)
hbox.addLayout(buttonBox)
self.buttons.append(button)
j = j + 1
vbox.addLayout(hbox)
vbox.addWidget(self.presetChooser)
vbox.addWidget(self.buttonBox)
vbox.addWidget(QLabel("Select the brush preset, then click on the button you want to use to select the preset"))
self.dialog.show()
self.dialog.activateWindow()
self.dialog.exec_()
def accept(self):
i = 0
presets = []
......
......@@ -26,6 +26,8 @@ public Q_SLOTS:
void setEnabled(bool value);
void setToolTip(QString tooltip);
void trigger();
void setMenu(const QString menu);
QString menu() const;
Q_SIGNALS:
void triggered(bool);
private:
......
......@@ -29,7 +29,7 @@ public Q_SLOTS:
Document * createDocument(int width, int height, const QString &name, const QString &colorModel, const QString &colorDepth, const QString &profile) /Factory/;
Document * openDocument(const QString &filename) /Factory/;