Merge pull request #456 from and3md/actions

Action improvements fixes #454
This commit is contained in:
Vadim Lopatin 2017-09-25 10:39:24 +03:00 committed by GitHub
commit 2d30f44752
9 changed files with 638 additions and 558 deletions

View File

@ -26,6 +26,20 @@ private import std.string;
private import std.conv; private import std.conv;
private import std.utf : toUTF32; private import std.utf : toUTF32;
/// Define when action need state update - optimization for high frequently uses actions
enum ActionStateUpdateFlag : uint {
/// action never change state so there is no need to search for dispatch action state request
never = 0,
/// dispatch action state change if action added to widget
inWidget = 1,
/// dispatch action state change if run from accelerator (keyboard)
inAccelerator = 2,
/// always dispatch action state change
always = inWidget | inAccelerator
}
/// Keyboard accelerator (key + modifiers) /// Keyboard accelerator (key + modifiers)
struct Accelerator { struct Accelerator {
/// Key code, usually one of KeyCode enum items /// Key code, usually one of KeyCode enum items
@ -301,6 +315,8 @@ class Action {
protected ActionState _defaultState = ACTION_STATE_ENABLED; protected ActionState _defaultState = ACTION_STATE_ENABLED;
protected uint _stateUpdateFlag = ActionStateUpdateFlag.always;
/// set default state to disabled, visible, not-checked /// set default state to disabled, visible, not-checked
Action disableByDefault() { _defaultState = ACTION_STATE_DISABLE; return this; } Action disableByDefault() { _defaultState = ACTION_STATE_DISABLE; return this; }
/// set default state to disabled, invisible, not-checked /// set default state to disabled, invisible, not-checked
@ -327,6 +343,15 @@ class Action {
return this; return this;
} }
/// return action state update flag (see ActionStateUpdateFlag for details)
@property uint stateUpdateFlag() const { return _stateUpdateFlag; }
/// sets action state update flag (see ActionStateUpdateFlag for details)
@property Action stateUpdateFlag(uint newStateUpdateFlag) {
_stateUpdateFlag = newStateUpdateFlag;
return this;
}
/// returns optional string parameter /// returns optional string parameter
@property string stringParam() const { @property string stringParam() const {
return _stringParam; return _stringParam;
@ -358,6 +383,7 @@ class Action {
_objectParam = v; _objectParam = v;
return this; return this;
} }
/// deep copy constructor /// deep copy constructor
this(immutable Action a) { this(immutable Action a) {
_id = a._id; _id = a._id;
@ -368,6 +394,7 @@ class Action {
_accelerators = a._accelerators.dup; _accelerators = a._accelerators.dup;
_stringParam = a._stringParam; _stringParam = a._stringParam;
_longParam = a._longParam; _longParam = a._longParam;
_stateUpdateFlag = a._stateUpdateFlag;
if (a._objectParam) if (a._objectParam)
_objectParam = cast(Object)a._objectParam; _objectParam = cast(Object)a._objectParam;
} }
@ -382,7 +409,8 @@ class Action {
_id = id; _id = id;
} }
/// create action with id, labelResourceId, and optional icon and key accelerator. /// create action with id, labelResourceId, and optional icon and key accelerator.
this(int id, string labelResourceId, string iconResourceId = null, uint keyCode = 0, uint keyFlags = 0) { this(int id, string labelResourceId, string iconResourceId = null, uint keyCode = 0, uint keyFlags = 0,
uint stateUpdateFlag = ActionStateUpdateFlag.always ) {
_id = id; _id = id;
_label.id = labelResourceId; _label.id = labelResourceId;
_iconId = iconResourceId; _iconId = iconResourceId;
@ -394,9 +422,10 @@ class Action {
} }
_accelerators ~= Accelerator(keyCode, keyFlags); _accelerators ~= Accelerator(keyCode, keyFlags);
} }
_stateUpdateFlag = stateUpdateFlag;
} }
/// action with accelerator, w/o label /// action with accelerator, w/o label
this(int id, uint keyCode, uint keyFlags = 0) { this(int id, uint keyCode, uint keyFlags = 0, uint stateUpdateFlag = ActionStateUpdateFlag.always) {
_id = id; _id = id;
version (OSX) { version (OSX) {
if (keyFlags & KeyFlag.Control) { if (keyFlags & KeyFlag.Control) {
@ -404,9 +433,11 @@ class Action {
} }
} }
_accelerators ~= Accelerator(keyCode, keyFlags); _accelerators ~= Accelerator(keyCode, keyFlags);
_stateUpdateFlag = stateUpdateFlag;
} }
/// action with label, icon, and accelerator /// action with label, icon, and accelerator
this(int id, dstring label, string iconResourceId = null, uint keyCode = 0, uint keyFlags = 0) { this(int id, dstring label, string iconResourceId = null, uint keyCode = 0, uint keyFlags = 0,
uint stateUpdateFlag = ActionStateUpdateFlag.always) {
_id = id; _id = id;
_label.value = label; _label.value = label;
_iconId = iconResourceId; _iconId = iconResourceId;
@ -418,6 +449,7 @@ class Action {
} }
_accelerators ~= Accelerator(keyCode, keyFlags); _accelerators ~= Accelerator(keyCode, keyFlags);
} }
_stateUpdateFlag = stateUpdateFlag;
} }
/// returs array of accelerators /// returs array of accelerators
@property Accelerator[] accelerators() { @property Accelerator[] accelerators() {
@ -613,6 +645,18 @@ struct ActionMap {
} }
return null; return null;
} }
int opApply(int delegate(ref Action) op) {
int result = 0;
foreach (ref Accelerator acc; _map.byKey) {
result = op(_map[acc]);
if (result)
break;
}
return result;
}
} }
/// List of Actions, for looking up Action by key /// List of Actions, for looking up Action by key

File diff suppressed because it is too large Load Diff

View File

@ -1823,6 +1823,8 @@ class Platform {
* When returned from this method, application is shutting down. * When returned from this method, application is shutting down.
*/ */
abstract int enterMessageLoop(); abstract int enterMessageLoop();
/// check has clipboard text
abstract bool hasClipboardText(bool mouseBuffer = false);
/// retrieves text from clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux) /// retrieves text from clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux)
abstract dstring getClipboardText(bool mouseBuffer = false); abstract dstring getClipboardText(bool mouseBuffer = false);
/// sets text to clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux) /// sets text to clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux)

View File

@ -240,6 +240,12 @@ class ConsolePlatform : Platform {
return 0; return 0;
} }
private dstring _clipboardText; private dstring _clipboardText;
/// check has clipboard text
override bool hasClipboardText(bool mouseBuffer = false) {
return (_clipboardText.length > 0);
}
/// retrieves text from clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux) /// retrieves text from clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux)
override dstring getClipboardText(bool mouseBuffer = false) { override dstring getClipboardText(bool mouseBuffer = false) {
return _clipboardText; return _clipboardText;

View File

@ -1462,10 +1462,13 @@ class SDLPlatform : Platform {
return 0; return 0;
} }
/// check has clipboard text
override bool hasClipboardText(bool mouseBuffer = false) {
return (SDL_HasClipboardText() == SDL_TRUE);
}
/// retrieves text from clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux) /// retrieves text from clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux)
override dstring getClipboardText(bool mouseBuffer = false) { override dstring getClipboardText(bool mouseBuffer = false) {
if (!SDL_HasClipboardText())
return ""d;
char * txt = SDL_GetClipboardText(); char * txt = SDL_GetClipboardText();
if (!txt) if (!txt)
return ""d; return ""d;

View File

@ -1158,6 +1158,13 @@ class Win32Platform : Platform {
_windowsToDestroy.length = 0; _windowsToDestroy.length = 0;
} }
/// check has clipboard text
override bool hasClipboardText(bool mouseBuffer = false) {
if (mouseBuffer)
return false;
return (IsClipboardFormatAvailable(CF_UNICODETEXT) != 0);
}
/// retrieves text from clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux) /// retrieves text from clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux)
override dstring getClipboardText(bool mouseBuffer = false) { override dstring getClipboardText(bool mouseBuffer = false) {
dstring res = null; dstring res = null;

View File

@ -1633,6 +1633,11 @@ class X11Platform : Platform {
return 0; return 0;
} }
/// check has clipboard text
override bool hasClipboardText(bool mouseBuffer = false) {
return (localClipboardContent.length != 0);
}
/// retrieves text from clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux) /// retrieves text from clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux)
override dstring getClipboardText(bool mouseBuffer = false) { override dstring getClipboardText(bool mouseBuffer = false) {
return toUTF32(localClipboardContent); return toUTF32(localClipboardContent);

View File

@ -210,12 +210,12 @@ void initStandardEditorActions() {
registerActionEnum!EditorActions(); registerActionEnum!EditorActions();
} }
const Action ACTION_EDITOR_INSERT_NEW_LINE = (new Action(EditorActions.InsertNewLine, KeyCode.RETURN, 0)).addAccelerator(KeyCode.RETURN, KeyFlag.Shift); const Action ACTION_EDITOR_INSERT_NEW_LINE = (new Action(EditorActions.InsertNewLine, KeyCode.RETURN, 0, ActionStateUpdateFlag.never)).addAccelerator(KeyCode.RETURN, KeyFlag.Shift);
const Action ACTION_EDITOR_PREPEND_NEW_LINE = (new Action(EditorActions.PrependNewLine, KeyCode.RETURN, KeyFlag.Control|KeyFlag.Shift)); const Action ACTION_EDITOR_PREPEND_NEW_LINE = (new Action(EditorActions.PrependNewLine, KeyCode.RETURN, KeyFlag.Control | KeyFlag.Shift, ActionStateUpdateFlag.never));
const Action ACTION_EDITOR_APPEND_NEW_LINE = (new Action(EditorActions.AppendNewLine, KeyCode.RETURN, KeyFlag.Control)); const Action ACTION_EDITOR_APPEND_NEW_LINE = (new Action(EditorActions.AppendNewLine, KeyCode.RETURN, KeyFlag.Control, ActionStateUpdateFlag.never));
const Action ACTION_EDITOR_DELETE_LINE = (new Action(EditorActions.DeleteLine, KeyCode.KEY_D, KeyFlag.Control)).addAccelerator(KeyCode.KEY_L, KeyFlag.Control); const Action ACTION_EDITOR_DELETE_LINE = (new Action(EditorActions.DeleteLine, KeyCode.KEY_D, KeyFlag.Control, ActionStateUpdateFlag.never)).addAccelerator(KeyCode.KEY_L, KeyFlag.Control);
const Action ACTION_EDITOR_TOGGLE_REPLACE_MODE = (new Action(EditorActions.ToggleReplaceMode, KeyCode.INS, 0)); const Action ACTION_EDITOR_TOGGLE_REPLACE_MODE = (new Action(EditorActions.ToggleReplaceMode, KeyCode.INS, 0, ActionStateUpdateFlag.never));
const Action ACTION_EDITOR_SELECT_ALL = (new Action(EditorActions.SelectAll, KeyCode.KEY_A, KeyFlag.Control)); const Action ACTION_EDITOR_SELECT_ALL = (new Action(EditorActions.SelectAll, KeyCode.KEY_A, KeyFlag.Control, ActionStateUpdateFlag.never));
const Action ACTION_EDITOR_TOGGLE_LINE_COMMENT = (new Action(EditorActions.ToggleLineComment, KeyCode.KEY_DIVIDE, KeyFlag.Control)); const Action ACTION_EDITOR_TOGGLE_LINE_COMMENT = (new Action(EditorActions.ToggleLineComment, KeyCode.KEY_DIVIDE, KeyFlag.Control));
const Action ACTION_EDITOR_TOGGLE_BLOCK_COMMENT = (new Action(EditorActions.ToggleBlockComment, KeyCode.KEY_DIVIDE, KeyFlag.Control | KeyFlag.Shift)); const Action ACTION_EDITOR_TOGGLE_BLOCK_COMMENT = (new Action(EditorActions.ToggleBlockComment, KeyCode.KEY_DIVIDE, KeyFlag.Control | KeyFlag.Shift));
const Action ACTION_EDITOR_TOGGLE_BOOKMARK = (new Action(EditorActions.ToggleBookmark, "ACTION_EDITOR_TOGGLE_BOOKMARK"c, null, KeyCode.KEY_B, KeyFlag.Control | KeyFlag.Shift)); const Action ACTION_EDITOR_TOGGLE_BOOKMARK = (new Action(EditorActions.ToggleBookmark, "ACTION_EDITOR_TOGGLE_BOOKMARK"c, null, KeyCode.KEY_B, KeyFlag.Control | KeyFlag.Shift));
@ -534,64 +534,64 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
super(ID, hscrollbarMode, vscrollbarMode); super(ID, hscrollbarMode, vscrollbarMode);
focusable = true; focusable = true;
acceleratorMap.add( [ acceleratorMap.add( [
new Action(EditorActions.Up, KeyCode.UP, 0), new Action(EditorActions.Up, KeyCode.UP, 0, ActionStateUpdateFlag.never),
new Action(EditorActions.SelectUp, KeyCode.UP, KeyFlag.Shift), new Action(EditorActions.SelectUp, KeyCode.UP, KeyFlag.Shift, ActionStateUpdateFlag.never),
new Action(EditorActions.SelectUp, KeyCode.UP, KeyFlag.Control | KeyFlag.Shift), new Action(EditorActions.SelectUp, KeyCode.UP, KeyFlag.Control | KeyFlag.Shift, ActionStateUpdateFlag.never),
new Action(EditorActions.Down, KeyCode.DOWN, 0), new Action(EditorActions.Down, KeyCode.DOWN, 0, ActionStateUpdateFlag.never),
new Action(EditorActions.SelectDown, KeyCode.DOWN, KeyFlag.Shift), new Action(EditorActions.SelectDown, KeyCode.DOWN, KeyFlag.Shift, ActionStateUpdateFlag.never),
new Action(EditorActions.SelectDown, KeyCode.DOWN, KeyFlag.Control | KeyFlag.Shift), new Action(EditorActions.SelectDown, KeyCode.DOWN, KeyFlag.Control | KeyFlag.Shift, ActionStateUpdateFlag.never),
new Action(EditorActions.Left, KeyCode.LEFT, 0), new Action(EditorActions.Left, KeyCode.LEFT, 0, ActionStateUpdateFlag.never),
new Action(EditorActions.SelectLeft, KeyCode.LEFT, KeyFlag.Shift), new Action(EditorActions.SelectLeft, KeyCode.LEFT, KeyFlag.Shift, ActionStateUpdateFlag.never),
new Action(EditorActions.Right, KeyCode.RIGHT, 0), new Action(EditorActions.Right, KeyCode.RIGHT, 0, ActionStateUpdateFlag.never),
new Action(EditorActions.SelectRight, KeyCode.RIGHT, KeyFlag.Shift), new Action(EditorActions.SelectRight, KeyCode.RIGHT, KeyFlag.Shift, ActionStateUpdateFlag.never),
new Action(EditorActions.WordLeft, KeyCode.LEFT, KeyFlag.Control), new Action(EditorActions.WordLeft, KeyCode.LEFT, KeyFlag.Control, ActionStateUpdateFlag.never),
new Action(EditorActions.SelectWordLeft, KeyCode.LEFT, KeyFlag.Control | KeyFlag.Shift), new Action(EditorActions.SelectWordLeft, KeyCode.LEFT, KeyFlag.Control | KeyFlag.Shift, ActionStateUpdateFlag.never),
new Action(EditorActions.WordRight, KeyCode.RIGHT, KeyFlag.Control), new Action(EditorActions.WordRight, KeyCode.RIGHT, KeyFlag.Control, ActionStateUpdateFlag.never),
new Action(EditorActions.SelectWordRight, KeyCode.RIGHT, KeyFlag.Control | KeyFlag.Shift), new Action(EditorActions.SelectWordRight, KeyCode.RIGHT, KeyFlag.Control | KeyFlag.Shift, ActionStateUpdateFlag.never),
new Action(EditorActions.PageUp, KeyCode.PAGEUP, 0), new Action(EditorActions.PageUp, KeyCode.PAGEUP, 0, ActionStateUpdateFlag.never),
new Action(EditorActions.SelectPageUp, KeyCode.PAGEUP, KeyFlag.Shift), new Action(EditorActions.SelectPageUp, KeyCode.PAGEUP, KeyFlag.Shift, ActionStateUpdateFlag.never),
new Action(EditorActions.PageDown, KeyCode.PAGEDOWN, 0), new Action(EditorActions.PageDown, KeyCode.PAGEDOWN, 0, ActionStateUpdateFlag.never),
new Action(EditorActions.SelectPageDown, KeyCode.PAGEDOWN, KeyFlag.Shift), new Action(EditorActions.SelectPageDown, KeyCode.PAGEDOWN, KeyFlag.Shift, ActionStateUpdateFlag.never),
new Action(EditorActions.PageBegin, KeyCode.PAGEUP, KeyFlag.Control), new Action(EditorActions.PageBegin, KeyCode.PAGEUP, KeyFlag.Control, ActionStateUpdateFlag.never),
new Action(EditorActions.SelectPageBegin, KeyCode.PAGEUP, KeyFlag.Control | KeyFlag.Shift), new Action(EditorActions.SelectPageBegin, KeyCode.PAGEUP, KeyFlag.Control | KeyFlag.Shift, ActionStateUpdateFlag.never),
new Action(EditorActions.PageEnd, KeyCode.PAGEDOWN, KeyFlag.Control), new Action(EditorActions.PageEnd, KeyCode.PAGEDOWN, KeyFlag.Control, ActionStateUpdateFlag.never),
new Action(EditorActions.SelectPageEnd, KeyCode.PAGEDOWN, KeyFlag.Control | KeyFlag.Shift), new Action(EditorActions.SelectPageEnd, KeyCode.PAGEDOWN, KeyFlag.Control | KeyFlag.Shift, ActionStateUpdateFlag.never),
new Action(EditorActions.LineBegin, KeyCode.HOME, 0), new Action(EditorActions.LineBegin, KeyCode.HOME, 0, ActionStateUpdateFlag.never),
new Action(EditorActions.SelectLineBegin, KeyCode.HOME, KeyFlag.Shift), new Action(EditorActions.SelectLineBegin, KeyCode.HOME, KeyFlag.Shift, ActionStateUpdateFlag.never),
new Action(EditorActions.LineEnd, KeyCode.END, 0), new Action(EditorActions.LineEnd, KeyCode.END, 0, ActionStateUpdateFlag.never),
new Action(EditorActions.SelectLineEnd, KeyCode.END, KeyFlag.Shift), new Action(EditorActions.SelectLineEnd, KeyCode.END, KeyFlag.Shift, ActionStateUpdateFlag.never),
new Action(EditorActions.DocumentBegin, KeyCode.HOME, KeyFlag.Control), new Action(EditorActions.DocumentBegin, KeyCode.HOME, KeyFlag.Control, ActionStateUpdateFlag.never),
new Action(EditorActions.SelectDocumentBegin, KeyCode.HOME, KeyFlag.Control | KeyFlag.Shift), new Action(EditorActions.SelectDocumentBegin, KeyCode.HOME, KeyFlag.Control | KeyFlag.Shift, ActionStateUpdateFlag.never),
new Action(EditorActions.DocumentEnd, KeyCode.END, KeyFlag.Control), new Action(EditorActions.DocumentEnd, KeyCode.END, KeyFlag.Control, ActionStateUpdateFlag.never),
new Action(EditorActions.SelectDocumentEnd, KeyCode.END, KeyFlag.Control | KeyFlag.Shift), new Action(EditorActions.SelectDocumentEnd, KeyCode.END, KeyFlag.Control | KeyFlag.Shift, ActionStateUpdateFlag.never),
new Action(EditorActions.ScrollLineUp, KeyCode.UP, KeyFlag.Control), new Action(EditorActions.ScrollLineUp, KeyCode.UP, KeyFlag.Control, ActionStateUpdateFlag.never),
new Action(EditorActions.ScrollLineDown, KeyCode.DOWN, KeyFlag.Control), new Action(EditorActions.ScrollLineDown, KeyCode.DOWN, KeyFlag.Control, ActionStateUpdateFlag.never),
// Backspace/Del // Backspace/Del
new Action(EditorActions.DelPrevChar, KeyCode.BACK, 0), new Action(EditorActions.DelPrevChar, KeyCode.BACK, 0, ActionStateUpdateFlag.never),
new Action(EditorActions.DelNextChar, KeyCode.DEL, 0), new Action(EditorActions.DelNextChar, KeyCode.DEL, 0, ActionStateUpdateFlag.never),
new Action(EditorActions.DelPrevWord, KeyCode.BACK, KeyFlag.Control), new Action(EditorActions.DelPrevWord, KeyCode.BACK, KeyFlag.Control, ActionStateUpdateFlag.never),
new Action(EditorActions.DelNextWord, KeyCode.DEL, KeyFlag.Control), new Action(EditorActions.DelNextWord, KeyCode.DEL, KeyFlag.Control, ActionStateUpdateFlag.never),
// Copy/Paste // Copy/Paste
new Action(EditorActions.Copy, KeyCode.KEY_C, KeyFlag.Control), new Action(EditorActions.Copy, KeyCode.KEY_C, KeyFlag.Control),
new Action(EditorActions.Copy, KeyCode.KEY_C, KeyFlag.Control|KeyFlag.Shift), new Action(EditorActions.Copy, KeyCode.KEY_C, KeyFlag.Control | KeyFlag.Shift),
new Action(EditorActions.Copy, KeyCode.INS, KeyFlag.Control), new Action(EditorActions.Copy, KeyCode.INS, KeyFlag.Control),
new Action(EditorActions.Cut, KeyCode.KEY_X, KeyFlag.Control), new Action(EditorActions.Cut, KeyCode.KEY_X, KeyFlag.Control),
new Action(EditorActions.Cut, KeyCode.KEY_X, KeyFlag.Control|KeyFlag.Shift), new Action(EditorActions.Cut, KeyCode.KEY_X, KeyFlag.Control | KeyFlag.Shift),
new Action(EditorActions.Cut, KeyCode.DEL, KeyFlag.Shift), new Action(EditorActions.Cut, KeyCode.DEL, KeyFlag.Shift),
new Action(EditorActions.Paste, KeyCode.KEY_V, KeyFlag.Control), new Action(EditorActions.Paste, KeyCode.KEY_V, KeyFlag.Control),
new Action(EditorActions.Paste, KeyCode.KEY_V, KeyFlag.Control|KeyFlag.Shift), new Action(EditorActions.Paste, KeyCode.KEY_V, KeyFlag.Control | KeyFlag.Shift),
new Action(EditorActions.Paste, KeyCode.INS, KeyFlag.Shift), new Action(EditorActions.Paste, KeyCode.INS, KeyFlag.Shift),
// Undo/Redo // Undo/Redo
new Action(EditorActions.Undo, KeyCode.KEY_Z, KeyFlag.Control), new Action(EditorActions.Undo, KeyCode.KEY_Z, KeyFlag.Control),
new Action(EditorActions.Redo, KeyCode.KEY_Y, KeyFlag.Control), new Action(EditorActions.Redo, KeyCode.KEY_Y, KeyFlag.Control),
new Action(EditorActions.Redo, KeyCode.KEY_Z, KeyFlag.Control|KeyFlag.Shift), new Action(EditorActions.Redo, KeyCode.KEY_Z, KeyFlag.Control | KeyFlag.Shift),
new Action(EditorActions.Tab, KeyCode.TAB, 0), new Action(EditorActions.Tab, KeyCode.TAB, 0, ActionStateUpdateFlag.never),
new Action(EditorActions.BackTab, KeyCode.TAB, KeyFlag.Shift), new Action(EditorActions.BackTab, KeyCode.TAB, KeyFlag.Shift, ActionStateUpdateFlag.never),
new Action(EditorActions.Find, KeyCode.KEY_F, KeyFlag.Control), new Action(EditorActions.Find, KeyCode.KEY_F, KeyFlag.Control),
new Action(EditorActions.Replace, KeyCode.KEY_H, KeyFlag.Control), new Action(EditorActions.Replace, KeyCode.KEY_H, KeyFlag.Control),
@ -642,7 +642,7 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
case Cut: case Cut:
return enabled && (_copyCurrentLineWhenNoSelection || !_selectionRange.empty); return enabled && (_copyCurrentLineWhenNoSelection || !_selectionRange.empty);
case Paste: case Paste:
return enabled && Platform.instance.getClipboardText().length > 0; return enabled && Platform.instance.hasClipboardText();
case Undo: case Undo:
return enabled && _content.hasUndo; return enabled && _content.hasUndo;
case Redo: case Redo:

View File

@ -741,7 +741,7 @@ public:
} }
/// call to update state for action (if action is assigned for widget) /// call to update state for action (if action is assigned for widget)
void updateActionState(bool force = false) { void updateActionState(bool force = false) {
if (!_action) if (!_action || !(action.stateUpdateFlag & ActionStateUpdateFlag.inWidget))
return; return;
if (updateActionState(_action, force)) if (updateActionState(_action, force))
handleActionStateChanged(); handleActionStateChanged();
@ -1189,7 +1189,13 @@ public:
Action action = findKeyAction(event.keyCode, event.flags); // & (KeyFlag.Shift | KeyFlag.Alt | KeyFlag.Control | KeyFlag.Menu) Action action = findKeyAction(event.keyCode, event.flags); // & (KeyFlag.Shift | KeyFlag.Alt | KeyFlag.Control | KeyFlag.Menu)
if (action !is null) { if (action !is null) {
//Log.d("Action found: ", action.id, " ", action.labelValue.id); //Log.d("Action found: ", action.id, " ", action.labelValue.id);
return dispatchAction(action); // update action state
if ((action.stateUpdateFlag & ActionStateUpdateFlag.inAccelerator) && updateActionState(action, true) && action is _action)
handleActionStateChanged();
//run only enabled actions
if (action.state.enabled)
return dispatchAction(action);
} }
} }
// handle focus navigation using keys // handle focus navigation using keys