I try to learn some event reflex extensions of LibreOffice. Catching events(like Save, SaveAs etc.) and after that getting some information about caught event(like flags, member variables etc.) and blocking event routine that I filtered is what I want to do. For example, the function has been caught SaveAs event and if the function want to prevent SaveAs routine, it has to set related flag or member variable of caught event. I have found some example python scripts from libreofficehelp.
The example used XDocumentEventListener from com.sun.star.document. And the example used following 2 functions for catching,
def listen(self, *args): # OnLoad/OnNew at the earliest
""" Start doc. events monitoring """
self.doc.addDocumentEventListener(self)
Console.log("INFO", "Document events are being logged", True)
def documentEventOccured(self, event: DocumentEvent):
""" Intercepts all doc. events """
#self.setCell(event.Source, event.EventName) # only for Calc docs
Console.log("DEBUG",
event.EventName+" in "+self.Filename,
False)
I tried to find documents about XDocumentEventListener. Unfortunately, I could not find an explanatory and detailed document.
In addition, similar process can be done on the Microsoft Office side below:
private void Application_DocumentBeforeSave(Word.Document doc, ref bool SaveAsUI, ref bool Cancel)
{
...
Cancel = true;
return;
}
How can I find related document and where from ? Or may someone give me some information ?
Here is an example in Basic from https://ask.libreoffice.org/t/prevent-save-in-calc-with-a-macro/3772 :
In Menu/Tools/Customize/Events you can assign a macro to “Save document” event.
function onsave(oEvent as object)
oEvent.Source.disableSetModified()
onsave=false
end function
From that same comment:
This prevent saving the document until you close the document.
Then appears the question “Document was modified. Save, discard or cancel?”
If you click “save” the document will be saved anyway.
Perhaps you could also add a handler for the Close Document event.
As mentioned in my comment to the question that seems suspiciously similar, this would potentially make LibreOffice very difficult for the user, so I wouldn't recommend it, and that's probably why there is so little information.
Related
In robot framework you can create an object from a library. Directly from the documentation, it looks like this.
*** Settings ***
Library com.company.TestLib WITH NAME TestLib
My question is can you do the same thing with a resource file? I have been trying to create a
keyword python file with instance variables that store the test start time and test name. I use the test name and time as a unique ID in a JavaScript data file for the web. I saw both values reverting to the default 'blank' and decided to insert some print statements about an instance ID variable. This was the result.
var testRuns = {};
testRuns['Test Site 2 2021-12-09 02:09:19.849706']=[];***ID79
testRuns['blank'].push({Case: 'Just Proving the Point.txt', Step: 'Verify Menu HTML', Time: '18970 days, 7:09:19.889702', Status: 'PASS***ID0', Details: 'Actual: Content, Expected: Content'});***ID0
testRuns['blank'].push({Case: 'Find Content Menu.txt', Step: 'Verify Menu HTML', Time: '18970 days, 7:09:19.919697', Status: 'PASS***ID34', Details: 'Actual: Content, Expected: Content'});***ID34
The randomly generated ID is created at construction of the python class (below). Each line in the output has the ID tacked on and you can see that they are different. Each one appears to be an entirely new instance of python class created in the resource file.
class kw_DataExtraction:
def __init__(self, primaryFile=defaultFile, secondaryFile=defaultSecondaryFile):
self.dataFile = primaryFile
self.otherFile = secondaryFile
self.currentTestName = "blank"
self.testCaseStart = datetime.fromtimestamp(0)
self.myID = random.randint(0,100)
So, I tried something like the below and it is apparently not legal syntax. Is there a way to instantiate the resources just once and consistently use it?
Resource ./../OQE/DataExtraction.resource WITH NAME dEx
Okay. Thanks to #Dev for helping to clarify the question. The issue here is an aspect of Robot Framework that I wouldn't have considered. This led me to a very good answer related to state How to Preserve Object state in Robot Framework. After some investigation, I was able to successfully solve my problem and the full explanation is below.
From the RF documentation http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#test-library-scope
"Because the state can affect how keywords actually behave, it is important to make sure that changes in one test case do not accidentally affect other test cases. These kind of dependencies may create hard-to-debug problems, for example, when new test cases are added and they use the library inconsistently. Robot Framework attempts to keep test cases independent from each other: by default, it creates new instances of test libraries for every test case."
In other words, it is a design decision that RF should have fresh state for all test cases. The behavior I was seeing was a direct result of that design decision.
In my case, I am using "test case" as steps within a whole task, what the documentation calls Robot Process Automation (RPA) http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#rpa. So in my work I want to designate the Python class with a more permanent state. To do that I add the ROBOT_LIBRARY_SCOPE variable to the class.
class kw_DataExtraction:
ROBOT_LIBRARY_SCOPE = 'SUITE'
With that in place I reran my test and the output shows the same ID number at the end and the right test case name is preserved. Mystery solved.
var testRuns = {};
testRuns['Test Site 2 2021-12-09 12:13:25.780586']=[];***ID56
testRuns['Test Site 2 2021-12-09 12:13:25.780586'].push({Case: 'Just Proving the Point.txt', Step: 'Verify Menu HTML', Time: '0:00:00.039995', Status: 'PASS***ID56', Details: 'Actual: Content, Expected: Content'});***ID56
testRuns['Test Site 2 2021-12-09 12:13:25.780586'].push({Case: 'Find Content Menu.txt', Step: 'Verify Menu HTML', Time: '0:00:00.070994', Status: 'PASS***ID56', Details: 'Actual: Content, Expected: Content'});***ID56
TL;DR; You cannot create just one library object by default. Default behavior in RF is to create a new instance for each test case. Add ROBOT_LIBRARY_SCOPE to any Python library to adjust the longevity of that class with respect to test cases.
I am faced with the task of writing a simple debug helper for Qt Creator 4.13.1 / Qt 5.12.5 / MSVC 2017 compiler for the C++ JSON implementation nlohmann::basic_json (https://github.com/nlohmann/json).
An object of nlohmann::basic_json can contain the contents of a single JSON data type (null, boolean, number, string, array, object) at a time.
There's a dump() member function which can be used to output the current content formatted as a std::string regardless of the current data type. I always want to use this function.
What I've done so far:
I've looked at https://doc.qt.io/qtcreator/creator-debugging-helpers.html, as well as at the given example files (qttypes.py, stdtypes.py...).
I made a copy of the file personaltypes.py and told Qt Creator about its existence at
Tools / Options / Debugger / Locals & Expressions / Extra Debugging Helpers
The following code works and displays a "Hello World" in the debugger window for nlohmann::basic_json objects.
import dumper
def qdump__nlohmann__basic_json(d, value):
d.putNumChild(0)
d.putValue("Hello World")
Unfortunately, despite the documentation, I have no idea how to proceed from here on.
I still have absolutely no clue how to correctly call basic_json's dump() function with the dumper from Python (e.g. with d.putCallItem ?).
I also have no starting point how to format the returned std::string so that it is finally displayed in the debugger window.
I imagined something like this, but it doesn't work.
d.putValue("data")
d.putNumChild(1)
d.putCallItem('dump', '#std::string', value, 'dump')
I hope someone can give me a little clue so that I can continue thinking in the right direction.
For example, can I call qdump__std__string from stdtypes.py myself to interpret the std::string?
Below is a snippet of code from Google's publicly available Neuroglancer. It is from an example on their github. Could someone explain what exactly this code does and how it does it? I am having trouble understanding it, and don't know what exactly the variable s is. Thank you for the help.
def my_action(s):
print('Got my-action')
print(' Mouse position: %s' % (s.mouse_voxel_coordinates,))
print(' Layer selected values: %s' % (s.selected_values,))
viewer.actions.add('my-action', my_action)
with viewer.config_state.txn() as s:
s.input_event_bindings.viewer['keyt'] = 'my-action'
s.status_messages['hello'] = 'Welcome to this example'
This example adds a key binding to the viewer and adds a status message. When you press the t key, the my_action function will run. my_action takes the current state of the action and grabs the mouse coordinates and selected values in the layer.
The .txn() method performs a state-modification transaction on the ConfigState object. And by state-modification, I mean it changes the config. There are several default actions in the ConfigState object (defined in part here), and you are modifying that config by adding your own action.
The mouse_coordinates and selected_values objects are defined in Python here, and link to the typescript implementation here. The example also sets a status message on the config state, and that is implemented here.
It might be useful to first point to the source code for the various functions involved.
the example is available on GitHub
viewer.config_state
viewer.config_state is a "trackable" version of neuroglancer.viewer_config_state.ConfigState
viewer.config_state.txn()
I've been struggling with this question for a while now. My question is very specific so please don't post a link to the ROS-tutorial page with the "!Note:" paragraph showing how to pass mutable objects (unless you show me something I have missed). I would like to know if anyone has been able to correctly pass mutable objects back and forth in SMACH states, without encountering any errors.
I wrote a particularly simple and useless program to explain what I am attempting to do. I could post the code of this example (unfortunately however, not surprisingly to those that have used SMACH before, it is a long piece of code). So for now I will just try my best to explain it and include a [link] to an image of my example. I created two python scripts. Each script contains a single class and object of that class (with some basic methods). I create a publisher and subscriber in each script, one of the scripts sends messages (talks) while the other script listens to (hears) the messages. At the end the talker flags both FSMs to shutdown. If anyone would like the full code example let me know...
Code snippet below showing smach states and transitions:
# begin sm
with sm:
smach.StateMachine.add('LOAD', loadFSM(),
transitions={'LOADED':'SENDMSG'})
smach.StateMachine.add('SENDMSG', startMSG(),
transitions={'SENT':'SENDMSG',
'ENDING':'END'})
smach.StateMachine.add('END', stopFSM(),
transitions={'DONE':'complete',
'ERRED':'incomplete'})
Code snippet below showing a smach state (loadFSM):
class loadFSM(smach.State):
def __init__(self):
smach.State.__init__(self, outcomes=['LOADED'],
output_keys=['talker_obj'],
input_keys=['talker_obj'])
# Initialise our talker object
self.talker = Talk()
def execute(self, userdata):
rospy.loginfo("talker state: Loading fsm")
self.talker.init_publish()
self.talker.init_subscribe()
userdata.talker_obj = self.talker
return 'LOADED'
The errors I receive (using Ubuntu 14.04, ROS indigo and python 2.7, not too sure but I believe the same errors occur in kinetic as well) only occur during state transitions and of course the introspective server does not work (does not show state transitions). The errors are;
1. "Exception in thread sm_introViewer:status_publisher:"
2. "Could not execute transition callback: Traceback (most recent call
last): File
"/opt/ros/indigo/lib/python2.7/dist-packages/smach/container.py",
line 175, in call_transition_cbs cb(self.userdata,
self.get_active_states(), *args)"
I also need to add, that my simple finite state machine example actually works and completes successfully, even my project's 2 larger FSMs complete. However, when the FSM has many states like in my project, sometimes my simulations fail. I would like to know from anyone who has used SMACH extensively if they think these errors are the cause or if they know for a fact that I am not passing the object correctly between states.
Thanks in Advance,
Tiz
I had similar problems in the past. If I remember correctly, userdata can only handle basic types (int, string, list, dict, ...) but not arbitrary objects.
I solved it by passing the objects to the constructor of state classes, instead of using the userdata, i.e. something like:
class myState(smach.State):
def __init__(self, obj):
smach.State.__init__(self, outcomes=['foo'], ...)
self.obj = obj
...
and then initialize like follows:
obj = SomeClass()
with sm:
smach.StateMachine.add('MY_STATE', myState(obj),
transitions={'foo':'bar'})
It is not so nice as it circumvents the userdata concept but it works.
Hi during the creation of multiple objects in pygtk application, calling some of these object return that they are uninitialised when passing there contents to signals (noting the value are showen correctly in the application)
sections = config.sections()
for section in sections:
box= gtk.Table (3,len(config.options(section)),False)
box.set_col_spacings(2)
box.set_row_spacings(2)
box.show()
label = gtk.Label(section)
label.show()
notebook.append_page (box,label)
for i,option in enumerate(config.options(section)):
optionlabel = gtk.Label(option)
optionvalue = gtk.Entry ()
optionvalue.set_text(config.get(section,option))
--> optionvalue.connect("activate", enter_callback,optionvalue, label, optionlabel)
box.attach(optionlabel,0,1,i,i+1,xoptions=gtk.SHRINK|gtk.FILL,yoptions=gtk.SHRINK)
box.attach(optionvalue,1,2,i,i+1,yoptions=gtk.SHRINK)
box.show_all()
at first I thought that the variables are not in scope but they were ( I've tested several objects and found them working the last 3 lines
Linuxcnc ini.py:70: GtkWarning: IA__gtk_entry_get_text: assertion "GTK_IS_ENTRY (entry) failed
print (widget.get_text())
None
<gtk.Label object at 0x9f44a54 (uninitialized at 0x0)>
<gtk.Label object at 0x9f44c0c (uninitialized at 0x0)>
0
<gtk.Label object at 0x9f4c8ec (GtkLabel at 0xa1a3350)>
<gtk.Label object at 0x9f4dc0c (GtkLabel at 0xa1a3450)>
For this one I think you may need to look in the Gtk system library itself.
(The source code that is used to produce ".so", ".dll" or ".dylib" file, that has the routines that your Python program is accessing).
You can look a the contents of such binary files with commands like "strings", "nm", and "objdump".
But based the nature of the error, it looks like the fix will be done in the source code of the library itself, not the Python program.
Sorry I cannot give more detail than that.