Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_nla/nla_channels.c')
-rw-r--r--source/blender/editors/space_nla/nla_channels.c206
1 files changed, 103 insertions, 103 deletions
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index 9b7a49ec624..d782fe4d7ef 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -80,26 +80,26 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
View2D *v2d = &ac->ar->v2d;
int notifierFlags = 0;
-
+
/* get the channel that was clicked on */
/* filter channels */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* get channel from index */
ale = BLI_findlink(&anim_data, channel_index);
if (ale == NULL) {
/* channel not found */
if (G.debug & G_DEBUG)
printf("Error: animation channel (index = %d) not found in mouse_anim_channels()\n", channel_index);
-
+
ANIM_animdata_freelist(&anim_data);
return 0;
}
-
+
/* action to take depends on what channel we've got */
// WARNING: must keep this in sync with the equivalent function in anim_channels_edit.c
switch (ale->type) {
@@ -107,7 +107,7 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
{
Scene *sce = (Scene *)ale->data;
AnimData *adt = sce->adt;
-
+
/* set selection status */
if (selectmode == SELECT_INVERT) {
/* swap select */
@@ -118,7 +118,7 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
sce->flag |= SCE_DS_SELECTED;
if (adt) adt->flag |= ADT_UI_SELECTED;
}
-
+
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
break;
}
@@ -128,14 +128,14 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
Base *base = (Base *)ale->data;
Object *ob = base->object;
AnimData *adt = ob->adt;
-
+
if (nlaedit_is_tweakmode_on(ac) == 0 && (base->flag & BASE_SELECTABLED)) {
/* set selection status */
if (selectmode == SELECT_INVERT) {
/* swap select */
ED_object_base_select(base, BA_INVERT);
BKE_scene_object_base_flag_sync_from_base(base);
-
+
if (adt) adt->flag ^= ADT_UI_SELECTED;
}
else {
@@ -146,19 +146,19 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
BKE_scene_object_base_flag_sync_from_base(b);
if (b->object->adt) b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE);
}
-
+
/* select object now */
ED_object_base_select(base, BA_SELECT);
BKE_scene_object_base_flag_sync_from_base(base);
if (adt) adt->flag |= ADT_UI_SELECTED;
}
-
+
/* change active object - regardless of whether it is now selected [T37883] */
ED_object_base_activate(C, base); /* adds notifier */
-
+
if ((adt) && (adt->flag & ADT_UI_SELECTED))
adt->flag |= ADT_UI_ACTIVE;
-
+
/* notifiers - channel was selected */
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
}
@@ -195,12 +195,12 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
ale->adt->flag |= ADT_UI_SELECTED;
}
-
+
/* set active? */
if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
ale->adt->flag |= ADT_UI_ACTIVE;
}
-
+
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
break;
}
@@ -209,7 +209,7 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
NlaTrack *nlt = (NlaTrack *)ale->data;
AnimData *adt = ale->adt;
short offset;
-
+
/* offset for start of channel (on LHS of channel-list) */
if (ale->id) {
/* special exception for materials and particles */
@@ -220,25 +220,25 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
}
else
offset = 0;
-
+
if (x >= (v2d->cur.xmax - NLACHANNEL_BUTTON_WIDTH)) {
/* toggle protection (only if there's a toggle there) */
nlt->flag ^= NLATRACK_PROTECTED;
-
+
/* notifier flags - channel was edited */
notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
}
else if (x >= (v2d->cur.xmax - 2 * NLACHANNEL_BUTTON_WIDTH)) {
/* toggle mute */
nlt->flag ^= NLATRACK_MUTED;
-
+
/* notifier flags - channel was edited */
notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
}
else if (x <= ((NLACHANNEL_BUTTON_WIDTH * 2) + offset)) {
/* toggle 'solo' */
BKE_nlatrack_solo_toggle(adt, nlt);
-
+
/* notifier flags - channel was edited */
notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
}
@@ -253,11 +253,11 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
nlt->flag |= NLATRACK_SELECTED;
}
-
+
/* if NLA-Track is selected now, make NLA-Track the 'active' one in the visible list */
if (nlt->flag & NLATRACK_SELECTED)
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nlt, ANIMTYPE_NLATRACK);
-
+
/* notifier flags - channel was selected */
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
}
@@ -266,7 +266,7 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
case ANIMTYPE_NLAACTION:
{
AnimData *adt = BKE_animdata_from_id(ale->id);
-
+
/* button region... */
if (x >= (v2d->cur.xmax - NLACHANNEL_BUTTON_WIDTH)) {
if (nlaedit_is_tweakmode_on(ac) == 0) {
@@ -279,13 +279,13 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
/* when in tweakmode, this button becomes the toggle for mapped editing */
adt->flag ^= ADT_NLA_EDIT_NOMAP;
}
-
+
/* changes to NLA-Action occurred */
notifierFlags |= ND_NLA_ACTCHANGE;
}
/* OR rest of name... */
else {
- /* NOTE: rest of NLA-Action name doubles for operating on the AnimData block
+ /* NOTE: rest of NLA-Action name doubles for operating on the AnimData block
* - this is useful when there's no clear divider, and makes more sense in
* the case of users trying to use this to change actions
* - in tweakmode, clicking here gets us out of tweakmode, as changing selection
@@ -296,7 +296,7 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
if (nlaedit_is_tweakmode_on(ac)) {
/* exit tweakmode immediately */
nlaedit_disable_tweakmode(ac, true);
-
+
/* changes to NLA-Action occurred */
notifierFlags |= ND_NLA_ACTCHANGE;
}
@@ -311,11 +311,11 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
adt->flag |= ADT_UI_SELECTED;
}
-
+
/* set active? */
if (adt->flag & ADT_UI_SELECTED)
adt->flag |= ADT_UI_ACTIVE;
-
+
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
}
}
@@ -326,10 +326,10 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
printf("Error: Invalid channel type in mouse_nla_channels()\n");
break;
}
-
+
/* free channels */
ANIM_animdata_freelist(&anim_data);
-
+
/* return the notifier-flags set */
return notifierFlags;
}
@@ -347,55 +347,55 @@ static int nlachannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmEv
int notifierFlags = 0;
short selectmode;
float x, y;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get useful pointers from animation context data */
snla = (SpaceNla *)ac.sl;
ar = ac.ar;
v2d = &ar->v2d;
-
+
/* select mode is either replace (deselect all, then add) or add/extend */
if (RNA_boolean_get(op->ptr, "extend"))
selectmode = SELECT_INVERT;
else
selectmode = SELECT_REPLACE;
-
- /* figure out which channel user clicked in
+
+ /* figure out which channel user clicked in
* Note: although channels technically start at y= NLACHANNEL_FIRST, we need to adjust by half a channel's height
* so that the tops of channels get caught ok. Since NLACHANNEL_FIRST is really NLACHANNEL_HEIGHT, we simply use
* NLACHANNEL_HEIGHT_HALF.
*/
UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y);
UI_view2d_listview_view_to_cell(v2d, NLACHANNEL_NAMEWIDTH, NLACHANNEL_STEP(snla), 0, (float)NLACHANNEL_HEIGHT_HALF(snla), x, y, NULL, &channel_index);
-
+
/* handle mouse-click in the relevant channel then */
notifierFlags = mouse_nla_channels(C, &ac, x, channel_index, selectmode);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | notifierFlags, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void NLA_OT_channels_click(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Mouse Click on NLA Channels";
ot->idname = "NLA_OT_channels_click";
ot->description = "Handle clicks to select NLA channels";
-
+
/* api callbacks */
ot->invoke = nlachannels_mouseclick_invoke;
ot->poll = ED_operator_nla_active;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
-
+
/* props */
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
@@ -411,15 +411,15 @@ static int nlachannels_pushdown_exec(bContext *C, wmOperator *op)
bAnimContext ac;
AnimData *adt = NULL;
int channel_index = RNA_int_get(op->ptr, "channel_index");
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get anim-channel to use (or more specifically, the animdata block behind it) */
if (channel_index == -1) {
PointerRNA adt_ptr = {{NULL}};
-
+
/* active animdata block */
if (nla_panel_context(C, &adt_ptr, NULL, NULL) == 0 || (adt_ptr.data == NULL)) {
BKE_report(op->reports, RPT_ERROR, "No active AnimData block to use "
@@ -435,11 +435,11 @@ static int nlachannels_pushdown_exec(bContext *C, wmOperator *op)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* filter channels */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* get channel from index */
ale = BLI_findlink(&anim_data, channel_index);
if (ale == NULL) {
@@ -452,14 +452,14 @@ static int nlachannels_pushdown_exec(bContext *C, wmOperator *op)
ANIM_animdata_freelist(&anim_data);
return OPERATOR_CANCELLED;
}
-
+
/* grab AnimData from the channel */
adt = ale->adt;
-
+
/* we don't need anything here anymore, so free it all */
ANIM_animdata_freelist(&anim_data);
}
-
+
/* double-check that we are free to push down here... */
if (adt == NULL) {
BKE_report(op->reports, RPT_WARNING, "Internal Error - AnimData block is not valid");
@@ -478,7 +478,7 @@ static int nlachannels_pushdown_exec(bContext *C, wmOperator *op)
/* 'push-down' action - only usable when not in TweakMode */
BKE_nla_action_pushdown(adt);
}
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
return OPERATOR_FINISHED;
@@ -490,14 +490,14 @@ void NLA_OT_action_pushdown(wmOperatorType *ot)
ot->name = "Push Down Action";
ot->idname = "NLA_OT_action_pushdown";
ot->description = "Push action down onto the top of the NLA stack as a new strip";
-
+
/* callbacks */
ot->exec = nlachannels_pushdown_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_int(ot->srna, "channel_index", -1, -1, INT_MAX, "Channel Index",
"Index of NLA action channel to perform pushdown operation on",
@@ -512,7 +512,7 @@ static int nla_action_unlink_poll(bContext *C)
if (ED_operator_nla_active(C)) {
return nla_panel_context(C, NULL, NULL, NULL);
}
-
+
/* something failed... */
return false;
}
@@ -521,22 +521,22 @@ static int nla_action_unlink_exec(bContext *C, wmOperator *op)
{
PointerRNA adt_ptr;
AnimData *adt;
-
+
/* check context and also validity of pointer */
if (!nla_panel_context(C, &adt_ptr, NULL, NULL))
return OPERATOR_CANCELLED;
-
+
/* get animdata */
adt = adt_ptr.data;
if (adt == NULL)
return OPERATOR_CANCELLED;
-
+
/* do unlinking */
if (adt && adt->action) {
bool force_delete = RNA_boolean_get(op->ptr, "force_delete");
ED_animedit_unlink_action(C, adt_ptr.id.data, adt, adt->action, op->reports, force_delete);
}
-
+
return OPERATOR_FINISHED;
}
@@ -550,19 +550,19 @@ static int nla_action_unlink_invoke(bContext *C, wmOperator *op, const wmEvent *
void NLA_OT_action_unlink(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Unlink Action";
ot->idname = "NLA_OT_action_unlink";
ot->description = "Unlink this action from the active action slot (and/or exit Tweak Mode)";
-
+
/* callbacks */
ot->invoke = nla_action_unlink_invoke;
ot->exec = nla_action_unlink_exec;
ot->poll = nla_action_unlink_poll;
-
+
/* properties */
- prop = RNA_def_boolean(ot->srna, "force_delete", false, "Force Delete",
+ prop = RNA_def_boolean(ot->srna, "force_delete", false, "Force Delete",
"Clear Fake User and remove copy stashed in this datablock's NLA stack");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
@@ -578,17 +578,17 @@ bool nlaedit_add_tracks_existing(bAnimContext *ac, bool above_sel)
int filter;
AnimData *lastAdt = NULL;
bool added = false;
-
+
/* get a list of the (selected) NLA Tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* add tracks... */
for (ale = anim_data.first; ale; ale = ale->next) {
if (ale->type == ANIMTYPE_NLATRACK) {
NlaTrack *nlt = (NlaTrack *)ale->data;
AnimData *adt = ale->adt;
-
+
/* check if just adding a new track above this one,
* or whether we're adding a new one to the top of the stack that this one belongs to
*/
@@ -605,10 +605,10 @@ bool nlaedit_add_tracks_existing(bAnimContext *ac, bool above_sel)
}
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
return added;
}
@@ -619,18 +619,18 @@ bool nlaedit_add_tracks_empty(bAnimContext *ac)
bAnimListElem *ale;
int filter;
bool added = false;
-
+
/* get a list of the selected AnimData blocks in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* check if selected AnimData blocks are empty, and add tracks if so... */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ale->adt;
-
+
/* sanity check */
BLI_assert(adt->flag & ADT_UI_SELECTED);
-
+
/* ensure it is empty */
if (BLI_listbase_is_empty(&adt->nla_tracks)) {
/* add new track to this AnimData block then */
@@ -638,10 +638,10 @@ bool nlaedit_add_tracks_empty(bAnimContext *ac)
added = true;
}
}
-
+
/* cleanup */
ANIM_animdata_freelist(&anim_data);
-
+
return added;
}
@@ -652,20 +652,20 @@ static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
bAnimContext ac;
bool above_sel = RNA_boolean_get(op->ptr, "above_selected");
bool op_done = false;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* perform adding in two passes - existing first so that we don't double up for empty */
op_done |= nlaedit_add_tracks_existing(&ac, above_sel);
op_done |= nlaedit_add_tracks_empty(&ac);
-
+
/* done? */
if (op_done) {
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -673,7 +673,7 @@ static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
/* failed to add any tracks */
BKE_report(op->reports, RPT_WARNING,
"Select an existing NLA Track or an empty action line first");
-
+
/* not done */
return OPERATOR_CANCELLED;
}
@@ -685,14 +685,14 @@ void NLA_OT_tracks_add(wmOperatorType *ot)
ot->name = "Add Tracks";
ot->idname = "NLA_OT_tracks_add";
ot->description = "Add NLA-Tracks above/after the selected tracks";
-
+
/* api callbacks */
ot->exec = nlaedit_add_tracks_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "above_selected", 0, "Above Selected", "Add a new NLA Track above every existing selected one");
}
@@ -703,42 +703,42 @@ void NLA_OT_tracks_add(wmOperatorType *ot)
static int nlaedit_delete_tracks_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the AnimData blocks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* delete tracks */
for (ale = anim_data.first; ale; ale = ale->next) {
if (ale->type == ANIMTYPE_NLATRACK) {
NlaTrack *nlt = (NlaTrack *)ale->data;
AnimData *adt = ale->adt;
-
+
/* if track is currently 'solo', then AnimData should have its
* 'has solo' flag disabled
*/
if (nlt->flag & NLATRACK_SOLO)
adt->flag &= ~ADT_NLA_SOLO_TRACK;
-
+
/* call delete on this track - deletes all strips too */
BKE_nlatrack_free(&adt->nla_tracks, nlt);
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -749,11 +749,11 @@ void NLA_OT_tracks_delete(wmOperatorType *ot)
ot->name = "Delete Tracks";
ot->idname = "NLA_OT_tracks_delete";
ot->description = "Delete selected NLA-Tracks and the strips they contain";
-
+
/* api callbacks */
ot->exec = nlaedit_delete_tracks_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -762,7 +762,7 @@ void NLA_OT_tracks_delete(wmOperatorType *ot)
/* AnimData Related Operators */
/* ******************** Include Objects Operator ***************************** */
-/* Include selected objects in NLA Editor, by giving them AnimData blocks
+/* Include selected objects in NLA Editor, by giving them AnimData blocks
* NOTE: This doesn't help for non-object AnimData, where we do not have any effective
* selection mechanism in place. Unfortunately, this means that non-object AnimData
* once again becomes a second-class citizen here. However, at least for the most
@@ -773,28 +773,28 @@ static int nlaedit_objects_add_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
SpaceNla *snla;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* ensure that filters are set so that the effect will be immediately visible */
snla = (SpaceNla *)ac.sl;
if (snla && snla->ads) {
snla->ads->filterflag &= ~ADS_FILTER_NLA_NOACT;
}
-
- /* operate on selected objects... */
+
+ /* operate on selected objects... */
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
/* ensure that object has AnimData... that's all */
BKE_animdata_add_id(&ob->id);
}
CTX_DATA_END;
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -805,11 +805,11 @@ void NLA_OT_selected_objects_add(wmOperatorType *ot)
ot->name = "Include Selected Objects";
ot->idname = "NLA_OT_selected_objects_add";
ot->description = "Make selected objects appear in NLA Editor by adding Animation Data";
-
+
/* api callbacks */
ot->exec = nlaedit_objects_add_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}