Jump to content

Kexi/Plugins/Macros/Discussions

From KDE Community Wiki
Revision as of 00:01, 27 December 2024 by Jstaniek (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
  • started by jstaniek, 2006-03-29
  • extended by sebsauer, 2006-05-14

This is temporary page usable for random discussions needed for Macros framework development.

TODOs

  1. Add version information to the XML format, otherwise it won't be easy to maintain backward compatibility.
  2. Add version information to the library much like in KexiDB's global.h, as we're going to have macros reused in other KOffice apps.

GUI, Part I

  • Priority: 1
  • Task: Modelling, Developing, Integration and Adoption needed.
  • Status: Progress.

GUI as frontend to the user to view and edit macros.

We need an abstraction-layer between the Macro-GUI functionality and the application that likes to use the GUI. As Example Kexi could reuse the KoPropertyView and the KexiTable to manage Macros while another application doesn't use KoPropertyView at all.

"The goal is that the user has to be able to understand what macro does without even looking at the manual."

  • Milestone 20
  • Prototype
  • GUI Examples

GUI, Part II

  • Priority: 2
  • Task: Use the UI-elements Kexi offers.
  • Status: Progress.

Kexi provides own UI-elements like the KexiViewBase the Macro-Editor is displayed in or the KoPropertyView used for settings. Kexi should use the UI-layer produced at "GUI, Part 1" to use it's own way to display the Macro-Editor functionality. Kexi will use his own KexiTable and KexiDataAwarePropertySet to display the editor.


Integration into Kexi, Part I

  • Priority: 2
  • Task: Coding and GUI needed.
  • Status: Progress.
  1. [done] [2006-04-01] Add kexi/plugins/macro directory in 1.6. branch and move komacro in.
  2. [done] [2006-04-23] Implement Kexi plugin that loads/restores the XML. By providing lib/xmlhandler.{h|cpp} to (un-)serialize XML.
  3. [done] [2006-05-02] Implement execution of the Macro.
  4. [progress] Provide the GUI-Editor as KexiView.


Integration into Kexi, Part II

  • Priority: 3
  • Task: New code, GUI and some rewrites are needed.
  • Status: Open.

We need a way to connect e.g. a buttons click-event with "Execute Macro". Currently Kexi provides a way to achieve exactly this by using the "Assign Action" Dialog displayed at the contextmenu of a button.

There are two ways to achieve the goal of integration;

  1. Add an additional "Macro" actiontype to the "Assign Action" Dialog and go the same way e.g. Scripts are using to be executable via a button's click.
  2. Redesign the "Assign Action" process. We like to have an own "Connect Event with Action" tab in KoPropertyView. The user should be able to connect any signal a widget offers with any kind of action.

User-Handbook

  • Priority: 1
  • Task: Documentation-writers needed.
  • Status: Started.

We need to produce a user-handbook how to use macros.


Issues

More general issues regarding the Framework.


Synchronous or asynchronous macros?

  • Priority: 2
  • Task: GUI related.
  • Status: Progress.

jstaniek, 2006-03-29: I'd vote for synchronous for now. There are many actions like "open dialog", "close window" that can work very well as synchronous. Especially for modal dialogs we expect synchronouos execution. There are cases when asynchronous macro can cause crashes when application is not designed to work asynchronously. I learned that such crashes can be hard to fix.

When could be asynchronous macro action usable? In Kexi context, e.g. for processing large data. But this action is the one we plan to make asynchr. anyway, independently of macros. Thus the same async. functionality can be accessed in three ways: 1. directly by user's mouse clicks; 2. within macros; 3. within scripts.

For above scenario, having async. data processing action, we may just need an execution context returned back to macro executing engine, so macro users can decide whether (1) they want to wait (block the macro execution) or (2) not. In case (1): macro engine will create a wait condition and sleep doing nothing before the action terminates. In case (2), the macro will continue without knowin anything about successfull termination of the action. Example action sequences in schematic notation:

 (1)
 run_large_query( update query, WAIT ) /* this takes 2 minutes */
 do_something_for_the_updated_data() /* this will be executed after
                                        successfull termination of
                                        the above action */
 (2)
 run_large_query( update query, DONTWAIT ) /* this takes 2 minutes */
 do_something_different() /* this will be probably executed in
                             parallel to the above action */

sebsauer, 2006-03-31: Steps

  1. [done] [2006-04-01] an option to decide in KoMacro::Context::activate() if the execution should be done synchron or asynchron.
  2. [done] [2006-04-23] (un-)serialize the option from/to XML.
  3. GUI-related those option needs to be configurable via the GUI.

sebsauer, 2006-04-01: Partly done now. We are able to decide via Action::setBlocking() if execution is done sychron or asynchron. GUI-related: Do we really like to have an option at the GUI for that functionality?

sebsauer, 2006-04-23: I would propose to declare this done cause remaining is GUI-related.


Does a Macro need to be an Action?

  • Priority: 3
  • Task: Refactoring needed and GUI-related.
  • Status: Done.

jstaniek, 2006-03-29: Complexity! I believe we need to keep macros functionality available for Joe User. As I understand what we wanted to achieve by "Macro is an Action too." here's what I's propose instead of this:

  • let's keep just a flat list of macros accessible by (unicode) name
  • define a macro action called "Execute Macro" taking a macro name as an argument; of course the argument will be selectable using combo box; (we can think about passing optional arguments later)

That's all. It's about replacing inclusion by calling. Thus we can simplify the hierarchy. If someone within his app wants to make hierarchical macro structure, it's easy to do this at app's global level, just similar to Kexi tables/queries structure in the Project Navigator by delivering something like virtual folders concept.


sebsauer, 2006-03-31: Steps

  1. [done] [2006-04-01] The KoMacro::Macro class uses currently QValueList<Action::Ptr> to store the actions. We could use a QMap<QString, Action::Ptr> to map name=>action's and a QStringList to map the order of the names (needed for the execution-chain).
  2. [done] [2006-04-23] Redesign the lib to use a flatlist rather then a tree. We are using MacroItem now.
  3. [done] [2006-05-02] Implement.


Not all slots should be published for Manager::publishObject()

  • Priority: 1
  • Task: design and implement.
  • Status: Open.

jstaniek, 2006-03-29: Perhaps we need to explicity publish each slot (security!).

sebsauer, 2006-03-31: We could add a class that provides public slots for functionality like

  • openTable(const QString& tablename)
  • closeTable(const QString& tablename)
  • openQuery(const QString& queryname)
  • closeQuery(const QString& queryname)
  • openForm(const QString& formname)
  • closeForm(const QString& formname)
  • executeScript(const QString& scriptname)
  • showMessageBox(const QString& caption, const QString& message)

jstaniek, 2006-03-31: You mean a wraper class that only exposes slots we want to expose to the public? My alternative cound be to: add a list of slot interfaces (written as strings). In the API this one could be:

 QStringList allowedInterfaces;
 allowedInterfaces
  << "KexiProject::openTable(const QString& tablename)"
  << "KexiProject::closeTable(const QString& tablename)"
  /* .... */
  ;
 /* let's declare allowed interfaces of the plugin */
 MacroPlugin::setAllowedInterfaces(allowedInterfaces);

Then we can avoid a situation when lazy developers just pass internal QObject having slots not suitable for macros, and thus introduce security holes. The drawback is that, OTOH, they canforget about adding some interface strings to the list of allowed interfaces.

sebsauer, 2006-04-01: We could provide QObject's to group different functionality.

  Class Table : public QObject {
    public slots:
      void open(const QString& tablename) { ... }
      void close(const QString& tablename) { ... }
  };

This offers us on the one hand a more typesafe way to deal with functionality provided by Kexi (typos are checked by the compiler) and enables an easy way to handle publishing. At a later stage (lower priority) we could also need some describing i18n-text for each function. That could be done e.g. by using Q_PROPERTY.

sebsauer, 2006-04-10: We need to limit the functionality. So, we should explicit pick Action's Kexi likes to provide on a list. At a first step I would suggest following actions;

  • OpenObject - With two arguments. The first argument is the plugintype which should be opened. This could be e.g. "table" or "query". The second argument is then the name of the item.
  • CloseObject - Same as with OpenObject except that it closes an opened object again.
  • ExecuteObject - The "Macros" and the "Scripts" plugins are able to execute an object.

sebsauer, 2006-05-14:

We have following actions now;

  • Open, to open a table, query, form, macro or a script.
  • Execute, to execute a macro or a script.
  • Navigate, to navigate with the cursor within a table, query or form
  • Message, to display a simple messagebox

Additional actions Kexi likes to offer;

  • Close, to close an opened table, query, form, macro or script.
  • Print and PrintPreview, print tables and queries.
  • Get/Set Field, to manipulate the current cursor within a table or form.
  • Import and Export, control the Comma-Separated-Value import and export functionality.
  • Migrate, control the migration-wizard
  • Variable, to set/get the variables more dynamic. That way as example a InputBox could be displayed and the resulting string could be used to set the value of a field in the current cursor.


Manager could handle the execution

  • Priority: 4
  • Task: Refactoring needed.
  • Status: Open.

jstaniek, 2006-03-29: Currently Action objects provide activate(). The idea is that since Manager want's to know about each action execution, we could move Action::activate() to Manager::execute(Macro&) or so. Action class and subclasses could stay just as something like action models, without a knowledge about executing context. Manager should care about executing. Thus, we can later extend the stuff to allow step-by-step execution, aka macro debugging.

  • http://kexi-project.org/docs/komacro/KoMacro.png
  • Umbrello file

sebsauer, 2006-04-04:

We are already able to add debugging (for a whole execution-chain) via the Context class. The Manager class needs to be extended to handle such cases more transparently.


Keep one place for handling XML

  • Priority: 2
  • Task: Design and code XMLReader/XMLWriter.
  • Status: Done

jstaniek, 2006-03-29: move QDomElement attributes e.g. from Action to XMLReader/XMLWriter.

sebsauer, 2006-04-04: Steps

  1. Redesign and implement XML<=>KoMacro (un-)marshaling. We will earn a more clean API and improve flexibility by moving the existing XML-functionality out of macros into there own XMLReader and XMLWriter classes.

sebsauer, 2006-04-23: Declared done cause we are able to (un-)serialize with lib/xmlhandler.{h|cpp} now.


Nice-to-have

Some nice to have features.


Debugger

  • Priority: 5
  • Task: Design and implement functionality.
  • Status: Open.

A debugger to debug Macros and control executions would be a nice feature. The KoMacro library could be extended to implement;

  • step-by-step execution.
  • display and modify variables at each step.
  • conditions for variables.
  • breakpoints
  • etc.


Kross-binding

  • Priority: 5
  • Task: Design and implement functionality.
  • Status: Open.

Kross is the Scripting Framework used within Kexi to enable Python and Ruby scripting support. It would be nice, to be able to control Macros from within Kross.


Macrorecorder

  • Priority: 6
  • Task: Design and implement functionality.
  • Status: Open.

A recorder to be able to record and replay performed actions.


Notes

  • Reflecting:
    • Refactoring
    • Manager as singleton
      • pro: smaller constructor, easier handling.
      • contra: not component-based.
  • XMLHandler
    • ->Keep_one_place_for_handling_XML
  • Actions
    • -> Not_all_slots_should_be_published_for_Manager::publishObject()
    • by an application predefined actions like e.g. OpenTable, CloseTable, KMessageBox
      • i18n-description, i18n-name, icon, activate(), container for parameters
    • actions defined in a macro
      • each action points to a predefined action
      • macro1(OpenObject("table","mytable1"),ExecuteObject("script","myscript1","optional argument"),...)
      • comment defined by the user for a macro and/or an action.
  • Does a Macro need to be an Action?
    • Does_a_Macro_need_to_be_an_Action
  • How to handle exceptions?
    • return THROW( new Exception() );
  • Unittests