Why the Range ExpandTo method edit the undo stack - ms-word

While working on a Word-Addin project, I use the method expandTo from the Word.Range class to expand two ranges together.
That method works as expected, it expands correctly two given ranges.
However, that method appears to have an unexpected side effect on the undo stack of Microsoft-Word Online (I haven't been able to test it on a native Microsoft-Word app).
Once the expandTo method called, the undo stack appears to have got the expanded selection as an item in the undo stack. So to actually undo something, I need to ctrl + z (or click on the undo button) multiple times.
Below is a simple trivial example, expanding the beginning of the document until the end. It does select the entire document as expected, but also add an item in the undo stack. From there, the undo functionality is not behaving as expected. Multiple undo is necessary to cancel the last text edit.
Word.run(async (context): Promise<void> => {
const firstParagraph = context.document.body.paragraphs.getFirst().getRange('Start')
const lastParagraph = context.document.body.paragraphs.getLast().getRange('End')
const expanded = firstParagraph.expandTo(lastParagraph).load('text')
await context.sync()
console.log(expanded.text) // Expanded selection text
})
This snippet doesn't trigger any error in the console.
Since the expandTo method doesn't actually change the active selection, why does it edit the undo stack?
Has anyone found a work-around for that issue? Is this an expected behaviour, or is there any way to avoid that side effect?
Thanks everyone.

Related

New unity input system - is there a way to not execute an action if a modifier is being pressed?

So I want 2 different things to happen for when SHIFT+Q is pressed and when merely 'q' is pressed.
Currently when I press SHIFT+Q both actions are being fired, and I don't want that. Is there a way to do this elegantly in the action mapping? I would prefer not to have to hardcode keys in my scripts, but if that's the only way then I will just check in script if shift is currently engaged. It will be a giant headache in the future though if I want to allow players to edit key mappings.
For anyone coming across this in the future - It looks like this feature is being implemented in InputSystem 1.4.0+
(ChangeLog: https://github.com/Unity-Technologies/InputSystem/blob/develop/Packages/com.unity.inputsystem/CHANGELOG.md)
From the changelog:
Added support for keyboard shortcuts and mutually exclusive use of modifiers.
In short, this means that a "Shift+B" binding can now prevent a "B" binding from triggering.
Just need to pick one of the new 'OneModifierComposite' or 'TwoModifierComposite'.
Edit: please scroll to the bottom of this post. It turns out there’s actually a way to do this natively
I’m not totally sure, but one thing that I know will for sure work is to have separate actions mapped to shift and to q. Then in your OnShift function, simply set a “shiftIsPressed” flag to true or false, depending on whether the context is starting or ending. Then your your OnQ function can look something like this:
void OnQ(CallbackContext ctx)
{
if(!ctx.actionStarted) return;
if(shiftPressed) ShiftQ();
else Q();
}
This will keep key remapping open to you. It’s not perfect, if the player remaps Q to, say R, it will also remap ShiftQ to ShiftR. Without knowing more about your application though, that sounds like a good thing.
Edit:
To get Shift+Q to register as a separate action from Q, all you need to do is click the plus button on your ShiftQ action and select “Button With One Modifier Composite”. Then set Shift as the modifier and Q as the button. If you want to rebind Shift+Q to, say R, then set the button to R and the modifier to “Any Button”.
Hope this helps!

uimenu buttons remain pressed and trigger also other menus by just sliding over them: pushbutton behaviour desired

I implemented various uimenus in my uitable but there appears a very annoying behaviour.
function createUItable
h = figure
...
uimenu(h,'Label','MenuButton','Callback',#someAction)
end
%---------
function someAction(~,~)
%some action
end
But after executing the callback function, the menu button remains pressed and highlighted and not even that, when I slide over the next menu button, this one is triggered also!
This behaviour was also described at Matlab Central, but without solution.
I tried the suggested:
function someAction(~,~)
%some action
set(gcbo,'Enable','off')
drawnow
set(gcbo,'Enable','on')
end
which does not change anything. set(gcbo,'Enable','off') alone would solve the sliding problem, but also disables the whole button, what I don't want.
I also tried to use the 'Checked','Visible' and 'Interuptible' property without success.
This problem must be known, any hints?
I also thought about using uicontrol instead of uimenu and use a pushbutton, but I don't get it work.
Edit: when I put my menubutton into a submenu it works perfect:
button = uimenu(h,'Label','MenuButton');
uimenu(button,'Label','MenuButton','Callback',#someAction)
Edit2:
A pushbutton works also, but how could I place it into the menubar?
I guess MATLAB implementation is this way, because setting a callback at the top-level menu is very odd.
Naturally in GUI's (not only MATLAB), when you click the top-level menu (like "File", "Edit", etc.) the standard behaviour is, that a submenu pops open rather than an immediate action being executed.
So you should only use the top-level callback to e.g. dynamically create/modify the associated submenus.
I think there are two alternatives to go:
1) If you'd like to stick to that manner (one, always-visible button-like element), then you should rather use the toolbar via a uipushtool:
hToolbar = uitoolbar(parentFigure);
uipushtool(hToolbar, 'ClickedCallback', #someAction);
This does not have the 'Label' property though, so you'll have to work with 'CData' and may be a 'TooltipString'.
2) Create a top-level menu that contains your actual action-menu:
topMenu = uimenu(parent, 'Label', 'Actions');
uimenu(topMenu, 'Label', 'MenuButton', 'callback', #someAction)
From the general point of view on GUI design, both alternatives have the benefit of being the more commonly used style, thus being more intuitive to any user.
I found an interesting work-around for this problem while keeping the callback in the TOP menu. Turns out that using the uistack function released focus from the menu item so in the top-level menu callback, I placed
uistack(hObj,'down');
uistack(hObj,'up');
drawnow;
Which does nothing to the actual ordering but releases the menu items' focus.

find out which gtk widget has the current selection

I have a collection of GtkEntry widgets, some of which are editable and focusable, and some of which are not. I would like to find out which, if any, of them currently has text selected, in order to implement an Edit->Copy menu item. Is there any way to do this other than iterating over all the widgets until gtk_editable_get_selection_bounds returns true?
I am currently sidestepping the issue by calling gtk_clipboard_get(GDK_SELECTION_PRIMARY) but from what the docs say, that's not portable (and will also pick up text selected anywhere within the current display, not just from within my application).
Have you tried gtk_window_get_focus ()? Users are frequently interacting with entries, so it may work for you. The documentation says that it "retrieves the current focused widget within the window." You can look it by yourself here. Then, compare if the widget retrieved is one of your entries.
Once you get the focused entry, perhaps you would like to get its text using gtk_entry_get_text () , though, it will get all the text in the entry. If this does not fit your purposes, the solution might be using gtk_editable_copy_clipboard () which copies the contents of the currently selected content in the editable (of course, cast the entry to editable) and puts it on the clipboard. Then if it applies, paste what was copied using gtk_editable_paste_clipboard ().

QCompleter and Tab key

I'm trying to make a Completion when pressing tab, you get the first completion of all possibilities.
But, in a QWidget-based main window, pressing tab will make that QLineEdit lost focus, and completion popup hides after that.
Is there a way to fix it ?
Have you tried to subclass QLineEdit and intercept the key press event?
Alternatively you could set up an event filter.
Whew. It took me some time to figure this out :) Multiple times I have tried to solve this problem, but always gave up. Now, I dug enough to find the answer.
OP, please pardon me, because the code here is Python, but should be understandable and work for C++ as well.
Basically, the problem I had was "how to select an entry in the QCompleter"; I didn't notice before, but the answer is in the popup() method. QCompleter works with a model and a view, which contains the things to show.
You can change the current row as you wish, then get the index of that row in the model, then select it in the pop-up.
In my code, I subclassed QLineEdit, created a tabPressed signal which is emitted every time Tab is pressed. Then, connected this signal to a method of the same class which does this:
get the current index;
select the index in the popup;
advance to the next row.
As implementation, this is very trivial, but for my current purpose this is enough. Here's the skeleton (just for the tab part, it's missing the model and everything else).
class MyLineEdit(QLineEdit):
tabPressed = pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
self._compl = QCompleter()
self.tabPressed.connect(self.next_completion)
def next_completion(self):
index = self._compl.currentIndex()
self._compl.popup().setCurrentIndex(index)
start = self._compl.currentRow()
if not self._compl.setCurrentRow(start + 1):
self._compl.setCurrentRow(0)
def event(self, event):
if event.type() == QEvent.KeyPress and event.key() == Qt.Key_Tab:
self.tabPressed.emit()
return True
return super().event(event)
You may need to adjust/fix few things, but this is the basic idea.
EDIT:
For details see
http://www.qtcentre.org/threads/23518-How-to-change-completion-rule-of-QCompleter
There's a little issue: when Return is pressed, the things don't work properly. Maybe you can find a solution to this problem in the link above, or in the referenced resources therein. I'll fix this in the next few days and update this answer.
There is probably a better solution but one that comes to mind is to change the focus policy for all other widgets on the form to something that doesn't include "tab" focus. The only options that don't use the tab key are Qt::ClickFocus and Qt::NoFocus.

SilverLight 4 DataGrid & MVVM: Using SelectionChanged trigger to check checkbox, but NotifyPropertyChanged causes crash

I have a DataGridCheckBoxColumn in my DataGrid which is to indicate the rows the user has selected. I want the checkboxes to be checked/unchecked with a single click. Making the column editable (i.e. IsReadOnly="False") means the user has to click twice (first click just selects the row, 2nd click changes the checkbox), so I decided to set/clear the property the column is bound to in the view model code in response to the SelectionChanged trigger firing.
Setting/clearing the property works fine, however as soon as I call NotifyPropertyChanged("name of collection the grid is bound to") to get the view to show the change, this causes the SelectionChanged trigger to fire again. This loops about 10 times until an exception is thrown.
If I remove the call to NotifyPropertyChanged, the SelectionChanged trigger fires once, but of course I don't see any change in the UI. The collection is a PagedCollectionView if this makes any difference.
How can I get this to work? Note - I am using MVVM pattern, so everything is done with bindings to View Model (no code behind).
Thanks
Sounds like you have a infinite loop by design.
but try using the selectionchanging instead of selectionchanged,
or put a isloading flag in your viewmodel and dont call the inotify if the isloading is true
I found a very simple solution that doesn't involve triggers or code behind. See: Silverlight single-click checkbox DataGrid columns
It seems to work by using a column template, but only providing the CellEditingTemplate and no CellTemplate.