Commit 956d6cdb authored by Boudewijn Rempt's avatar Boudewijn Rempt

Merge remote-tracking branch 'origin' into rempt/T379-resource-management

parents d86cf191 b84ef60f
......@@ -311,13 +311,6 @@ xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0 http://www.kde.org
<Menu name="tools">
<text>&amp;Tools</text>
<Menu name="scripts"><text>Scripts</text></Menu>
<Menu name="Macro Recording">
<text>Macros</text>
<Action name="Recording_Start_Recording_Macro"/>
<Action name="Recording_Stop_Recording_Macro"/>
<Action name="Macro_Open_Play"/>
<Action name="Macro_Open_Edit"/>
</Menu>
</Menu>
<Menu name="settings">
<text>Setti&amp;ngs</text>
......
......@@ -1495,58 +1495,6 @@
</Action>
</Actions>
<Actions category="Tools">
<text>Tools</text>
<Action name="Recording_Start_Recording_Macro">
<icon>media-record</icon>
<text>&amp;Start recording macro</text>
<whatsThis></whatsThis>
<toolTip>Start recording macro</toolTip>
<iconText>Start recording macro</iconText>
<activationFlags>1000</activationFlags>
<activationConditions>0</activationConditions>
<shortcut></shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
<Action name="Recording_Stop_Recording_Macro">
<icon>media-playback-stop</icon>
<text>Stop &amp;recording macro</text>
<whatsThis></whatsThis>
<toolTip>Stop recording macro</toolTip>
<iconText>Stop recording macro</iconText>
<activationFlags>1000</activationFlags>
<activationConditions>0</activationConditions>
<shortcut></shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
<Action name="Macro_Open_Play">
<icon>media-playback-start</icon>
<text>&amp;Open and play...</text>
<whatsThis></whatsThis>
<toolTip>Open and play</toolTip>
<iconText>Open and play</iconText>
<activationFlags>0</activationFlags>
<activationConditions>0</activationConditions>
<shortcut></shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
<Action name="Macro_Open_Edit">
<icon>document-edit</icon>
<text>Open &amp;and edit...</text>
<whatsThis></whatsThis>
<toolTip>Open and edit</toolTip>
<iconText>Open and edit</iconText>
<activationFlags>0</activationFlags>
<activationConditions>0</activationConditions>
<shortcut></shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
</Actions>
<Actions category="Settings">
<text>Settings</text>
<Action name="options_configure">
......
......@@ -14,7 +14,6 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/generator
${CMAKE_CURRENT_SOURCE_DIR}/layerstyles
${CMAKE_CURRENT_SOURCE_DIR}/processing
${CMAKE_CURRENT_SOURCE_DIR}/recorder
${CMAKE_SOURCE_DIR}/sdk/tests
)
......@@ -286,21 +285,6 @@ set(kritaimage_LIB_SRCS
metadata/kis_meta_data_type_info.cc
metadata/kis_meta_data_validator.cc
metadata/kis_meta_data_value.cc
recorder/kis_action_recorder.cc
recorder/kis_macro.cc
recorder/kis_macro_player.cc
recorder/kis_node_query_path.cc
recorder/kis_play_info.cc
recorder/kis_recorded_action.cc
recorder/kis_recorded_action_factory_registry.cc
recorder/kis_recorded_action_load_context.cpp
recorder/kis_recorded_action_save_context.cpp
recorder/kis_recorded_filter_action.cpp
recorder/kis_recorded_fill_paint_action.cpp
recorder/kis_recorded_node_action.cc
recorder/kis_recorded_paint_action.cpp
recorder/kis_recorded_path_paint_action.cpp
recorder/kis_recorded_shape_paint_action.cpp
kis_keyframe.cpp
kis_keyframe_channel.cpp
......@@ -328,6 +312,8 @@ set(kritaimage_LIB_SRCS
layerstyles/gimp_bump_map.cpp
KisProofingConfiguration.cpp
kis_node_query_path.cc
)
set(einspline_SRCS
......@@ -381,7 +367,6 @@ target_include_directories(kritaimage
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/layerstyles>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/metadata>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/processing>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/recorder>
)
set_target_properties(kritaimage PROPERTIES
......
because KoUpdater was moved to komvc, Krita/Image now
depends on komvc again -- this is not right, since it
makes it impossible to use krita/image outside a calligra
mvc application framework, so KoUpdater must be moved out
again.
......@@ -61,7 +61,7 @@ const QString SPACING_USE_UPDATES = "PaintOpSettings/updateSpacingBetweenDabs";
* between two creations. There is one KisPaintOpSettings per input device (mouse, tablet,
* etc...).
*
* The settings may be stored in a preset or a recorded brush stroke. Note that if your
* The settings may be stored in a preset. Note that if your
* paintop's settings subclass has data that is not stored as a property, that data is not
* saved and restored.
*
......
......@@ -40,7 +40,6 @@
#include <KoCompositeOpRegistry.h>
#include "KisProofingConfiguration.h"
#include "recorder/kis_action_recorder.h"
#include "kis_adjustment_layer.h"
#include "kis_annotation.h"
#include "kis_change_profile_visitor.h"
......@@ -140,7 +139,6 @@ public:
, undoStore(undo ? undo : new KisDumbUndoStore())
, legacyUndoAdapter(undoStore.data(), _q)
, postExecutionUndoAdapter(undoStore.data(), _q)
, recorder(_q)
, signalRouter(_q)
, animationInterface(_animationInterface)
, scheduler(_q, _q)
......@@ -217,8 +215,6 @@ public:
KisLegacyUndoAdapter legacyUndoAdapter;
KisPostExecutionUndoAdapter postExecutionUndoAdapter;
KisActionRecorder recorder;
vKisAnnotationSP annotations;
QAtomicInt disableUIUpdateSignals;
......@@ -1155,11 +1151,6 @@ KisUndoAdapter* KisImage::undoAdapter() const
return &m_d->legacyUndoAdapter;
}
KisActionRecorder* KisImage::actionRecorder() const
{
return &m_d->recorder;
}
void KisImage::setDefaultProjectionColor(const KoColor &color)
{
KIS_ASSERT_RECOVER_RETURN(m_d->rootLayer);
......
......@@ -43,7 +43,6 @@ class KoColorSpace;
class KoColor;
class KisCompositeProgressProxy;
class KisActionRecorder;
class KisUndoStore;
class KisUndoAdapter;
class KisImageSignalRouter;
......@@ -388,11 +387,6 @@ public:
*/
KisUndoStore* undoStore();
/**
* @return the action recorder associated with this image
*/
KisActionRecorder* actionRecorder() const;
/**
* Tell the image it's modified; this emits the sigImageModified
* signal. This happens when the image needs to be saved
......
......@@ -360,21 +360,16 @@ void KisImageAnimationInterface::notifyNodeChanged(const KisNode *node,
if (externalFrameActive() || m_d->frameInvalidationBlocked) return;
if (node->inherits("KisSelectionMask")) return;
KisKeyframeChannel *channel =
node->getKeyframeChannel(KisKeyframeChannel::Content.id());
const int currentTime = m_d->currentTime();
KisTimeRange invalidateRange;
if (recursive) {
KisTimeRange::calculateTimeRangeRecursive(node, currentTime(), invalidateRange, false);
} else if (channel) {
const int currentTime = m_d->currentTime();
invalidateRange = channel->affectedFrames(currentTime);
KisTimeRange::calculateTimeRangeRecursive(node, currentTime, invalidateRange, false);
} else {
invalidateRange = KisTimeRange::infinite(0);
invalidateRange = KisTimeRange::calculateNodeAffectedFrames(node, currentTime);
}
// we compress the updated rect (atm, no one uses it anyway)
QRect unitedRect;
Q_FOREACH (const QRect &rc, rects) {
......
......@@ -24,7 +24,7 @@
/**
* This class represents a simple update just that should be
* executed by the updates system from time to time, without
* any recording or undo support. Just some useful update that
* any undo support. Just some useful update that
* can be run concurrently with other types updates.
*/
class KRITAIMAGE_EXPORT KisSpontaneousJob : public KisRunnable
......
......@@ -40,14 +40,13 @@ QDebug operator<<(QDebug dbg, const KisTimeRange &r)
void KisTimeRange::calculateTimeRangeRecursive(const KisNode *node, int time, KisTimeRange &range, bool exclusive)
{
if (!node->visible()) return;
Q_FOREACH (const KisKeyframeChannel *channel, node->keyframeChannels()) {
if (exclusive) {
// Intersection
range &= channel->identicalFrames(time);
} else {
// Union
range |= channel->affectedFrames(time);
}
if (exclusive) {
// Intersection
range &= calculateNodeIdenticalFrames(node, time);
} else {
// Union
range |= calculateNodeAffectedFrames(node, time);
}
KisNodeSP child = node->firstChild();
......@@ -57,6 +56,51 @@ void KisTimeRange::calculateTimeRangeRecursive(const KisNode *node, int time, Ki
}
}
KisTimeRange KisTimeRange::calculateNodeIdenticalFrames(const KisNode *node, int time)
{
KisTimeRange range = KisTimeRange::infinite(0);
const QMap<QString, KisKeyframeChannel*> channels =
node->keyframeChannels();
if (channels.isEmpty() ||
!channels.contains(KisKeyframeChannel::Content.id())) {
return range;
}
Q_FOREACH (const KisKeyframeChannel *channel, channels) {
// Intersection
range &= channel->identicalFrames(time);
}
return range;
}
KisTimeRange KisTimeRange::calculateNodeAffectedFrames(const KisNode *node, int time)
{
KisTimeRange range;
if (!node->visible()) return range;
const QMap<QString, KisKeyframeChannel*> channels =
node->keyframeChannels();
if (channels.isEmpty() ||
!channels.contains(KisKeyframeChannel::Content.id())) {
range = KisTimeRange::infinite(0);
return range;
}
Q_FOREACH (const KisKeyframeChannel *channel, channels) {
// Union
range |= channel->affectedFrames(time);
}
return range;
}
namespace KisDomUtils {
void saveValue(QDomElement *parent, const QString &tag, const KisTimeRange &range)
......
......@@ -129,6 +129,8 @@ public:
static void calculateTimeRangeRecursive(const KisNode *node, int time, KisTimeRange &range, bool exclusive);
static KisTimeRange calculateNodeIdenticalFrames(const KisNode *node, int time);
static KisTimeRange calculateNodeAffectedFrames(const KisNode *node, int time);
private:
int m_start;
......
......@@ -27,7 +27,6 @@
typedef Eigen::Matrix<qreal, 2, 1> KisVector2D;
typedef Eigen::Matrix<qreal, 3, 1> KisVector3D;
inline KisVector2D toKisVector2D(const QPointF& p)
{
......@@ -44,18 +43,4 @@ inline QPointF toQPointF(const ExpressionType& expr)
return QPointF(expr.x(), expr.y());
}
template<typename ExpressionType>
inline QVector2D toQVector2D(const ExpressionType& expr){
return QVector2D(expr.x(), expr.y());
}
inline KisVector2D nullKisVector2D()
{
KisVector2D v;
v(0) = 0.0;
v(1) = 0.0;
return v;
}
#endif
/*
* Copyright (c) 2007 Cyrille Berger <cberger@cberger.net>
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "recorder/kis_action_recorder.h"
#include "recorder/kis_recorded_action.h"
KisActionRecorder::KisActionRecorder(QObject* parent)
: QObject(parent)
{
}
KisActionRecorder::~KisActionRecorder()
{
}
void KisActionRecorder::addAction(const KisRecordedAction& action, const KisRecordedAction* before)
{
Q_UNUSED(before);
emit(addedAction(action));
}
/*
* Copyright (c) 2007 Cyrille Berger <cberger@cberger.net>
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _KIS_ACTION_RECORDER_H_
#define _KIS_ACTION_RECORDER_H_
#include <QObject>
#include "kritaimage_export.h"
class KisRecordedAction;
/**
* This class allows other \ref KisMacro to connect to it
* to get the action that are currently created.
*/
class KRITAIMAGE_EXPORT KisActionRecorder : public QObject
{
Q_OBJECT
public:
KisActionRecorder(QObject* parent = 0);
~KisActionRecorder() override;
public Q_SLOTS:
void addAction(const KisRecordedAction& action, const KisRecordedAction* before = 0);
Q_SIGNALS:
/**
* This signal is emitted each time an action is added to this recorder.
*/
void addedAction(const KisRecordedAction& action);
};
#endif
/*
* Copyright (c) 2007 Cyrille Berger <cberger@cberger.net>
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_macro.h"
#include <QDomNode>
#include <kis_debug.h>
#include <klocalizedstring.h>
#include "kis_image.h"
#include "recorder/kis_recorded_action.h"
#include "recorder/kis_recorded_action_factory_registry.h"
#include "kis_undo_adapter.h"
#include "kis_play_info.h"
#include "kis_node_query_path.h"
#include <kis_paint_device.h>
struct Q_DECL_HIDDEN KisMacro::Private {
QList<KisRecordedAction*> actions;
};
KisMacro::KisMacro(QObject* parent) : QObject(parent), d(new Private)
{
}
KisMacro::KisMacro(const QList<KisRecordedAction*>& actions) : d(new Private)
{
appendActions(actions);
}
KisMacro::~KisMacro()
{
qDeleteAll(d->actions);
delete d;
}
void KisMacro::appendActions(const QList<KisRecordedAction*>& actions)
{
Q_FOREACH (KisRecordedAction* action, actions) {
addAction(*action);
}
}
void KisMacro::removeActions(const QList<KisRecordedAction*>& actions)
{
Q_FOREACH (KisRecordedAction* action, actions) {
d->actions.removeAll(action);
}
qDeleteAll(actions);
}
void KisMacro::addAction(const KisRecordedAction& action, const KisRecordedAction* before)
{
if (before == 0) {
KisRecordedAction* a = action.clone();
Q_ASSERT(a);
d->actions.append(a);
} else {
d->actions.insert(d->actions.indexOf(const_cast<KisRecordedAction*>(before)), action.clone());
}
}
void KisMacro::moveAction(const KisRecordedAction* action, const KisRecordedAction* before)
{
KisRecordedAction* _action = d->actions.takeAt(d->actions.indexOf(const_cast<KisRecordedAction*>(action)));
if (before == 0) {
Q_ASSERT(_action);
d->actions.append(_action);
} else {
d->actions.insert(d->actions.indexOf(const_cast<KisRecordedAction*>(before)), _action);
}
}
void KisMacro::fromXML(const QDomElement& docElem, const KisRecordedActionLoadContext* loadContext)
{
d->actions.clear();
QDomNode node = docElem.firstChild();
while (!node.isNull()) {
QDomElement elt = node.toElement(); // try to convert the node to an element.
if (!elt.isNull() && elt.tagName() == "RecordedAction") {
QString id = elt.attribute("id", "");
if (!id.isNull()) {
dbgImage << "Reconstruct : " << id << endl; // the node really is an element.
KisRecordedActionFactory* raf = KisRecordedActionFactoryRegistry::instance()->get(id);
if (raf) {
KisRecordedAction* a = raf->fromXML(elt, loadContext);
Q_ASSERT(a);
d->actions.append(a); // TODO should use addAction
} else {
dbgImage << "Unknown action : " << id << endl;
}
} else {
dbgImage << "Invalid recorded action: null id";
}
} else {
dbgImage << "Unknown element " << elt.tagName() << (elt.tagName() == "RecordedAction");
}
node = node.nextSibling();
}
}
void KisMacro::toXML(QDomDocument& doc, QDomElement& e, KisRecordedActionSaveContext* saveContext) const
{
for (QList<KisRecordedAction*>::iterator it = d->actions.begin();
it != d->actions.end(); ++it) {
QDomElement eAct = doc.createElement("RecordedAction");
(*it)->toXML(doc, eAct, saveContext);
e.appendChild(eAct);
}
}
const QList<KisRecordedAction*>& KisMacro::actions() const
{
return d->actions;
}
/*
* Copyright (c) 2007 Cyrille Berger <cberger@cberger.net>
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _KIS_MACRO_H_
#define _KIS_MACRO_H_
#include <QList>
#include <QObject>
#include <kritaimage_export.h>
#include "kis_serializable_configuration.h"
#include "kis_types.h"
class KisRecordedAction;
class KisRecordedActionLoadContext;
class KisRecordedActionSaveContext;
/**
* This is the base class for macro in Krita. It's basically a list of recorded action,KisRecordedAction
* that can be stored as XML, played, and edited.
*/
class KRITAIMAGE_EXPORT KisMacro : public QObject
{
Q_OBJECT
public:
KisMacro(QObject* parent = 0);
KisMacro(const QList<KisRecordedAction*>& _actions);
~KisMacro() override;
public:
/**
* Append a list of actions, and make clone of them.
*/
void appendActions(const QList<KisRecordedAction*>& actions);
/**
* Remove the list of actions. Actions are deleted.
*/
void removeActions(const QList<KisRecordedAction*>& actions);
/**
* Move the action before an other one.
* @param before if null, the action is moved to the end
*/
void moveAction(const KisRecordedAction* action, const KisRecordedAction* before);
public: // serialization functions
virtual void fromXML(const QDomElement&, const KisRecordedActionLoadContext* loadContext);
virtual void toXML(QDomDocument& doc, QDomElement& e, KisRecordedActionSaveContext* saveContext) const;
const QList<KisRecordedAction*>& actions() const;
public Q_SLOTS:
/**
* add a single action, and make a clone of it.
* @param before if non null, the action will be added before that action,
* otherwise, if null, the action will be added at the end.
*/
virtual void addAction(const KisRecordedAction& action, const KisRecordedAction* before = 0);
private:
struct Private;
Private* const d;
};
#endif
/*
* Copyright (c) 2007,2011 Cyrille Berger <cberger@cberger.net>
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_macro_player.h"
#include <klocalizedstring.h>
#include <KoProgressUpdater.h>
#include <KoUpdater.h>
#include "kis_image.h"
#include "kis_debug.h"
#include "kis_macro.h"
#include "kis_node_query_path.h"
#include "kis_play_info.h"
#include "kis_recorded_action.h"
#include "kis_undo_adapter.h"
#include "kundo2magicstring.h"
struct Q_DECL_HIDDEN KisMacroPlayer::Private
{
Private(const KisPlayInfo& _info) : info(_info), updater(0) {}
bool paused;
KisMacro* macro;
KisPlayInfo info;
KoUpdater* updater;
};
KisMacroPlayer::KisMacroPlayer(KisMacro* _macro, const KisPlayInfo& info, KoUpdater *