1. EXTENSIONS



DOCUMENTATION

1.1. Presentation

Extensions allow to add functions and dropdown menus dynamically to the KM2 interface.
Example :
BEFORE
AFTER
It is a feature/design choice that only one file can be used as extension.

Extensions are easy to write.

Extensions are written in python, and are based on simple primitives in KM2.
  • Extensions are defined in a single file, which is based KM2_USER/EXTENSIONS/extensions.py
  • Extensions can easily be written as an an xmind file which is then converted to py. KM2_USER/EXTENSIONS/extensions.xmind

1.2. Using extensions

Loading extensions is very easy : Just use the APPEARANCE\\LOAD EXTENSION in the menubar of KM2.
You can reload dynamically the extensions, thus load new functions any time.


PRIMITIVES

1.3. Accessible variables for writing extensions

These variables are intended to provide some background for the extensions.
Name Type Purpose
KM2_APP instance allows to interact globally with the app
KM2_WINDOW instance of tkinter frame allows to interact with the frame
KM2_FILE str / filename name of the current file selected in KM2
KM2_DIR str / filename name of the current directory selected in KM2

1.4. Suggestions for writing extensions

1.4.1. General use of extensions

Extensions are not supposed to be computationally heavy, or difficult.
Extensions are usefuls for calling programms.
Be careful with imports : some incompatibilities with the internal imports of KM2 might cause unexpected behaviours.

1.4.2. Some best practices

To make sure that the extension is loaded properly
If used for testing purposes, use the power of the KM2 macros to generate easily more cases !
Always
  • start an extension file with KM2_MSG ('ok - loading extensions ', 'red')
  • ends the extension file with KM2_MSG ('ok - extensions are loaded', 'green')

Sometimes you can also read and check the python code that is generated : just run it in your KM2_USER/EXTENSIONS directory !

1.5. Accessible primitives for writing extensions

1.5.1. interacting with the user

These functions allow to interact with the user using the tkinter functions. Please refer to the tkinter documentation for more information. HERE
Name Arguments Description Example of use Notes
KM2_MSG string, color writes the string with the given color in the "KM2 MESSAGE" line KM2_MSG ('hello world - this is an error', 'red') keep messages short
KM2_SPEAK sentence KM2 will speak loudly the sentence. A sentence is a list of strings or sentences. KM2_SPEAK (['hello', 'i am happy']) Warning : feature not always available

1.5.2. TkInter primitives

These functions allow to interact with the user using the tkinter functions. Please refer to the tkinter documentation for more information. HERE
Name Arguments Description Example of use Notes
showinfo title, message title of the window
message to inform
showinfo ("KM2_window", "this is a question")
showwarning title, message
showwarning ("KM2_window", "this is a question")
showerror title, message
showerror ("KM2_window", "this is a question")
askquestion title, message
askquestion ("KM2_window", "this is a question")
askokcancel title, message idem
askretrycancel title, message
askretrycancel ("KM2_window", "this is a question")
askyesno title, message
askyesno  ("KM2_window", "this is a question")
askyesnocancel title, message
askyesnocancel   ("KM2_window", "this is a question")
askopenfilename asks the user for the name of a file
opens a file dialog
askopenfilename ()
askdirectory asks the user for the name of a directory
opens dialog to find a directory name
askdirectory ()
asksaveasfilename asks the user for the name of a file
asksaveasfilename ()
askfloat title, message asks the user for a floating point number
will only return a float
askfloat ("KM2_window", "this is a question")
askinteger title, message asks the user for an integer
askinteger ("KM2_window", "this is a question") :
askinteger   ("KM2_window", "this is a question")
askstring title, message asks the user for a string
askstring ("KM2_window", "this is a question") :
askstring  ("KM2_window", "this is a question")
askcolor ask the user for a color
  • opens a dialog window
  • click OK or Cancel when finished


askcolor ()

±► TKINTER ELEMENTS More primitives

1.5.3. interacting with the NOTEPAD

FUNCTIONS arguments Description Example of use Notes
clear_notepad () W = notepad clears notepad
def test_clear_notepad () :
    clear_notepad ()
insert_notepad (string) string, W = notepad this text is inserted at the current position of the cursor in the notepad
def test_insert_notepad () :
    insert_notepad ("some text")
write_notepad (string) string, W = notepad write all the text to the notepad
def test_write_notepad () :
    write_notepad ("text to insert\n 2nd line")
current_line_notepad W = notepad gets the current line in the notepad
def test_current_line_notepad () :
    line = current_line_notepad ()
replace_current_line_notepad lines, W = notepad replaces the current line in the notepad
def test_replace_current_line_notepad () :
    replace_current_line_notepad (line)

1.5.4. Functions for building a menu

FUNCTIONS arguments Description Example of use Notes
add_extension name : string , menu inserts the menu with the name "name"
add_extension ("EXAMPLE", menu_example)
# first define menu_example as a menu (cf above)
menu_example = ...
unload_extension name : string the extension menu disappears from the KM2 interface
unload_extension ("EXAMPLE")

1.5.5. Function for adding Keys to windows

FUNCTIONS arguments Description Example of use Notes
add_key key, function, W = notepad associates the key with the function in indow W
add_key ("", reverse_current_line )

1.5.6. Functions for workspaces

FUNCTIONS arguments Description Example of use Notes
WORKSPACE title, file creates a WORKSPACE
WORKSPACE (title = "my title", file = "my_file.xmind")
VIEW key, function, W = notepad Creates a VIEW
VIEW  (title = "my title")
ARBRE key, function, W = notepad creates a tree
ARBRE (title = "my title")
is_workspace checks it x is a WORKSPACE
is_workspace (x)
is_view checks it x is a VIEW
is_view (x)
is_tree checks it x is a TREE
is_tree (x)
file_to_workspace interns a file into a WORKSPACE
file_to_workspace (fichier, get_images = False, get_styles = False, get_files = False)
workspace_to_file outputs a WORKSPACE into a file
workspace_to_file  (ws, file_name)


GRAPHICS

We use specifically the tkinter library.

1.6. USING MACROS FOR WRITING EXTENSIONS

Extensions can be written easily using the standard KM2 extensions of python.
Standard and specific macros can be used in the regular way. :

1.7. MACROS FOR CREATING WINDOWS AND INTERACTIONS

We distinguish the layout of the different tkinter widgets with text notations
For example, we define the following layouts :

Now we define how to create a window, and the attached menubars :

We define notations for the positions, etc

And we create and position the various widgets :
We use the the grid method to position the various widgets.
We can create :
  • Frames
  • Entries
  • Buttons
  • A notepad
  • Line of widgets
  • etc.

This may sound a bit complicated, but you don't need to rewrite these macros !

Note : This page of documentation is subject to potential evolutions, according to the development of smarter notations.

1.8. Pre-imported modules

  • Basic modules
    • from types import *
    • from string import *
    • import itertools
    • import copy
    • import time
    • import datetime
    • from datetime import date
    • import random
    • import math
    • from sets import Set
    • from collections import Counter
  • SYSTEM
    • import sys
    • import gc
    • import subprocess
    • import multiprocessing
    • import threading
    • import uuid
    • import platform
  • FILES import os import os.path import shutil import json from pprint import pprint import codecs import unicodedata import pickle import zipfile
  • STANDARD MODULES
    • WEB import urllib import urllib2 import webbrowser
    • import keyword
    • import re
    • import base64 # for images
  • GRAPHICS
    • import Tkinter as Tk
      • from Tkinter import *
      • import tkFileDialog
      • import tkSimpleDialog
      • import tkMessageBox
      • from ScrolledText import *
      • import tkColorChooser
      • #from Tkinter import tix # pour les micro-fenetres d'aide / tooltip
    • #import ImageTk
    • #import PIL
    • #import Image
  • # mail
    • import smtplib
    • import email


NEW EXTENSION


We show here how it is possible to write simple extensions to KM2

1.9. Writing an extension

An extension is defined in 2 parts
  • define the functions
  • build the menus

1.9.1. Defining functions

You can define variables and function using the whole set and libraries of python.
Some primitives are provided in the extensions for writing easily the menus and interacting with the user. The specific functions are described below.
Example of functions

and we get :
# !!! ERROR : COULD NOT *IMPORT NODE HERE : *import FENETRES/tests pour le notepad, modifier des trucs/some local code for the application

1.9.2. Definition of a menu

A menu is a list of menu_items. A menu_item can be :
  • "SEP" a separator
  • ["text", function_name] The text is displayed in the menu, and if choosen the function is called.
  • ["some text", list of menu_items]

Example
IN KM2
IN PYTHON

Attach the new menu to the menu bar
Result Now, the main menubar of KM2 has new dropdown menus :

1.9.3. Definition of a specific window


APPLICATION

We show here how to build an application integrated in KM2, but with its own buttons, functions, etc.

1.10. A complete example

1.10.1. The objective

The objective is to have an independant window such as :
we have :
  • a menubar with sub menus
  • a set of buttons, which activate changes in the text
  • an entry line
  • a notepad for the text
  • A frame with 2 parts
    • a large button "CLOSE ALL"
    • A second notepad, which should resizable.

Some examples of behaviour :
  • if we press a button, the text of the entry is inserted into the notepad

1.10.2. Defining the window

We use the styles and all notations as defined earlier.
Then, the window can be defined using the following scheme :

We have added the precision that NO2 is resizable.
making a part of a window resizable is a complex endeavour in Tkinter, as there must be a global coherency in the hierarchy of frames and windows, no error in the numbering of rows and columns, etc.. And everything changes when the graphics is redrawn ! So there is a real need to provide intelligence in the making.
Also, it is very easy to change the appearance of the different parts, adding a button, etc.

This code transforms into :
# !!! ERROR : COULD NOT *IMPORT NODE HERE : *import FENETRES/tests pour le notepad, modifier des trucs/define the window


Now you may guess what is the most simple way of programming !

Finally we add a menu with the make_new_window () options, as described above.

1.10.3. Writing the functions


Now we need to develop some specific functions. For example :

and we get :
# !!! ERROR : COULD NOT *IMPORT NODE HERE : *import FENETRES/tests pour le notepad, modifier des trucs/some local code for the application

1.10.4. Running the example

screen shots :

Initial view

After a few clicks and resize of the window






...