diff --git a/krita/krita.action b/krita/krita.action
--- a/krita/krita.action
+++ b/krita/krita.action
@@ -2141,24 +2141,11 @@
-
-
- Insert Keyframe Right
-
- Insert keyframes to the right of selection moving the tail of animation to the right
-
- 100000
- 0
-
- false
-
-
-
-
+
Insert Keyframe Left
- Insert keyframes to the left of selection moving the tail of animation to the right
+ Insert keyframes to the left of selection, moving the tail of animation to the right.
100000
0
@@ -2167,11 +2154,11 @@
-
+
- Insert N Keyframes Right
+ Insert Keyframe Right
- Insert several keyframes to the right of selection moving the tail of animation to the right
+ Insert keyframes to the right of selection, moving the tail of animation to the right.
100000
0
@@ -2180,11 +2167,11 @@
-
+
- Insert N Keyframes Left
+ Insert Multiple Keyframes
- Insert several keyframes to the left of selection moving the tail of animation to the right
+ Insert several keyframes based on user parameters.
100000
0
@@ -2219,24 +2206,11 @@
-
-
- Insert Column Right
-
- Insert column to the right of selection moving the tail of animation to the right
-
- 100000
- 0
-
- false
-
-
-
-
+
Insert Column Left
- Insert column to the left of selection moving the tail of animation to the right
+ Insert column to the left of selection, moving the tail of animation to the right
100000
0
@@ -2245,11 +2219,11 @@
-
+
- Insert N Columns Right
+ Insert Column Right
- Insert several columns to the right of selection moving the tail of animation to the right
+ Insert column to the right of selection, moving the tail of animation to the right
100000
0
@@ -2258,11 +2232,11 @@
-
+
- Insert N Columns Left
+ Insert Multiple Columns
- Insert several columns to the left of selection moving the tail of animation to the right
+ Insert several columns based on user parameters.
100000
0
@@ -2310,9 +2284,9 @@
-
+
- Insert N Hold Frames
+ Insert Multiple Hold Frames
Insert N hold frames after every keyframe
@@ -2336,9 +2310,9 @@
-
+
- Remove N Hold Frames
+ Remove Multiple Hold Frames
Remove N hold frames after every keyframe
@@ -2362,9 +2336,9 @@
-
+
- Insert N Hold Columns
+ Insert Multiple Hold Columns
Insert N hold columns into the frame at the current position
@@ -2388,9 +2362,9 @@
-
+
- Remove N Hold Columns
+ Remove Multiple Hold Columns
Remove N hold columns from the frame at the current position
diff --git a/plugins/dockers/animation/kis_time_based_item_model.cpp b/plugins/dockers/animation/kis_time_based_item_model.cpp
--- a/plugins/dockers/animation/kis_time_based_item_model.cpp
+++ b/plugins/dockers/animation/kis_time_based_item_model.cpp
@@ -304,7 +304,7 @@
}
Q_FOREACH(KisKeyframeChannel *channel, channelsAt(srcIndex)) {
- if (moveEmptyFrames || channel->keyframeAt(srcIndex.column())) {
+ if (moveEmptyFrames || channel->keyframeAt(srcIndex.column())) {
srcFrameItems << KisAnimationUtils::FrameItem(srcNode, channel->id(), srcIndex.column());
dstFrameItems << KisAnimationUtils::FrameItem(dstNode, channel->id(), dstIndex.column());
}
@@ -350,8 +350,8 @@
new KisSwitchCurrentTimeCommand(m_d->image->animationInterface(),
oldTime,
- newTime, parentCommand);
-
+ newTime,
+ parentCommand);
}
KisProcessingApplicator::runSingleCommandStroke(m_d->image, parentCommand, KisStrokeJobData::BARRIER);
diff --git a/plugins/dockers/animation/timeline_frames_model.h b/plugins/dockers/animation/timeline_frames_model.h
--- a/plugins/dockers/animation/timeline_frames_model.h
+++ b/plugins/dockers/animation/timeline_frames_model.h
@@ -19,6 +19,7 @@
#ifndef __TIMELINE_FRAMES_MODEL_H
#define __TIMELINE_FRAMES_MODEL_H
+
#include
#include
@@ -86,9 +87,9 @@
Qt::DropActions supportedDragActions() const override;
Qt::DropActions supportedDropActions() const override;
QStringList mimeTypes() const override;
- QMimeData * mimeData(const QModelIndexList &indexes) const override;
- QMimeData * mimeDataExtended(const QModelIndexList &indexes, const QModelIndex &baseIndex, MimeCopyPolicy copyPolicy) const;
- bool dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent) override;
+ QMimeData *mimeData(const QModelIndexList &indexes) const override;
+ QMimeData *mimeDataExtended(const QModelIndexList &indexes, const QModelIndex &baseIndex, MimeCopyPolicy copyPolicy) const;
+ bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
bool dropMimeDataExtended(const QMimeData *data, Qt::DropAction action, const QModelIndex &parent, bool *dataMoved = 0);
diff --git a/plugins/dockers/animation/timeline_frames_view.h b/plugins/dockers/animation/timeline_frames_view.h
--- a/plugins/dockers/animation/timeline_frames_view.h
+++ b/plugins/dockers/animation/timeline_frames_view.h
@@ -19,6 +19,7 @@
#ifndef __TIMELINE_FRAMES_VIEW_H
#define __TIMELINE_FRAMES_VIEW_H
+
#include
#include
#include "kis_action_manager.h"
@@ -27,9 +28,20 @@
class KisAction;
class TimelineWidget;
+enum TimelineDirection : short
+{
+ LEFT = -1,
+ BEFORE = -1,
+
+ RIGHT = 1,
+ AFTER = 1
+};
+
+
class KRITAANIMATIONDOCKER_EXPORT TimelineFramesView : public QTableView
{
Q_OBJECT
+
public:
TimelineFramesView(QWidget *parent);
~TimelineFramesView() override;
@@ -40,7 +52,7 @@
void setShowInTimeline(KisAction *action);
- void setActionManager( KisActionManager * actionManager);
+ void setActionManager(KisActionManager *actionManager);
public Q_SLOTS:
void slotSelectionChanged();
@@ -61,51 +73,49 @@
void slotRemoveLayer();
void slotLayerContextMenuRequested(const QPoint &globalPos);
- // New, Copy, Insert and Remove Frames
- void slotNewFrame();
- void slotCopyFrame();
-
- void slotInsertKeyframesLeft(int count = 1, int timing = 1, bool forceEntireColumn = false);
- void slotInsertKeyframesRight(int count = 1, int timing = 1, bool forceEntireColumn = false);
+ // New, Insert and Remove Frames
+ void slotAddBlankFrame();
+ void slotAddDuplicateFrame();
- void slotInsertKeyframesLeftCustom();
- void slotInsertKeyframesRightCustom();
+ void slotInsertKeyframeLeft() {insertKeyframes(-1, 1, TimelineDirection::LEFT, false);}
+ void slotInsertKeyframeRight() {insertKeyframes(-1, 1, TimelineDirection::RIGHT, false);}
- void slotRemoveFrame(bool forceEntireColumn = false, bool needsOffset = false);
- void slotRemoveFramesAndShift(bool forceEntireColumn = false);
+ void slotInsertKeyframeColumnLeft() {insertKeyframes(-1, 1, TimelineDirection::LEFT, true);}
+ void slotInsertKeyframeColumnRight() {insertKeyframes(-1, 1, TimelineDirection::RIGHT, true);}
- void slotInsertColumnsLeft(int count = 1, int timing = 1);
- void slotInsertColumnsLeftCustom();
+ void slotInsertMultipleKeyframes() {insertMultipleKeyframes(false);}
+ void slotInsertMultipleKeyframeColumns() {insertMultipleKeyframes(true);}
- void slotInsertColumnsRight(int count = 1, int timing = 1);
- void slotInsertColumnsRightCustom();
+ void slotRemoveSelectedFrames(bool entireColumn = false, bool needsOffset = false);
+ void slotRemoveSelectedFramesAndShift() {slotRemoveSelectedFrames(false, true);}
- void slotRemoveColumns();
- void slotRemoveColumnsAndShift();
+ void slotRemoveSelectedColumns() {slotRemoveSelectedFrames(true);}
+ void slotRemoveSelectedColumnsAndShift() {slotRemoveSelectedFrames(true, true);}
- void slotInsertHoldFrames(int count = 1, bool forceEntireColumn = false);
- void slotRemoveHoldFrames(int count = 1, bool forceEntireColumn = false);
+ void slotInsertHoldFrame() {insertOrRemoveHoldFrames(1);}
+ void slotRemoveHoldFrame() {insertOrRemoveHoldFrames(-1);}
- void slotInsertHoldFramesCustom();
- void slotRemoveHoldFramesCustom();
+ void slotInsertHoldFrameColumn() {insertOrRemoveHoldFrames(1,true);}
+ void slotRemoveHoldFrameColumn() {insertOrRemoveHoldFrames(-1,true);}
- void slotInsertHoldColumns(int count = 1);
- void slotRemoveHoldColumns(int count = 1);
+ void slotInsertMultipleHoldFrames() {insertOrRemoveMultipleHoldFrames(true);}
+ void slotRemoveMultipleHoldFrames() {insertOrRemoveMultipleHoldFrames(false);}
- void slotInsertHoldColumnsCustom();
- void slotRemoveHoldColumnsCustom();
+ void slotInsertMultipleHoldFrameColumns() {insertOrRemoveMultipleHoldFrames(true, true);}
+ void slotRemoveMultipleHoldFrameColumns() {insertOrRemoveMultipleHoldFrames(false, true);}
- void slotMirrorFrames(bool forceEntireColumn = false);
- void slotMirrorColumns();
+ void slotMirrorFrames(bool entireColumn = false);
+ void slotMirrorColumns() {slotMirrorFrames(true);}
// Copy-paste
- void slotCopyFrames(bool forceEntireColumn = false);
- void slotCutFrames(bool forceEntireColumn = false);
- void slotPasteFrames(bool forceEntireColumn = false);
+ void slotCopyFrames() {cutCopyImpl(false, true);}
+ void slotCutFrames() {cutCopyImpl(false, false);}
+
+ void slotCopyColumns() {cutCopyImpl(true, true);}
+ void slotCutColumns() {cutCopyImpl(true, false);}
- void slotCopyColumns();
- void slotCutColumns();
- void slotPasteColumns();
+ void slotPasteFrames(bool entireColumn = false);
+ void slotPasteColumns() {slotPasteFrames(true);}
void slotReselectCurrentIndex();
@@ -128,14 +138,28 @@
private:
void setFramesPerSecond(int fps);
+
void calculateSelectionMetrics(int &minColumn, int &maxColumn, QSet &rows) const;
- void insertFramesImpl(int insertAtColumn, int count, int timing, QSet rows, bool forceEntireColumn);
+ /* Insert new keyframes/columns.
+ *
+ * count - Number of frames to add. If <0, use number of currently SELECTED frames.
+ * timing - Animation timing of frames to be added (on 1s, 2s, 3s, etc.)
+ * direction - Insert frames before (left) or after (right) selection scrubber.
+ * entireColumn - Create frames on all layers (rows) instead of just the active layer?
+ */
+ void insertKeyframes(int count = 1, int timing = 1,
+ TimelineDirection direction = TimelineDirection::LEFT, bool entireColumn = false);
+ void insertMultipleKeyframes(bool entireColumn = false);
+
+ void insertOrRemoveHoldFrames(int count, bool entireColumn = false);
+ void insertOrRemoveMultipleHoldFrames(bool insertion, bool entireColumn = false);
+
+ void cutCopyImpl(bool entireColumn, bool copy);
void createFrameEditingMenuActions(QMenu *menu, bool addFrameCreationActions);
- QModelIndexList calculateSelectionSpan(bool forceEntireColumn, bool editableOnly = true) const;
- void cutCopyImpl(bool forceEntireColumn, bool copy);
+ QModelIndexList calculateSelectionSpan(bool entireColumn, bool editableOnly = true) const;
int defaultNumberOfFramesToAdd() const;
void setDefaultNumberOfFramesToAdd(int value) const;
@@ -163,7 +187,7 @@
void mouseMoveEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
void wheelEvent(QWheelEvent *e) override;
- void rowsInserted(const QModelIndex& parent, int start, int end) override;
+ void rowsInserted(const QModelIndex &parent, int start, int end) override;
bool viewportEvent(QEvent *event) override;
private:
diff --git a/plugins/dockers/animation/timeline_frames_view.cpp b/plugins/dockers/animation/timeline_frames_view.cpp
--- a/plugins/dockers/animation/timeline_frames_view.cpp
+++ b/plugins/dockers/animation/timeline_frames_view.cpp
@@ -19,38 +19,25 @@
#include "timeline_frames_view.h"
#include "timeline_frames_model.h"
-
#include "timeline_ruler_header.h"
#include "timeline_layers_header.h"
#include "timeline_insert_keyframe_dialog.h"
-
-#include
-#include
+#include "timeline_frames_item_delegate.h"
#include
-
-#include
#include
-#include
#include
-#include
#include
#include
-#include
#include
-#include
-#include
-#include
+#include
+#include
+#include
#include "KSharedConfig"
-#include "kis_debug.h"
-#include "timeline_frames_item_delegate.h"
-
#include "kis_zoom_button.h"
-
#include "kis_icon_utils.h"
-
#include "kis_animation_utils.h"
#include "kis_custom_modifiers_catcher.h"
#include "kis_action.h"
@@ -59,17 +46,11 @@
#include "kis_color_label_selector_widget.h"
#include "kis_slider_spin_box.h"
#include
+#include
+#include
#include
#include
-#include
-#include
-#include
-
-#include
-#include
-
-#include "config-qtmultimedia.h"
typedef QPair QItemViewPaintPair;
typedef QList QItemViewPaintPairs;
@@ -134,7 +115,7 @@
KoIconToolTip tip;
- KisActionManager * actionMan = 0;
+ KisActionManager *actionMan = 0;
};
TimelineFramesView::TimelineFramesView(QWidget *parent)
@@ -160,20 +141,19 @@
m_d->horizontalRuler = new TimelineRulerHeader(this);
this->setHorizontalHeader(m_d->horizontalRuler);
- connect(m_d->horizontalRuler, SIGNAL(sigInsertColumnsLeft()), SLOT(slotInsertColumnsLeft()));
- connect(m_d->horizontalRuler, SIGNAL(sigInsertColumnsRight()), SLOT(slotInsertColumnsRight()));
+ connect(m_d->horizontalRuler, SIGNAL(sigInsertColumnLeft()), SLOT(slotInsertKeyframeColumnLeft()));
+ connect(m_d->horizontalRuler, SIGNAL(sigInsertColumnRight()), SLOT(slotInsertKeyframeColumnRight()));
- connect(m_d->horizontalRuler, SIGNAL(sigInsertColumnsLeftCustom()), SLOT(slotInsertColumnsLeftCustom()));
- connect(m_d->horizontalRuler, SIGNAL(sigInsertColumnsRightCustom()), SLOT(slotInsertColumnsRightCustom()));
+ connect(m_d->horizontalRuler, SIGNAL(sigInsertMultipleColumns()), SLOT(slotInsertMultipleKeyframeColumns()));
- connect(m_d->horizontalRuler, SIGNAL(sigRemoveColumns()), SLOT(slotRemoveColumns()));
- connect(m_d->horizontalRuler, SIGNAL(sigRemoveColumnsAndShift()), SLOT(slotRemoveColumnsAndShift()));
+ connect(m_d->horizontalRuler, SIGNAL(sigRemoveColumns()), SLOT(slotRemoveSelectedColumns()));
+ connect(m_d->horizontalRuler, SIGNAL(sigRemoveColumnsAndShift()), SLOT(slotRemoveSelectedColumnsAndShift()));
- connect(m_d->horizontalRuler, SIGNAL(sigInsertHoldColumns()), SLOT(slotInsertHoldColumns()));
- connect(m_d->horizontalRuler, SIGNAL(sigRemoveHoldColumns()), SLOT(slotRemoveHoldColumns()));
+ connect(m_d->horizontalRuler, SIGNAL(sigInsertHoldColumns()), SLOT(slotInsertHoldFrameColumn()));
+ connect(m_d->horizontalRuler, SIGNAL(sigRemoveHoldColumns()), SLOT(slotRemoveHoldFrameColumn()));
- connect(m_d->horizontalRuler, SIGNAL(sigInsertHoldColumnsCustom()), SLOT(slotInsertHoldColumnsCustom()));
- connect(m_d->horizontalRuler, SIGNAL(sigRemoveHoldColumnsCustom()), SLOT(slotRemoveHoldColumnsCustom()));
+ connect(m_d->horizontalRuler, SIGNAL(sigInsertHoldColumnsCustom()), SLOT(slotInsertMultipleHoldFrameColumns()));
+ connect(m_d->horizontalRuler, SIGNAL(sigRemoveHoldColumnsCustom()), SLOT(slotRemoveMultipleHoldFrameColumns()));
connect(m_d->horizontalRuler, SIGNAL(sigMirrorColumns()), SLOT(slotMirrorColumns()));
@@ -305,13 +285,13 @@
{
}
-void TimelineFramesView::setShowInTimeline(KisAction* action)
+void TimelineFramesView::setShowInTimeline(KisAction *action)
{
m_d->showHideLayerAction = action;
m_d->layerEditingMenu->addAction(m_d->showHideLayerAction);
}
-void TimelineFramesView::setActionManager( KisActionManager * actionManager)
+void TimelineFramesView::setActionManager(KisActionManager *actionManager)
{
m_d->actionMan = actionManager;
m_d->horizontalRuler->setActionManager(actionManager);
@@ -321,40 +301,37 @@
KisAction *action = 0;
action = m_d->actionMan->createAction("add_blank_frame");
- connect(action, SIGNAL(triggered()), SLOT(slotNewFrame()));
+ connect(action, SIGNAL(triggered()), SLOT(slotAddBlankFrame()));
action = m_d->actionMan->createAction("add_duplicate_frame");
- connect(action, SIGNAL(triggered()), SLOT(slotCopyFrame()));
-
- action = m_d->actionMan->createAction("insert_keyframes_right");
- connect(action, SIGNAL(triggered()), SLOT(slotInsertKeyframesRight()));
+ connect(action, SIGNAL(triggered()), SLOT(slotAddDuplicateFrame()));
- action = m_d->actionMan->createAction("insert_n_keyframes_right");
- connect(action, SIGNAL(triggered()), SLOT(slotInsertKeyframesRightCustom()));
+ action = m_d->actionMan->createAction("insert_keyframe_left");
+ connect(action, SIGNAL(triggered()), SLOT(slotInsertKeyframeLeft()));
- action = m_d->actionMan->createAction("insert_keyframes_left");
- connect(action, SIGNAL(triggered()), SLOT(slotInsertKeyframesLeft()));
+ action = m_d->actionMan->createAction("insert_keyframe_right");
+ connect(action, SIGNAL(triggered()), SLOT(slotInsertKeyframeRight()));
- action = m_d->actionMan->createAction("insert_n_keyframes_left");
- connect(action, SIGNAL(triggered()), SLOT(slotInsertKeyframesLeftCustom()));
+ action = m_d->actionMan->createAction("insert_multiple_keyframes");
+ connect(action, SIGNAL(triggered()), SLOT(slotInsertMultipleKeyframes()));
action = m_d->actionMan->createAction("remove_frames_and_pull");
- connect(action, SIGNAL(triggered()), SLOT(slotRemoveFramesAndShift()));
+ connect(action, SIGNAL(triggered()), SLOT(slotRemoveSelectedFramesAndShift()));
action = m_d->actionMan->createAction("remove_frames");
- connect(action, SIGNAL(triggered()), SLOT(slotRemoveFrame()));
+ connect(action, SIGNAL(triggered()), SLOT(slotRemoveSelectedFrames()));
action = m_d->actionMan->createAction("insert_hold_frame");
- connect(action, SIGNAL(triggered()), SLOT(slotInsertHoldFrames()));
+ connect(action, SIGNAL(triggered()), SLOT(slotInsertHoldFrame()));
- action = m_d->actionMan->createAction("insert_n_hold_frames");
- connect(action, SIGNAL(triggered()), SLOT(slotInsertHoldFramesCustom()));
+ action = m_d->actionMan->createAction("insert_multiple_hold_frames");
+ connect(action, SIGNAL(triggered()), SLOT(slotInsertMultipleHoldFrames()));
action = m_d->actionMan->createAction("remove_hold_frame");
- connect(action, SIGNAL(triggered()), SLOT(slotRemoveHoldFrames()));
+ connect(action, SIGNAL(triggered()), SLOT(slotRemoveHoldFrame()));
- action = m_d->actionMan->createAction("remove_n_hold_frames");
- connect(action, SIGNAL(triggered()), SLOT(slotRemoveHoldFramesCustom()));
+ action = m_d->actionMan->createAction("remove_multiple_hold_frames");
+ connect(action, SIGNAL(triggered()), SLOT(slotRemoveMultipleHoldFrames()));
action = m_d->actionMan->createAction("mirror_frames");
connect(action, SIGNAL(triggered()), SLOT(slotMirrorFrames()));
@@ -722,7 +699,6 @@
QTableView::rowsInserted(parent, start, end);
}
-
inline bool isIndexDragEnabled(QAbstractItemModel *model, const QModelIndex &index) {
return (model->flags(index) & Qt::ItemIsDragEnabled);
}
@@ -948,40 +924,44 @@
if (selectionExists) {
- KisActionManager::safePopulateMenu(menu, "update_playback_range", m_d->actionMan);
+ KisActionManager::safePopulateMenu(menu, "update_playback_range", m_d->actionMan);
} else {
KisActionManager::safePopulateMenu(menu, "set_start_time", m_d->actionMan);
KisActionManager::safePopulateMenu(menu, "set_end_time", m_d->actionMan);
}
- menu->addSeparator();
+ menu->addSeparator();
KisActionManager::safePopulateMenu(menu, "cut_frames_to_clipboard", m_d->actionMan);
KisActionManager::safePopulateMenu(menu, "copy_frames_to_clipboard", m_d->actionMan);
KisActionManager::safePopulateMenu(menu, "paste_frames_from_clipboard", m_d->actionMan);
menu->addSeparator();
- QMenu *frames = menu->addMenu(i18nc("@item:inmenu", "Keyframes"));
- KisActionManager::safePopulateMenu(frames, "insert_keyframes_right", m_d->actionMan);
- KisActionManager::safePopulateMenu(frames, "insert_keyframes_left", m_d->actionMan);
- frames->addSeparator();
- KisActionManager::safePopulateMenu(frames, "insert_n_keyframes_right", m_d->actionMan);
- KisActionManager::safePopulateMenu(frames, "insert_n_keyframes_left", m_d->actionMan);
-
- QMenu *hold = menu->addMenu(i18nc("@item:inmenu", "Hold Frames"));
- KisActionManager::safePopulateMenu(hold, "insert_hold_frame", m_d->actionMan);
- KisActionManager::safePopulateMenu(hold, "remove_hold_frame", m_d->actionMan);
+ { //Frames submenu.
+ QMenu *frames = menu->addMenu(i18nc("@item:inmenu", "Keyframes"));
+ KisActionManager::safePopulateMenu(frames, "insert_keyframe_left", m_d->actionMan);
+ KisActionManager::safePopulateMenu(frames, "insert_keyframe_right", m_d->actionMan);
+ frames->addSeparator();
+ KisActionManager::safePopulateMenu(frames, "insert_multiple_keyframes", m_d->actionMan);
+ }
- hold->addSeparator();
- KisActionManager::safePopulateMenu(hold, "insert_n_hold_frames", m_d->actionMan);
- KisActionManager::safePopulateMenu(hold, "remove_n_hold_frames", m_d->actionMan);
+ { //Holds submenu.
+ QMenu *hold = menu->addMenu(i18nc("@item:inmenu", "Hold Frames"));
+ KisActionManager::safePopulateMenu(hold, "insert_hold_frame", m_d->actionMan);
+ KisActionManager::safePopulateMenu(hold, "remove_hold_frame", m_d->actionMan);
+ hold->addSeparator();
+ KisActionManager::safePopulateMenu(hold, "insert_multiple_hold_frames", m_d->actionMan);
+ KisActionManager::safePopulateMenu(hold, "remove_multiple_hold_frames", m_d->actionMan);
+ }
menu->addSeparator();
+
KisActionManager::safePopulateMenu(menu, "remove_frames", m_d->actionMan);
KisActionManager::safePopulateMenu(menu, "remove_frames_and_pull", m_d->actionMan);
menu->addSeparator();
+
if (addFrameCreationActions) {
KisActionManager::safePopulateMenu(menu, "add_blank_frame", m_d->actionMan);
KisActionManager::safePopulateMenu(menu, "add_duplicate_frame", m_d->actionMan);
@@ -1202,20 +1182,18 @@
enableAction("add_blank_frame", hasEditableFrames);
enableAction("add_duplicate_frame", hasEditableFrames);
- enableAction("insert_keyframes_right", hasEditableFrames);
- enableAction("insert_n_keyframes_right", hasEditableFrames);
-
- enableAction("insert_keyframes_left", hasEditableFrames);
- enableAction("insert_n_keyframes_left", hasEditableFrames);
+ enableAction("insert_keyframe_left", hasEditableFrames);
+ enableAction("insert_keyframe_right", hasEditableFrames);
+ enableAction("insert_multiple_keyframes", hasEditableFrames);
enableAction("remove_frames", hasEditableFrames && hasExistingFrames);
enableAction("remove_frames_and_pull", hasEditableFrames);
enableAction("insert_hold_frame", hasEditableFrames);
- enableAction("insert_n_hold_frames", hasEditableFrames);
+ enableAction("insert_multiple_hold_frames", hasEditableFrames);
enableAction("remove_hold_frame", hasEditableFrames);
- enableAction("remove_n_hold_frames", hasEditableFrames);
+ enableAction("remove_multiple_hold_frames", hasEditableFrames);
enableAction("mirror_frames", hasEditableFrames && editableIndexes.size() > 1);
@@ -1284,7 +1262,7 @@
model()->removeRow(index.row());
}
-void TimelineFramesView::slotNewFrame()
+void TimelineFramesView::slotAddBlankFrame()
{
QModelIndex index = currentIndex();
if (!index.isValid() ||
@@ -1296,7 +1274,7 @@
m_d->model->createFrame(index);
}
-void TimelineFramesView::slotCopyFrame()
+void TimelineFramesView::slotAddDuplicateFrame()
{
QModelIndex index = currentIndex();
if (!index.isValid() ||
@@ -1322,102 +1300,49 @@
}
}
-void TimelineFramesView::insertFramesImpl(int insertAtColumn, int count, int timing, QSet rows, bool forceEntireColumn)
-{
- if (forceEntireColumn) {
- rows.clear();
- for (int i = 0; i < m_d->model->rowCount(); i++) {
- if (!m_d->model->data(m_d->model->index(i, insertAtColumn), TimelineFramesModel::FrameEditableRole).toBool()) continue;
- rows.insert(i);
- }
- }
-
- if (!rows.isEmpty()) {
- m_d->model->insertFrames(insertAtColumn, rows.toList(), count, timing);
- }
-}
-
-void TimelineFramesView::slotInsertKeyframesLeft(int count, int timing, bool forceEntireColumn)
-{
- QSet rows;
- int minColumn = 0;
- int maxColumn = 0;
-
- calculateSelectionMetrics(minColumn, maxColumn, rows);
-
- if (count <= 0) {
- count = qMax(1, maxColumn - minColumn + 1);
- }
-
- insertFramesImpl(minColumn, count, timing, rows, forceEntireColumn);
-}
-
-void TimelineFramesView::slotInsertKeyframesRight(int count, int timing, bool forceEntireColumn)
+void TimelineFramesView::insertKeyframes(int count, int timing, TimelineDirection direction, bool entireColumn)
{
QSet rows;
- int minColumn = 0;
- int maxColumn = 0;
+ int minColumn = 0, maxColumn = 0;
calculateSelectionMetrics(minColumn, maxColumn, rows);
- if (count <= 0) {
+ if (count <= 0) { //Negative count? Use number of selected frames.
count = qMax(1, maxColumn - minColumn + 1);
}
- insertFramesImpl(maxColumn + 1, count, timing, rows, forceEntireColumn);
-}
-
-void TimelineFramesView::slotInsertColumnsLeft(int count, int timing)
-{
- slotInsertKeyframesLeft(count, timing, true);
-}
-
-void TimelineFramesView::slotInsertColumnsRight(int count, int timing)
-{
- slotInsertKeyframesRight(count, timing, true);
-}
-
-void TimelineFramesView::slotInsertKeyframesLeftCustom()
-{
- int count, timing;
+ const int insertionColumn =
+ direction == TimelineDirection::RIGHT ?
+ maxColumn + 1 : minColumn;
- if (m_d->insertKeyframeDialog->promptUserSettings(count, timing)) {
- slotInsertKeyframesLeft(count, timing, false);
- }
-}
-
-void TimelineFramesView::slotInsertKeyframesRightCustom()
-{
- int count, timing;
-
- if (m_d->insertKeyframeDialog->promptUserSettings(count, timing)) {
- slotInsertKeyframesRight(count, timing, false);
+ if (entireColumn) {
+ rows.clear();
+ for (int i = 0; i < m_d->model->rowCount(); i++) {
+ if (!m_d->model->data(m_d->model->index(i, insertionColumn), TimelineFramesModel::FrameEditableRole).toBool()) continue;
+ rows.insert(i);
+ }
}
-}
-
-void TimelineFramesView::slotInsertColumnsLeftCustom()
-{
- int count, timing;
- if (m_d->insertKeyframeDialog->promptUserSettings(count, timing)) {
- slotInsertColumnsLeft(count, timing);
+ if (!rows.isEmpty()) {
+ m_d->model->insertFrames(insertionColumn, rows.toList(), count, timing);
}
}
-void TimelineFramesView::slotInsertColumnsRightCustom()
+void TimelineFramesView::insertMultipleKeyframes(bool entireColumn)
{
int count, timing;
+ TimelineDirection direction;
- if (m_d->insertKeyframeDialog->promptUserSettings(count, timing)) {
- slotInsertColumnsRight(count, timing);
+ if (m_d->insertKeyframeDialog->promptUserSettings(count, timing, direction)) {
+ insertKeyframes(count, timing, direction, entireColumn);
}
}
-QModelIndexList TimelineFramesView::calculateSelectionSpan(bool forceEntireColumn, bool editableOnly) const
+QModelIndexList TimelineFramesView::calculateSelectionSpan(bool entireColumn, bool editableOnly) const
{
QModelIndexList indexes;
- if (forceEntireColumn) {
+ if (entireColumn) {
QSet rows;
int minColumn = 0;
int maxColumn = 0;
@@ -1444,9 +1369,9 @@
return indexes;
}
-void TimelineFramesView::slotRemoveFrame(bool forceEntireColumn, bool needsOffset)
+void TimelineFramesView::slotRemoveSelectedFrames(bool entireColumn, bool needsOffset)
{
- const QModelIndexList indexes = calculateSelectionSpan(forceEntireColumn);
+ const QModelIndexList indexes = calculateSelectionSpan(entireColumn);
if (!indexes.isEmpty()) {
if (needsOffset) {
@@ -1457,26 +1382,11 @@
}
}
-void TimelineFramesView::slotRemoveColumns()
-{
- slotRemoveFrame(true);
-}
-
-void TimelineFramesView::slotRemoveFramesAndShift(bool forceEntireColumn)
-{
- slotRemoveFrame(forceEntireColumn, true);
-}
-
-void TimelineFramesView::slotRemoveColumnsAndShift()
-{
- slotRemoveFramesAndShift(true);
-}
-
-void TimelineFramesView::slotInsertHoldFrames(int count, bool forceEntireColumn)
+void TimelineFramesView::insertOrRemoveHoldFrames(int count, bool entireColumn)
{
QModelIndexList indexes;
- if (!forceEntireColumn) {
+ if (!entireColumn) {
Q_FOREACH (const QModelIndex &index, selectionModel()->selectedIndexes()) {
if (m_d->model->data(index, TimelineFramesModel::FrameEditableRole).toBool()) {
indexes << index;
@@ -1498,98 +1408,38 @@
}
}
-void TimelineFramesView::slotRemoveHoldFrames(int count, bool forceEntireColumn)
-{
- slotInsertHoldFrames(-count, forceEntireColumn);
-}
-
-void TimelineFramesView::slotInsertHoldFramesCustom()
+void TimelineFramesView::insertOrRemoveMultipleHoldFrames(bool insertion, bool entireColumn)
{
bool ok = false;
const int count = QInputDialog::getInt(this,
- i18nc("@title:window", "Insert hold frames"),
+ i18nc("@title:window", "Insert or Remove Hold Frames"),
i18nc("@label:spinbox", "Enter number of frames"),
defaultNumberOfFramesToAdd(),
1, 10000, 1, &ok);
if (ok) {
- setDefaultNumberOfFramesToAdd(count);
- slotInsertHoldFrames(count);
- }
-}
-
-void TimelineFramesView::slotRemoveHoldFramesCustom()
-{
- bool ok = false;
- const int count = QInputDialog::getInt(this,
- i18nc("@title:window", "Remove hold frames"),
- i18nc("@label:spinbox", "Enter number of frames"),
- defaultNumberOfFramesToRemove(),
- 1, 10000, 1, &ok);
-
- if (ok) {
- setDefaultNumberOfFramesToRemove(count);
- slotRemoveHoldFrames(count);
- }
-}
-
-void TimelineFramesView::slotInsertHoldColumns(int count)
-{
- slotInsertHoldFrames(count, true);
-}
-
-void TimelineFramesView::slotRemoveHoldColumns(int count)
-{
- slotRemoveHoldFrames(count, true);
-}
-
-void TimelineFramesView::slotInsertHoldColumnsCustom()
-{
- bool ok = false;
- const int count = QInputDialog::getInt(this,
- i18nc("@title:window", "Insert hold columns"),
- i18nc("@label:spinbox", "Enter number of columns"),
- defaultNumberOfColumnsToAdd(),
- 1, 10000, 1, &ok);
-
- if (ok) {
- setDefaultNumberOfColumnsToAdd(count);
- slotInsertHoldColumns(count);
- }
-}
-
-void TimelineFramesView::slotRemoveHoldColumnsCustom()
-{
- bool ok = false;
- const int count = QInputDialog::getInt(this,
- i18nc("@title:window", "Remove hold columns"),
- i18nc("@label:spinbox", "Enter number of columns"),
- defaultNumberOfColumnsToRemove(),
- 1, 10000, 1, &ok);
-
- if (ok) {
- setDefaultNumberOfColumnsToRemove(count);
- slotRemoveHoldColumns(count);
+ if (insertion) {
+ setDefaultNumberOfFramesToAdd(count);
+ insertOrRemoveHoldFrames(count, entireColumn);
+ } else {
+ setDefaultNumberOfFramesToRemove(count);
+ insertOrRemoveHoldFrames(-count, entireColumn);
+ }
}
}
-void TimelineFramesView::slotMirrorFrames(bool forceEntireColumn)
+void TimelineFramesView::slotMirrorFrames(bool entireColumn)
{
- const QModelIndexList indexes = calculateSelectionSpan(forceEntireColumn);
+ const QModelIndexList indexes = calculateSelectionSpan(entireColumn);
if (!indexes.isEmpty()) {
m_d->model->mirrorFrames(indexes);
}
}
-void TimelineFramesView::slotMirrorColumns()
+void TimelineFramesView::cutCopyImpl(bool entireColumn, bool copy)
{
- slotMirrorFrames(true);
-}
-
-void TimelineFramesView::cutCopyImpl(bool forceEntireColumn, bool copy)
-{
- const QModelIndexList indexes = calculateSelectionSpan(forceEntireColumn, !copy);
+ const QModelIndexList indexes = calculateSelectionSpan(entireColumn, !copy);
if (indexes.isEmpty()) return;
int minColumn = std::numeric_limits::max();
@@ -1613,20 +1463,10 @@
}
}
-void TimelineFramesView::slotCopyFrames(bool forceEntireColumn)
-{
- cutCopyImpl(forceEntireColumn, true);
-}
-
-void TimelineFramesView::slotCutFrames(bool forceEntireColumn)
-{
- cutCopyImpl(forceEntireColumn, false);
-}
-
-void TimelineFramesView::slotPasteFrames(bool forceEntireColumn)
+void TimelineFramesView::slotPasteFrames(bool entireColumn)
{
const QModelIndex currentIndex =
- !forceEntireColumn ? this->currentIndex() : m_d->model->index(0, this->currentIndex().column());
+ !entireColumn ? this->currentIndex() : m_d->model->index(0, this->currentIndex().column());
if (!currentIndex.isValid()) return;
@@ -1644,21 +1484,6 @@
}
}
-void TimelineFramesView::slotCutColumns()
-{
- slotCutFrames(true);
-}
-
-void TimelineFramesView::slotPasteColumns()
-{
- slotPasteFrames(true);
-}
-
-void TimelineFramesView::slotCopyColumns()
-{
- slotCopyFrames(true);
-}
-
int TimelineFramesView::defaultNumberOfFramesToAdd() const
{
KConfigGroup cfg = KSharedConfig::openConfig()->group("FrameActionsDefaultValues");
diff --git a/plugins/dockers/animation/timeline_insert_keyframe_dialog.h b/plugins/dockers/animation/timeline_insert_keyframe_dialog.h
--- a/plugins/dockers/animation/timeline_insert_keyframe_dialog.h
+++ b/plugins/dockers/animation/timeline_insert_keyframe_dialog.h
@@ -1,9 +1,31 @@
+/*
+ * Copyright (c) 2018 Emmet O'Neill
+ * Copyright (c) 2018 Eoin O'Neill
+ *
+ * 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 __TIMELINE_INSERT_KEYFRAME_DIALOG_H
#define __TIMELINE_INSERT_KEYFRAME_DIALOG_H
#include "kritaanimationdocker_export.h"
#include
#include
+#include
+
+enum TimelineDirection : short;
class KRITAANIMATIONDOCKER_EXPORT TimelineInsertKeyframeDialog : QDialog {
Q_OBJECT
@@ -11,10 +33,13 @@
QSpinBox frameCountSpinbox;
QSpinBox frameTimingSpinbox;
+ QRadioButton *leftBefore;
+ QRadioButton *rightAfter;
+
public:
TimelineInsertKeyframeDialog(QWidget *parent = 0);
- bool promptUserSettings(int &count, int &timing);
+ bool promptUserSettings(int &count, int &timing, TimelineDirection &out_direction);
};
#endif // __TIMELINE_INSERT_KEYFRAME_DIALOG_H
diff --git a/plugins/dockers/animation/timeline_insert_keyframe_dialog.cpp b/plugins/dockers/animation/timeline_insert_keyframe_dialog.cpp
--- a/plugins/dockers/animation/timeline_insert_keyframe_dialog.cpp
+++ b/plugins/dockers/animation/timeline_insert_keyframe_dialog.cpp
@@ -1,7 +1,29 @@
+/*
+ * Copyright (c) 2018 Emmet O'Neill
+ * Copyright (c) 2018 Eoin O'Neill
+ *
+ * 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 "timeline_insert_keyframe_dialog.h"
+#include "timeline_frames_view.h"
#include
+#include
#include
+#include
#include
#include
#include
@@ -14,31 +36,58 @@
setModal(true);
setLayout(new QVBoxLayout(this));
- frameCountSpinbox.setMinimum(1);
- frameCountSpinbox.setValue(1);
+ { // Count and Spacing Forms.
+ QWidget *forms = new QWidget(this);
+ layout()->addWidget(forms);
+
+ frameCountSpinbox.setMinimum(1);
+ frameCountSpinbox.setValue(1);
+
+ frameTimingSpinbox.setMinimum(1);
+ frameTimingSpinbox.setValue(1);
+
+ QFormLayout *LO = new QFormLayout(this);
+ forms->setLayout(LO);
+
+ LO->addRow(QString(i18nc("@label:spinbox", "Number of frames:")), &frameCountSpinbox);
+ LO->addRow(QString(i18nc("@label:spinbox", "Frame timing:")), &frameTimingSpinbox);
+ }
+
+ { // Side Buttons.
+ QGroupBox *sideRadioButtons = new QGroupBox(i18nc("@label:group","Side:"), this);
+ layout()->addWidget(sideRadioButtons);
- frameTimingSpinbox.setMinimum(1);
- frameTimingSpinbox.setValue(1);
+ leftBefore = new QRadioButton(i18nc("@label:radio", "Left / Before"), sideRadioButtons);
+ rightAfter = new QRadioButton(i18nc("@label:radio", "Right / After"), sideRadioButtons);
+ leftBefore->setChecked(true);
- QWidget *formsWidget = new QWidget();
- QFormLayout *formLayout = new QFormLayout();
- formsWidget->setLayout( formLayout );
- layout()->addWidget(formsWidget);
+ QVBoxLayout *LO = new QVBoxLayout(this);
+ sideRadioButtons->setLayout(LO);
- QDialogButtonBox *buttonbox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
- layout()->addWidget(buttonbox);
+ LO->addWidget(leftBefore);
+ LO->addWidget(rightAfter);
+ }
- formLayout->addRow(QString(i18nc("@label:spinbox", "Number of frames:")), &frameCountSpinbox);
- formLayout->addRow(QString(i18nc("@label:spinbox", "Frame timing:")), &frameTimingSpinbox);
+ { // Cancel / OK Buttons.
+ QDialogButtonBox *buttonbox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
+ layout()->addWidget(buttonbox);
- connect(buttonbox, SIGNAL(accepted()), this, SLOT(accept()));
- connect(buttonbox, SIGNAL(rejected()), this, SLOT(reject()));
+ connect(buttonbox, SIGNAL(accepted()), this, SLOT(accept()));
+ connect(buttonbox, SIGNAL(rejected()), this, SLOT(reject()));
+ }
}
-bool TimelineInsertKeyframeDialog::promptUserSettings(int &out_count, int &out_timing){
- if(exec() == QDialog::Accepted){
+bool TimelineInsertKeyframeDialog::promptUserSettings(int &out_count, int &out_timing, TimelineDirection &out_direction)
+{
+ if (exec() == QDialog::Accepted) {
out_count = frameCountSpinbox.value();
out_timing = frameTimingSpinbox.value();
+
+ out_direction = TimelineDirection::LEFT; // Default
+ if (rightAfter && rightAfter->isChecked()) {
+ out_direction = TimelineDirection::RIGHT;
+ }
+
return true;
}
return false;
diff --git a/plugins/dockers/animation/timeline_ruler_header.h b/plugins/dockers/animation/timeline_ruler_header.h
--- a/plugins/dockers/animation/timeline_ruler_header.h
+++ b/plugins/dockers/animation/timeline_ruler_header.h
@@ -37,7 +37,7 @@
void setModel(QAbstractItemModel *model) override;
- void setActionManager( KisActionManager * actionManager);
+ void setActionManager(KisActionManager *actionManager);
protected:
void mousePressEvent(QMouseEvent *e) override;
@@ -61,10 +61,10 @@
const QPen &gridPen) const;
Q_SIGNALS:
- void sigInsertColumnsLeft();
- void sigInsertColumnsRight();
- void sigInsertColumnsLeftCustom();
- void sigInsertColumnsRightCustom();
+ void sigInsertColumnLeft();
+ void sigInsertColumnRight();
+ void sigInsertMultipleColumns();
+
void sigRemoveColumns();
void sigRemoveColumnsAndShift();
diff --git a/plugins/dockers/animation/timeline_ruler_header.cpp b/plugins/dockers/animation/timeline_ruler_header.cpp
--- a/plugins/dockers/animation/timeline_ruler_header.cpp
+++ b/plugins/dockers/animation/timeline_ruler_header.cpp
@@ -55,10 +55,6 @@
{
setSectionResizeMode(QHeaderView::Fixed);
setDefaultSectionSize(18);
-
-
-
-
}
TimelineRulerHeader::~TimelineRulerHeader()
@@ -66,24 +62,21 @@
}
-void TimelineRulerHeader::setActionManager( KisActionManager * actionManager)
+void TimelineRulerHeader::setActionManager(KisActionManager *actionManager)
{
m_d->actionMan = actionManager;
if (actionManager) {
KisAction *action;
- action = actionManager->createAction("insert_columns_right");
- connect(action, SIGNAL(triggered()), SIGNAL(sigInsertColumnsRight()));
-
- action = actionManager->createAction("insert_n_columns_right");
- connect(action, SIGNAL(triggered()), SIGNAL(sigInsertColumnsRightCustom()));
+ action = actionManager->createAction("insert_column_left");
+ connect(action, SIGNAL(triggered()), SIGNAL(sigInsertColumnLeft()));
- action = actionManager->createAction("insert_columns_left");
- connect(action, SIGNAL(triggered()), SIGNAL(sigInsertColumnsLeft()));
+ action = actionManager->createAction("insert_column_right");
+ connect(action, SIGNAL(triggered()), SIGNAL(sigInsertColumnRight()));
- action = actionManager->createAction("insert_n_columns_left");
- connect(action, SIGNAL(triggered()), SIGNAL(sigInsertColumnsLeftCustom()));
+ action = actionManager->createAction("insert_multiple_columns");
+ connect(action, SIGNAL(triggered()), SIGNAL(sigInsertMultipleColumns()));
action = actionManager->createAction("remove_columns_and_pull");
connect(action, SIGNAL(triggered()), SIGNAL(sigRemoveColumnsAndShift()));
@@ -94,13 +87,13 @@
action = actionManager->createAction("insert_hold_column");
connect(action, SIGNAL(triggered()), SIGNAL(sigInsertHoldColumns()));
- action = actionManager->createAction("insert_n_hold_columns");
+ action = actionManager->createAction("insert_multiple_hold_columns");
connect(action, SIGNAL(triggered()), SIGNAL(sigInsertHoldColumnsCustom()));
action = actionManager->createAction("remove_hold_column");
connect(action, SIGNAL(triggered()), SIGNAL(sigRemoveHoldColumns()));
- action = actionManager->createAction("remove_n_hold_columns");
+ action = actionManager->createAction("remove_multiple_hold_columns");
connect(action, SIGNAL(triggered()), SIGNAL(sigRemoveHoldColumnsCustom()));
action = actionManager->createAction("mirror_columns");
@@ -440,27 +433,31 @@
KisActionManager::safePopulateMenu(&menu, "cut_columns_to_clipboard", m_d->actionMan);
KisActionManager::safePopulateMenu(&menu, "copy_columns_to_clipboard", m_d->actionMan);
KisActionManager::safePopulateMenu(&menu, "paste_columns_from_clipboard", m_d->actionMan);
- menu.addSeparator();
- QMenu *frames = menu.addMenu(i18nc("@item:inmenu", "Keyframe Columns"));
- KisActionManager::safePopulateMenu(frames, "insert_columns_right", m_d->actionMan);
- KisActionManager::safePopulateMenu(frames, "insert_columns_left", m_d->actionMan);
menu.addSeparator();
- KisActionManager::safePopulateMenu(frames, "insert_n_columns_right", m_d->actionMan);
- KisActionManager::safePopulateMenu(frames, "insert_n_columns_left", m_d->actionMan);
- QMenu *hold = menu.addMenu(i18nc("@item:inmenu", "Hold Frame Columns"));
- KisActionManager::safePopulateMenu(hold, "insert_hold_column", m_d->actionMan);
- KisActionManager::safePopulateMenu(hold, "remove_hold_column", m_d->actionMan);
- menu.addSeparator();
- KisActionManager::safePopulateMenu(hold, "insert_n_hold_columns", m_d->actionMan);
- KisActionManager::safePopulateMenu(hold, "remove_n_hold_columns", m_d->actionMan);
+ { //Frame Columns Submenu
+ QMenu *frames = menu.addMenu(i18nc("@item:inmenu", "Keyframe Columns"));
+ KisActionManager::safePopulateMenu(frames, "insert_column_left", m_d->actionMan);
+ KisActionManager::safePopulateMenu(frames, "insert_column_right", m_d->actionMan);
+ frames->addSeparator();
+ KisActionManager::safePopulateMenu(frames, "insert_multiple_columns", m_d->actionMan);
+ }
+
+ { //Hold Columns Submenu
+ QMenu *hold = menu.addMenu(i18nc("@item:inmenu", "Hold Frame Columns"));
+ KisActionManager::safePopulateMenu(hold, "insert_hold_column", m_d->actionMan);
+ KisActionManager::safePopulateMenu(hold, "remove_hold_column", m_d->actionMan);
+ hold->addSeparator();
+ KisActionManager::safePopulateMenu(hold, "insert_multiple_hold_columns", m_d->actionMan);
+ KisActionManager::safePopulateMenu(hold, "remove_multiple_hold_columns", m_d->actionMan);
+ }
menu.addSeparator();
+
KisActionManager::safePopulateMenu(&menu, "remove_columns", m_d->actionMan);
KisActionManager::safePopulateMenu(&menu, "remove_columns_and_pull", m_d->actionMan);
-
if (numSelectedColumns > 1) {
menu.addSeparator();
KisActionManager::safePopulateMenu(&menu, "mirror_columns", m_d->actionMan);