I have a TableViewer within my View and I would like to use the org.eclipse.ui.edit.selectAll command to select all rows using the standard Ctrl+A shortcut.
When I put tracing on I can see the HandlerAuthority class resolves some conflicts and the output looks like this:
HANDLERS >>> Command('org.eclipse.ui.edit.selectAll') has changed to 'org.eclipse.ui.internal.handlers.SelectAllHandler' as its handler
HANDLERS >>> resolveConflicts: eval: HandlerActivation(commandId=org.eclipse.ui.edit.selectAll,
handler=org.eclipse.ui.internal.handlers.SelectAllHandler#2a3e58,
expression=,sourcePriority=0)
HANDLERS >>> Resolved conflict detected. The following activation won:
HANDLERS >>> HandlerActivation(commandId=org.eclipse.ui.edit.selectAll,
handler=org.eclipse.ui.internal.handlers.SelectAllHandler#2a3e58,
expression=,sourcePriority=0)
HANDLERS >>> resolveConflicts: eval: HandlerActivation(commandId=org.eclipse.ui.edit.selectAll,
handler=org.eclipse.ui.internal.handlers.SelectAllHandler#2a3e58,
expression=,sourcePriority=0)
HANDLERS >>> Resolved conflict detected. The following activation won:
HANDLERS >>> HandlerActivation(commandId=org.eclipse.ui.edit.selectAll,
handler=org.eclipse.ui.internal.handlers.SelectAllHandler#2a3e58,
expression=,sourcePriority=0)
HANDLERS >>> resolveConflicts: eval: HandlerActivation(commandId=org.eclipse.ui.edit.selectAll,
handler=ActionHandler(RetargetAction(selectAll)),
expression=ActiveShellExpression(Shell {SPL v0.1.2 (VYVOJ) (DB TEST)}),sourcePriority=17408)
HANDLERS >>> resolveConflicts: eval: HandlerActivation(commandId=org.eclipse.ui.edit.selectAll,
handler=org.eclipse.ui.internal.handlers.SelectAllHandler#2a3e58,
expression=,sourcePriority=0)
HANDLERS >>> Resolved conflict detected. The following activation won:
HANDLERS >>> HandlerActivation(commandId=org.eclipse.ui.edit.selectAll,
handler=ActionHandler(RetargetAction(selectAll)),
expression=ActiveShellExpression(Shell {SPL v0.1.2 (VYVOJ) (DB TEST)}),sourcePriority=17408)
HANDLERS >>> Command('org.eclipse.ui.edit.selectAll') has changed to 'ActionHandler(RetargetAction(selectAll))' as its handler
When I press Ctrl+A I can see:
KEYS >>> Listener.handleEvent(type = KeyDown, stateMask = 0x0, keyCode = 0x40000, time = 9403459, character = 0x0)
KEYS >>> Listener.handleEvent(type = KeyDown, stateMask = 0x40000, keyCode = 0x61, time = 9403553, character = 0x1)
KEYS >>> WorkbenchKeyboard.press(potentialKeyStrokes = [CTRL+A])
KEYS >>> WorkbenchKeyboard.executeCommand(commandId = 'org.eclipse.ui.edit.selectAll', parameters = {})
KEYS >>> not handled
Debugging the RetargetAction I found that the Action is not handled because it has no handler set.
So my question is, why the HandlerAuthority sets an RetargetAction as a handler for the
org.eclipse.ui.edit.selectAll command? I would like to use the default one (org.eclipse.ui.internal.handlers.SelectAllHandler).
All actions which are intended to be implemented by multiple views and editors use RetargetAction. You hook in to the retarget action in your view like this:
IActionBars bars = getViewSite().getActionBars();
bars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), selectAllAction);
where selectionAllAction is an Action that does the select all on your table. The action might look like:
class SelectAllAction extends Action
{
private final TableViewer tableViewer;
SelectAllAction(final TreeViewer viewer)
{
tableViewer = viewer;
}
#Override
public void run()
{
tableViewer.getTable().selectAll();
// Get table view selection synchronized with table selection
tableViewer.setSelection(tableViewer.getSelection());
}
}
Related
based on that js demo: http://jsfiddle.net/wfbY8/737/
class Draggable(element: HTMLDivElement) {
var offX: Double = 0
var offY: Double = 0
val divMove = (e:MouseEvent) => {
//element.style.position = 'absolute';
element.style.top = (e.clientY-offY) + "px"
element.style.left = (e.clientX-offX) + "px"
}
val mouseDown = (e:MouseEvent) => {
offY = e.clientY - element.offsetTop
offX = e.clientX - element.offsetLeft
window.addEventListener("mousemove", divMove, useCapture = true)
println("added")
}
val mouseUp = (e:MouseEvent) => {
window.removeEventListener("mousemove", divMove, useCapture = true)
println("removed")
}
def addListeners(){
element.addEventListener("mousedown", mouseDown, useCapture = false)
window.addEventListener("mouseup", mouseUp, useCapture = false)
}
addListeners()
}
From the client code I use it like:
val panelElem = document.getElementById(COMPONENT_ID).asInstanceOf[HTMLDivElement]
if (draggable == null) {
draggable = new Draggable(panelElem)
}
I see "added" and "removed" on my log. But the element still movable (when I move mouse without pressing it) for me as if I did not removed mousemove event from the listener (on mouseUp).
I wonder why..
This happens because you're effectively converting the Scala function (the lambda) into a JS function separately for add and remove. In Scala.js, Scala functions are implicitly converted to JS functions as needed. However, the conversion yields a different JS function every time (it does not have the same identity). Therefore, the function you're trying to remove is not the same as the one you added, and of course that has no effect.
You can fix this by forcing the conversion to happen early, so that then you add and remove the same function. To do so, simply add an explicit type to your function vals as JS functions:
val divMove: js.Function1[MouseEvent, Unit] = (e:MouseEvent) => {
...
}
This way, the conversion from Scala function to JS function happens only once, and it is the same JS function that is given to add- and removeEventListener.
When Canonical-Quickly sets up a new project it has the following line for the "About dialog":
self.AboutDialog = AboutNewAppDialog
I edited the menu item in glade and added the following code to the python code for the main window:
self.menuabout = self.builder.get_object("menuabout")
and
def on_menuabout_activate(self, menuitem, data=None):
print("About activated")
self.response = self.AboutDialog.run()
self.AboutDialog.hide()
But this produces the error:
self.response = self.AboutDialog.run()
TypeError: run() takes exactly 1 argument (0 given)
I am also working through this tutorial which is using a similar syntax: http://gnipsel.com/glade/glade02b.html
When I place Gtk.Dialog into the brackets the program crashes:
self.response = self.AboutDialog.run(Gtk.Dialog)
My second try:
#!/usr/bin/env python
from gi.repository import Gtk
class Handler:
def on_mainwindow_destroy(self, menuitem):
print("destroy window")
Gtk.main_quit()
def on_menuquit_activate(self, menuitem):
print("quit from menu")
Gtk.main_quit()
def on_menuabout_activate(self, menuitem, data=None):
print("menu about activated")
response = aboutdialog.run()
aboutdialog.hide()
builder = Gtk.Builder()
builder.add_from_file("psn.glade")
builder.connect_signals(Handler())
window = builder.get_object("mainwindow")
window.show_all()
Gtk.main()
Error:
"Traceback (most recent call last):
File "psn_main.py", line 21, in on_menuabout_activate
response = aboutdialog.run()
NameError: name 'aboutdialog' is not defined"
I got it to work using the following code. The function is activated by a menu item which calls "on_menuabout_activate". It prints a debug message to the console. Then it gets the aboutdialog-window from the glade file and runs it:
def on_menuabout_activate(self, menuitem, data=None):
print("menu about activated")
aboutdialog = builder.get_object("aboutdialog")
aboutdialog.run()
I'm relatively new to wxpython - really appreciate it any help you can offer me. Basically, I'm having trouble closing the loop between
1) filling a list called ListOfFiles in my OnDropFiles method below and
2) refreshing the FileList so that it displays the items in ListOfFiles.
I know that if you call
FileWindow(None, -1, 'List of Files and Actions')
right at the end of OnDropFiles, it inits a new frame and draws from ListOfFiles when populating the FileList listctrl... but I was hoping there would be a way to update in the same window. I've tried noodling around with Layout() and calling various methods on my FileWindowObject... but there's been no success.
Thanks so much for your help. I think the answer you give me might lead to a real breakthrough in my understanding of wxpython.
#!/usr/bin/env python
import wx
import sys
import traceback
import time
APP_EXIT = 1
ListOfFiles = []
class FileDrop(wx.FileDropTarget): #This is the file drop target
def __init__(self, window):
wx.FileDropTarget.__init__(self) #File Drop targets are subsets of windows
self.window = window
def OnDropFiles(self, x, y, filenames): #FileDropTarget now fills in the ListOfFiles
for DragAndDropFile in filenames:
ListOfFiles.append(DragAndDropFile) #We simply append to the bottom of our list of files.
class FileWindow(wx.Frame):
def __init__(self, parent, id, title): #This will initiate with an id and a title
wx.Frame.__init__(self, parent, id, title, size=(300, 300))
hbox = wx.BoxSizer(wx.HORIZONTAL) #These are layout items
panel = wx.Panel(self, -1) #These are layout items
self.FileList = wx.ListCtrl(panel, -1, style=wx.LC_REPORT) #This builds the list control box
DropTarget = FileDrop(self.FileList) #Establish the listctrl as a drop target
self.FileList.SetDropTarget(DropTarget) #Make drop target.
self.FileList.InsertColumn(0,'Filename',width=140) #Here we build the columns
for i in ListOfFiles: #Fill up listctrl starting with list of working files
InsertedItem = self.FileList.InsertStringItem(sys.maxint, i) #Here we insert an item at the bottom of the list
hbox.Add(self.FileList, 1, wx.EXPAND)
panel.SetSizer(hbox)
self.Show(True)
def main():
ex = wx.App(redirect = True, filename = time.strftime("%Y%m%d%H%M%S.txt"))
FileWindowObject = FileWindow(None, -1, 'List of Files and Actions')
ex.MainLoop()
if __name__ == '__main__':
main() #Execute function#!/usr/bin/env python
The problem is that all you're doing is adding items to a list, not to the ListCtrl itself. You need to subclass wx.ListCtrl and add an update method of some sort. Then you would call that update method instead of appending to a list you don't use anywhere. Here's one way to do it:
import wx
import time
########################################################################
class MyListCtrl(wx.ListCtrl):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.ListCtrl.__init__(self, parent, style=wx.LC_REPORT)
self.index = 0
#----------------------------------------------------------------------
def dropUpdate(self, path):
""""""
self.InsertStringItem(self.index, path)
self.index += 1
class FileDrop(wx.FileDropTarget): #This is the file drop target
def __init__(self, window):
wx.FileDropTarget.__init__(self) #File Drop targets are subsets of windows
self.window = window
def OnDropFiles(self, x, y, filenames): #FileDropTarget now fills in the ListOfFiles
for DragAndDropFile in filenames:
self.window.dropUpdate(DragAndDropFile) # update list control
class FileWindow(wx.Frame):
def __init__(self, parent, id, title): #This will initiate with an id and a title
wx.Frame.__init__(self, parent, id, title, size=(300, 300))
hbox = wx.BoxSizer(wx.HORIZONTAL) #These are layout items
panel = wx.Panel(self, -1) #These are layout items
self.FileList = MyListCtrl(panel) #This builds the list control box
DropTarget = FileDrop(self.FileList) #Establish the listctrl as a drop target
self.FileList.SetDropTarget(DropTarget) #Make drop target.
self.FileList.InsertColumn(0,'Filename',width=140) #Here we build the columns
hbox.Add(self.FileList, 1, wx.EXPAND)
panel.SetSizer(hbox)
self.Show(True)
def main():
ex = wx.App(redirect = True, filename = time.strftime("%Y%m%d%H%M%S.txt"))
FileWindowObject = FileWindow(None, -1, 'List of Files and Actions')
ex.MainLoop()
if __name__ == '__main__':
main()
Is there any way to implement nsICommandLineHandler in a restartless add-on?
It seems possible from https://addons.mozilla.org/en-US/developers/docs/sdk/latest/modules/sdk/platform/xpcom.html , but this code (run from within exports.main) is not working for me:
var { Class } = require('sdk/core/heritage');
var { Unknown, Factory } = require('sdk/platform/xpcom');
var { Cc, Ci } = require('chrome');
var contractId = '#mozilla.org/commandlinehandler/general-startup;1?type=webappfind';
// Define a component
var CommandLineHandler = Class({
extends: Unknown,
get wrappedJSObject() this,
classDescription: "webAppFinder",
/* Not used by SDK, so commenting out
_xpcom_categories: [{
category: "command-line-handler",
// category names are sorted alphabetically. Typical command-line handlers use a
// category that begins with the letter "m".
entry: "m-webappfind"
}],
*/
helpInfo : " -webappfind Open My Application\n",
// nsICommandLineHandler
handle : function clh_handle(cmdLine) {
try {
console.log('good so far'); // Doesn't actually reach here
var fileStr = cmdLine.handleFlagWithParam("webappfind", false);
if (fileStr) {
console.log('made it');
}
}
catch (e) {
Cu.reportError("incorrect parameter passed to -webappfind on the command line.");
}
if (cmdLine.handleFlag("webappfind", false)) { // no argument
cmdLine.preventDefault = true;
throw 'A valid ID must be provided to webappfind';
}
},
hello: function() {return 'Hello World';}
});
// Create and register the factory
var factory = Factory({
contract: contractId,
// id: '{7f397cba-7a9a-4a05-9ca7-a5b8d7438c6c}', // Despite the docs saying one can add both, this doesn't work
Component: CommandLineHandler
});
I have the following code afterward which works...
// XPCOM clients can retrieve and use this new
// component in the normal way
var wrapper = Cc[contractId].createInstance(Ci.nsISupports);
var helloWorld = wrapper.wrappedJSObject;
console.log(helloWorld.hello());
...but Firefox is not accepting command line args as per this error:
Error: Warning: unrecognized command line flag -webappfind
Source file: resource://app/components/nsBrowserContentHandler.js
Line: 765
UPDATE
I've now taken #nmaier's advice to add categories and therefore added these lines afterward:
var catMan = Cc['#mozilla.org/categorymanager;1'].getService(Ci.nsICategoryManager); //
catMan.addCategoryEntry('command-line-handler', 'm-webappfind' /*contractId*/, contractId, false, true);
But I'm getting these 3 errors when invoking from the command line:
Error: [Exception... "'Failure' when calling method:
[nsIFactory::createInstance]" nsresult: "0x80004005
(NS_ERROR_FAILURE)" location: "native frame :: ::
:: line 0" data: no]
Contract ID
'#mozilla.org/commandlinehandler/general-startup;1?type=webappfind'
was registered as a command line handler for entry 'm-webappfind', but
could not be created.
Error: Warning: unrecognized command line flag -webappfind
Source file: resource://app/components/nsBrowserContentHandler.js
Line: 765
The SDK will not register categories for you.
Some remarks regarding categories can be found here:
https://stackoverflow.com/a/18366485/484441
But still, I'm not sure if bootstrapped extensions are actually started before the initial command line is processed. Trial and error, I guess...
Edit:
Your component does not specify any interfaces, hence it does only support nsISupports.
The SDK module docs state that you should add an interfaces: [ 'nsICommandLineHandler' ] property.
I've added the code in the answer to this question: Unknown discriminator value 'MyEvent', but it didn't help.
An error occurred while deserializing the Body property of class EventStore.EventMessage: Unknown discriminator value : "Insert event name".
Error only occurs when you try to rehydrate a saved object after program restart.
Running latest MyGet Build
Sample Repository:https://github.com/tonyeung/EventStore-MongoDB
To replicate the issue:
run the program
press c to create a new record
press q to quit
run the program again
but press r to rehydrate
error triggers
If you run the program, press c, press enter to continue, and press r to rehydrate without quitting, the object is rehydrated without a problem. WAT?
using (var eventStore = WireupEventStore())
{
var snapshot = eventStore.Advanced.GetSnapshot(ID, int.MaxValue);
if (snapshot == null)
{
// ERRORS HERE
using (var stream = eventStore.OpenStream(ID, 0, int.MaxValue))
{
var events = from s in stream.CommittedEvents
select s.Body as IEvent;
obj.LoadsFromHistory(events);
}
}
}
github issue: https://github.com/NEventStore/NEventStore/issues/203
I figured it out, since I was using an interface as a marker for my events, I had to change the query from the SO question from
var types = Assembly.GetAssembly(typeof(SimpleCQRS.Event))
.GetTypes()
.Where(type => type.IsSubclassOf(typeof(SimpleCQRS.Event)));
to
var type = typeof(IEvent);
var types = Assembly.GetAssembly(typeof(IEvent))
.GetTypes()
.Where(t => type.IsAssignableFrom(t))
.Where(t => t.IsClass);