Key shortcuts in source editor work as expected, but only with "Alt" key. Support...
authorŁukasz Rekucki <lrekucki@gmail.com>
Sat, 10 Apr 2010 23:44:04 +0000 (01:44 +0200)
committerŁukasz Rekucki <lrekucki@gmail.com>
Sat, 10 Apr 2010 23:44:04 +0000 (01:44 +0200)
12 files changed:
apps/toolbar/admin.py
apps/toolbar/fixtures/initial_data.yaml [new file with mode: 0644]
apps/toolbar/fixtures/toolbar.yaml [deleted file]
apps/toolbar/migrations/0001_initial.py [new file with mode: 0644]
apps/toolbar/migrations/0002_auto__del_field_button_key_mod__chg_field_button_key.py [new file with mode: 0644]
apps/toolbar/migrations/0003_button_key_rename_to_accesskey.py [new file with mode: 0644]
apps/toolbar/migrations/__init__.py [new file with mode: 0644]
apps/toolbar/models.py
apps/toolbar/templates/toolbar/button.html
apps/wiki/templates/wiki/document_details.html
platforma/static/js/wiki/main.js
platforma/static/js/wiki/source_editor.js

index 93fedbb..7edd26b 100644 (file)
@@ -5,46 +5,7 @@ from django.utils import simplejson as json
 
 from toolbar import models
 
-#class ButtonGroupAdmin(admin.ModelAdmin):
-#    list_display = ('name', 'slug', 'position',)
-#    search_fields = ('name', 'slug',)
-#    prepopulated_fields = {'slug': ('name',)}
-#    list_editable = ('position',)
-
-class KeyModSelector(forms.MultiWidget):
-    def __init__(self):
-        super(KeyModSelector, self).__init__(
-            [forms.CheckboxInput() for x in xrange(0, 3)])
-
-    def decompress(self, v):
-        if not v: v = 0
-        r = [(v & 0x01) != 0, (v & 0x02) != 0, (v & 0x04) != 0]
-        print "DECOMPRESS: " , v, repr(r)
-        return r
-
-    def format_output(self, widgets):
-        out = u''
-        out += u'<p>' + widgets[0] + u' Alt </p>'
-        out += u'<p>' + widgets[1] + u' Ctrl </p>'
-        out += u'<p>' + widgets[2] + u' Shift </p>'
-        return out
-
-class KeyModField(forms.MultiValueField):
-
-    def __init__(self):
-        super(KeyModField, self).__init__(\
-            fields = tuple(forms.BooleanField() for x in xrange(0, 3)), \
-            widget = KeyModSelector())
-
-    def compress(self, dl):
-        v = int(dl[0]) | (int(dl[1]) << 1) | (int(dl[2]) << 2)
-        print "COMPRESS", v
-        return v
-
-
 class ButtonAdminForm(forms.ModelForm):
-    key_mod = KeyModField()
-
     class Meta:
         model = models.Button
 
@@ -52,24 +13,16 @@ class ButtonAdminForm(forms.ModelForm):
         value = self.cleaned_data['params']
         try:
             return json.dumps(json.loads(value))
-        except Exception, e:
+        except ValueError, e:
             raise forms.ValidationError(e)
 
 class ButtonAdmin(admin.ModelAdmin):
     form = ButtonAdminForm
-    list_display = ('slug', 'label', 'tooltip', 'hotkey_name')
+    list_display = ('slug', 'label', 'tooltip', 'accesskey')
     list_display_links = ('slug',)
     list_editable = ('label', 'tooltip',)
     prepopulated_fields = {'slug': ('label',)}
 
 admin.site.register(models.Button, ButtonAdmin)
 admin.site.register(models.ButtonGroup)
-admin.site.register(models.Scriptlet)
-
-#class ButtonAdmin(admin.ModelAdmin):
-#    list_display = ('label', 'action', 'key', 'position',)
-#    list_filter = ('group',)
-#    search_fields = ('label', 'action', 'key',)
-#    filter_horizontal = ('group',)
-#    list_editable = ('position',)
-
+admin.site.register(models.Scriptlet)
\ No newline at end of file
diff --git a/apps/toolbar/fixtures/initial_data.yaml b/apps/toolbar/fixtures/initial_data.yaml
new file mode 100644 (file)
index 0000000..723732d
--- /dev/null
@@ -0,0 +1,895 @@
+-   fields: {name: Akapity, position: 0, slug: akapity}
+    model: toolbar.buttongroup
+    pk: 14
+-   fields: {name: Autokorekta, position: 0, slug: autokorekta}
+    model: toolbar.buttongroup
+    pk: 2
+-   fields: {name: Bloki, position: 0, slug: bloki}
+    model: toolbar.buttongroup
+    pk: 21
+-   fields: {name: 'Dramat ', position: 0, slug: dramat}
+    model: toolbar.buttongroup
+    pk: 12
+-   fields: {name: "Elementy pocz\u0105tkowe", position: 0, slug: elementy-poczatkowe}
+    model: toolbar.buttongroup
+    pk: 13
+-   fields: {name: Mastery, position: 0, slug: mastery}
+    model: toolbar.buttongroup
+    pk: 11
+-   fields: {name: "Nag\u0142\xF3wki", position: 0, slug: naglowki}
+    model: toolbar.buttongroup
+    pk: 1
+-   fields: {name: "Pocz\u0105tek dramatu", position: 0, slug: poczatek-dramatu}
+    model: toolbar.buttongroup
+    pk: 22
+-   fields: {name: Polecenia, position: 0, slug: polecenia}
+    model: toolbar.buttongroup
+    pk: 27
+-   fields: {name: Przypisy, position: 0, slug: przypisy}
+    model: toolbar.buttongroup
+    pk: 26
+-   fields: {name: Separatory, position: 0, slug: separatory}
+    model: toolbar.buttongroup
+    pk: 16
+-   fields: {name: Style znakowe, position: 0, slug: style-znakowe}
+    model: toolbar.buttongroup
+    pk: 15
+-   fields: {name: Wersy, position: 0, slug: wersy}
+    model: toolbar.buttongroup
+    pk: 17
+-   fields:
+        group: [14, 12]
+        accesskey: a
+        label: akapit
+        link: ''
+        params: '{"tag": "akap"}'
+        scriptlet: insert_tag
+        slug: akapit
+        tooltip: wstawia akapit
+    model: toolbar.button
+    pk: 39
+-   fields:
+        group: [14]
+        accesskey: ''
+        label: akapit cd.
+        link: ''
+        params: '{"tag": "akap_cd"}'
+        scriptlet: insert_tag
+        slug: akapit-cd
+        tooltip: "ci\u0105g dalszy akapitu po wewn\u0105trzakapitowym wtr\u0105ceniu"
+    model: toolbar.button
+    pk: 40
+-   fields:
+        group: [14]
+        accesskey: d
+        label: akapit dialogowy
+        link: ''
+        params: '{"tag": "akap_dialog"}'
+        scriptlet: insert_tag
+        slug: akapit-dialogowy
+        tooltip: wstawia akapit dialogowy
+    model: toolbar.button
+    pk: 41
+-   fields:
+        group: [1]
+        accesskey: ''
+        label: akt
+        link: ''
+        params: '{"tag": "akt"}'
+        scriptlet: insert_tag
+        slug: akt
+        tooltip: ''
+    model: toolbar.button
+    pk: 14
+-   fields:
+        group: [13]
+        accesskey: ''
+        label: autor
+        link: ''
+        params: '{"tag": "autor_utworu"}'
+        scriptlet: insert_tag
+        slug: autor
+        tooltip: ''
+    model: toolbar.button
+    pk: 32
+-   fields:
+        group: [2]
+        accesskey: ''
+        label: Podstawowa
+        link: ''
+        params: '[["fulltextregexp", {"exprs": [["\ufeff", ""], ["$[\\s]*\\d+[\\s]*^",
+            ""], ["-\\s*^", ""], ["\\,\\.\\.|\\.\\,\\.|\\.\\.\\,", "..."]]}], ["lineregexp",
+            {"exprs": [["^\\s+|\\s+$", ""], ["\\s+", " "], ["(,,)\\s+|\\s+(\")", "$1"],
+            ["(\\d)[\u2014-](\\d)", "$1--$2"], ["[\u2014]", "---"], ["<(/?)P([aert])",
+            "<$1p$2"], ["([^\\.])(\\s*)</p", "$1.$2</p"], ["([,\\.:;!\\?])([^\\s\\\\])",
+            "$1 $2"], ["([^\\s])\\s+([,\\.:;!\\?])", "$1$2"]]}]]'
+        scriptlet: macro
+        slug: basic_correction
+        tooltip: "Wykonuj\u0119 operacj\u0119 z novel-pages i poem-pages."
+    model: toolbar.button
+    pk: 4
+-   fields:
+        group: [2]
+        accesskey: ''
+        label: "zamiana cudzys\u0142ow\xF3w 1"
+        link: ''
+        params: '{"exprs": [["\u00ab|\u201e", ",,"], ["\u00bb", "\""], ["([^=])\"([\u0104\u0118\u00d3\u0141\u017b\u0179\u0106\u0143\u0105\u017c\u017a\u015b\u0144\u00f3\u0142\u0107\\w])",
+            "$1,,$2"], ["^\"([\u0104\u0118\u00d3\u0141\u017b\u0179\u0106\u0143\u0105\u017c\u017a\u015b\u0144\u00f3\u0142\u0107\\w])",
+            ",,$1"], ["(,,)\\s+|\\s+(\")", "$1"]]}'
+        scriptlet: lineregexp
+        slug: cudzyslow-francuski
+        tooltip: "zamiana \" na ,, oraz  \xABa\xBB na ,,a\""
+    model: toolbar.button
+    pk: 89
+-   fields:
+        group: [2]
+        accesskey: ''
+        label: "zamiana cudzys\u0142ow\xF3w 2"
+        link: ''
+        params: '{"exprs": [["\u00bb|\u201e", ",,"], ["\u00ab", "\""], ["([^=])\"([\u0104\u0118\u00d3\u0141\u017b\u0179\u0106\u0143\u0105\u017c\u017a\u015b\u0144\u00f3\u0142\u0107\\w])",
+            "$1,,$2"], ["^\"([\u0104\u0118\u00d3\u0141\u017b\u0179\u0106\u0143\u0105\u017c\u017a\u015b\u0144\u00f3\u0142\u0107\\w])",
+            ",,$1"], ["(,,)\\s+|\\s+(\")", "$1"]]}'
+        scriptlet: lineregexp
+        slug: cudzyslow-niemiecki
+        tooltip: "zamienia \" na ,, oraz \xBBa\xAB na ,,a\""
+    model: toolbar.button
+    pk: 77
+-   fields:
+        group: [1]
+        accesskey: ''
+        label: "cz\u0119\u015B\u0107/ksi\u0119ga"
+        link: ''
+        params: '{"tag": "naglowek_czesc"}'
+        scriptlet: insert_tag
+        slug: czesc
+        tooltip: ''
+    model: toolbar.button
+    pk: 10
+-   fields:
+        group: [13, 22]
+        accesskey: ''
+        label: dedykacja
+        link: ''
+        params: '{"tag": "dedykacja"}'
+        scriptlet: insert_tag
+        slug: dedykacja
+        tooltip: ''
+    model: toolbar.button
+    pk: 74
+-   fields:
+        group: [12]
+        accesskey: ''
+        label: didaskalia
+        link: ''
+        params: '{"tag": "didaskalia"}'
+        scriptlet: insert_tag
+        slug: didaskalia
+        tooltip: ''
+    model: toolbar.button
+    pk: 62
+-   fields:
+        group: [22]
+        accesskey: ''
+        label: "didaskalia pocz\u0105tkowe"
+        link: ''
+        params: '{"tag": "miejsce_czas"}'
+        scriptlet: insert_tag
+        slug: didaskalia-poczatkowe
+        tooltip: "komentarze wprowadzaj\u0105ce przed tekstem dramatu"
+    model: toolbar.button
+    pk: 79
+-   fields:
+        group: [12]
+        accesskey: ''
+        label: didaskalia tekstowe
+        link: ''
+        params: '{"tag": "didask_tekst"}'
+        scriptlet: insert_tag
+        slug: didaskalia-tekstowe
+        tooltip: "didaskalia umieszczone w obr\u0119bie innego tekstu"
+    model: toolbar.button
+    pk: 63
+-   fields:
+        group: [21]
+        accesskey: ''
+        label: "d\u0142ugi cyt. poet."
+        link: ''
+        params: '{"tag": "poezja_cyt"}'
+        scriptlet: insert_tag
+        slug: dlugi-cyt-poet
+        tooltip: "d\u0142ugi cytat wierszowany wyr\xF3\u017Cniony sk\u0142adem"
+    model: toolbar.button
+    pk: 67
+-   fields:
+        group: [21]
+        accesskey: ''
+        label: "d\u0142ugi cytat"
+        link: ''
+        params: '{"tag": "dlugi_cyt"}'
+        scriptlet: insert_tag
+        slug: dlugi-cytat
+        tooltip: "d\u0142ugi cytat wyr\xF3\u017Cniony sk\u0142adem"
+    model: toolbar.button
+    pk: 42
+-   fields:
+        group: [11]
+        accesskey: ''
+        label: dramat wiersz.
+        link: ''
+        params: '{"tag": "dramat_wierszowany_l"}'
+        scriptlet: insert_tag
+        slug: dramat-wiersz
+        tooltip: ''
+    model: toolbar.button
+    pk: 20
+-   fields:
+        group: [11]
+        accesskey: ''
+        label: "dramat wiersz./w. \u0142am"
+        link: ''
+        params: '{"tag": "dramat_wierszowany_lp"}'
+        scriptlet: insert_tag
+        slug: dramat-wiersz-w-lam
+        tooltip: "dramat wierszowany o zw\u0119\u017Conej szeroko\u015Bci \u0142amu"
+    model: toolbar.button
+    pk: 22
+-   fields:
+        group: [11]
+        accesskey: ''
+        label: "dramat wsp\xF3\u0142czesny"
+        link: ''
+        params: '{"tag": "dramat_wspolczesny"}'
+        scriptlet: insert_tag
+        slug: dramat-wspolczesny
+        tooltip: "dramat wsp\xF3\u0142czesny (proz\u0105)"
+    model: toolbar.button
+    pk: 21
+-   fields:
+        group: [13]
+        accesskey: ''
+        label: "dzie\u0142o nadrz\u0119dne"
+        link: ''
+        params: '{"tag": "dzielo_nadrzedne"}'
+        scriptlet: insert_tag
+        slug: dzielo-nadrzedne
+        tooltip: ''
+    model: toolbar.button
+    pk: 38
+-   fields:
+        group: [27]
+        accesskey: ''
+        label: extra
+        link: ''
+        params: '{"tag": "extra"}'
+        scriptlet: insert_tag
+        slug: extra
+        tooltip: "uwagi dotycz\u0105ce sk\u0142adu"
+    model: toolbar.button
+    pk: 96
+-   fields:
+        group: []
+        accesskey: ''
+        label: Wydrukuj
+        link: print/html
+        params: '[]'
+        scriptlet: insert_tag
+        slug: htmleditor-print
+        tooltip: ''
+    model: toolbar.button
+    pk: 87
+-   fields:
+        group: [12]
+        accesskey: k
+        label: kwestia
+        link: ''
+        params: '{"tag": "kwestia"}'
+        scriptlet: insert_tag
+        slug: kwestia
+        tooltip: "wstawia kwesti\u0119"
+    model: toolbar.button
+    pk: 82
+-   fields:
+        group: [11]
+        accesskey: ''
+        label: liryka
+        link: ''
+        params: '{"tag": "liryka_l"}'
+        scriptlet: insert_tag
+        slug: liryka
+        tooltip: ''
+    model: toolbar.button
+    pk: 23
+-   fields:
+        group: [11]
+        accesskey: ''
+        label: "liryka/w. \u0142am"
+        link: ''
+        params: '{"tag": "liryka_lp"}'
+        scriptlet: insert_tag
+        slug: liryka-w-lam
+        tooltip: "utw\xF3r liryczny o zw\u0119\u017Conej szeroko\u015Bci \u0142amu"
+    model: toolbar.button
+    pk: 24
+-   fields:
+        group: [22]
+        accesskey: ''
+        label: "lista os\xF3b"
+        link: ''
+        params: '{"tag": "lista_osob"}'
+        scriptlet: insert_tag
+        slug: lista-osob
+        tooltip: "lista os\xF3b poprzedzaj\u0105ca tekst dramatu"
+    model: toolbar.button
+    pk: 93
+-   fields:
+        group: [22]
+        accesskey: ''
+        label: 'typ osoby '
+        link: ''
+        params: '{"tag": "lista_osoba", "attrs": {"typ": ""}}'
+        scriptlet: insert_tag
+        slug: lista-osob-pole
+        tooltip: osoby z takim samym opisem
+    model: toolbar.button
+    pk: 78
+-   fields:
+        group: [15]
+        accesskey: ''
+        label: matemat.
+        link: ''
+        params: '{"tag": "mat"}'
+        scriptlet: insert_tag
+        slug: matemat
+        tooltip: "wyra\u017Cenia matematyczne lub zmienne symboliczne"
+    model: toolbar.button
+    pk: 47
+-   fields:
+        group: [13, 22]
+        accesskey: ''
+        label: motto
+        link: ''
+        params: '{"tag": "motto"}'
+        scriptlet: insert_tag
+        slug: motto
+        tooltip: ''
+    model: toolbar.button
+    pk: 75
+-   fields:
+        group: [13, 22]
+        accesskey: ''
+        label: motto podpis
+        link: ''
+        params: '{"tag": "motto_podpis"}'
+        scriptlet: insert_tag
+        slug: motto-podpis
+        tooltip: ''
+    model: toolbar.button
+    pk: 37
+-   fields:
+        group: [12]
+        accesskey: ''
+        label: "nag\u0142\xF3wek kwestii"
+        link: ''
+        params: '{"tag": "naglowek_osoba"}'
+        scriptlet: insert_tag
+        slug: naglowek-kwestii
+        tooltip: "nag\u0142\xF3wek kwestii - nazwa osoby"
+    model: toolbar.button
+    pk: 16
+-   fields:
+        group: [22]
+        accesskey: ''
+        label: "nag\u0142\xF3wek listy"
+        link: ''
+        params: '{"tag": "naglowek_listy"}'
+        scriptlet: insert_tag
+        slug: naglowek-listy
+        tooltip: "nag\u0142\xF3wek listy os\xF3b"
+    model: toolbar.button
+    pk: 94
+-   fields:
+        group: [13]
+        accesskey: ''
+        label: nazwa utworu
+        link: ''
+        params: '{"tag": "nazwa_utworu"}'
+        scriptlet: insert_tag
+        slug: nazwa-utworu
+        tooltip: ''
+    model: toolbar.button
+    pk: 33
+-   fields:
+        group: [13]
+        accesskey: ''
+        label: nota
+        link: ''
+        params: '{"tag": "nota"}'
+        scriptlet: insert_tag
+        slug: nota
+        tooltip: ''
+    model: toolbar.button
+    pk: 35
+-   fields:
+        group: [11]
+        accesskey: ''
+        label: opowiadanie
+        link: ''
+        params: '{"tag": "opowiadanie"}'
+        scriptlet: insert_tag
+        slug: opowiadanie
+        tooltip: ''
+    model: toolbar.button
+    pk: 18
+-   fields:
+        group: [12]
+        accesskey: b
+        label: osoba
+        link: ''
+        params: '{"tag": "osoba"}'
+        scriptlet: insert_tag
+        slug: osoba
+        tooltip: "wstawia nazw\u0119 osoby w didaskaliach"
+    model: toolbar.button
+    pk: 64
+-   fields:
+        group: [22]
+        accesskey: ''
+        label: osoba na liscie
+        link: ''
+        params: '{"tag": "lista_osoba"}'
+        scriptlet: insert_tag
+        slug: osoba-na-liscie
+        tooltip: "nazwa osoby na liscie os\xF3b"
+    model: toolbar.button
+    pk: 95
+-   fields:
+        group: [1]
+        accesskey: ''
+        label: "podrozdzia\u0142"
+        link: ''
+        params: '{"tag": "naglowek_podrozdzial"}'
+        scriptlet: insert_tag
+        slug: podrozdzial
+        tooltip: ''
+    model: toolbar.button
+    pk: 12
+-   fields:
+        group: [1]
+        accesskey: ''
+        label: "podtytu\u0142"
+        link: ''
+        params: '{"tag": "podtytul"}'
+        scriptlet: insert_tag
+        slug: podtytul
+        tooltip: ''
+    model: toolbar.button
+    pk: 34
+-   fields:
+        group: [11]
+        accesskey: ''
+        label: "powie\u015B\u0107"
+        link: ''
+        params: '{"tag": "powiesc"}'
+        scriptlet: insert_tag
+        slug: powiesc
+        tooltip: ''
+    model: toolbar.button
+    pk: 19
+-   fields:
+        group: []
+        accesskey: ''
+        label: Wydrukuj
+        link: print/xml
+        params: '[]'
+        scriptlet: insert_tag
+        slug: print-xml
+        tooltip: ''
+    model: toolbar.button
+    pk: 86
+-   fields:
+        group: [26]
+        accesskey: ''
+        label: przypis autorski
+        link: ''
+        params: '{"tag": "pa"}'
+        scriptlet: insert_tag
+        slug: przypis-autorski
+        tooltip: ''
+    model: toolbar.button
+    pk: 68
+-   fields:
+        group: [26]
+        accesskey: ''
+        label: przypis edytorski
+        link: ''
+        params: '{"tag": "pe"}'
+        scriptlet: insert_tag
+        slug: przypis-edytorski
+        tooltip: ''
+    model: toolbar.button
+    pk: 71
+-   fields:
+        group: [26]
+        accesskey: ''
+        label: przypis redaktorski
+        link: ''
+        params: '{"tag": "pr"}'
+        scriptlet: insert_tag
+        slug: przypis-redaktorski
+        tooltip: ''
+    model: toolbar.button
+    pk: 70
+-   fields:
+        group: [26]
+        accesskey: ''
+        label: "przypis t\u0142umacza"
+        link: ''
+        params: '{"tag": "pt"}'
+        scriptlet: insert_tag
+        slug: przypis-tlumacza
+        tooltip: ''
+    model: toolbar.button
+    pk: 69
+-   fields:
+        group: [1]
+        accesskey: ''
+        label: "rozdzia\u0142"
+        link: ''
+        params: '{"tag": "naglowek_rozdzial"}'
+        scriptlet: insert_tag
+        slug: rozdzial
+        tooltip: ''
+    model: toolbar.button
+    pk: 11
+-   fields:
+        group: [1]
+        accesskey: ''
+        label: scena
+        link: ''
+        params: '{"tag": "naglowek_scena"}'
+        scriptlet: insert_tag
+        slug: scena
+        tooltip: ''
+    model: toolbar.button
+    pk: 15
+-   fields:
+        group: [16]
+        accesskey: ''
+        label: asterysk
+        link: ''
+        params: '{"nocontent": "true", "tag": "sekcja_asterysk"}'
+        scriptlet: insert_tag
+        slug: sep-asterysk
+        tooltip: rozdzielenie partii tekstu asteryskiem
+    model: toolbar.button
+    pk: 54
+-   fields:
+        group: [16]
+        accesskey: ''
+        label: linia
+        link: ''
+        params: '{"nocontent": "true", "tag": "separator_linia"}'
+        scriptlet: insert_tag
+        slug: sep-linia
+        tooltip: "rozdzielenie partii tekstu pozioma lini\u0105"
+    model: toolbar.button
+    pk: 55
+-   fields:
+        group: [16]
+        accesskey: ''
+        label: "\u015Bwiat\u0142o"
+        link: ''
+        params: '{"nocontent": "true", "tag": "sekcja_swiatlo"}'
+        scriptlet: insert_tag
+        slug: sep-swiatlo
+        tooltip: "\u015Bwiat\u0142o rozdzielaj\u0105ce sekcje tekstu"
+    model: toolbar.button
+    pk: 53
+-   fields:
+        group: [15]
+        accesskey: ''
+        label: "s\u0142owo obce"
+        link: ''
+        params: '{"tag": "slowo_obce"}'
+        scriptlet: insert_tag
+        slug: slowo-obce
+        tooltip: "frazy w j\u0119zykach innych ni\u017C polski/definiendum w przypisie"
+    model: toolbar.button
+    pk: 46
+-   fields:
+        group: [1]
+        accesskey: ''
+        label: "\u015Br\xF3dtytu\u0142"
+        link: ''
+        params: '{"tag": "srodtytul"}'
+        scriptlet: insert_tag
+        slug: srodtytul
+        tooltip: ''
+    model: toolbar.button
+    pk: 13
+-   fields:
+        group: [2]
+        accesskey: ''
+        label: "Usu\u0144 spacj\u0119"
+        link: ''
+        params: '{"exprs": [["^\\s+|\\s+$", ""], ["\\s+", " "], ["(,,)\\s+", "$1"],
+            ["\\s+(\")", "$1"]]}'
+        scriptlet: lineregexp
+        slug: strip_whitespace
+        tooltip: "Usuwa zb\u0119dne spacj\u0119 z dokumentu."
+    model: toolbar.button
+    pk: 3
+-   fields:
+        group: [12, 17]
+        accesskey: s
+        label: strofa
+        link: ''
+        params: '{"tag": "strofa"}'
+        scriptlet: insert_stanza
+        slug: strofa
+        tooltip: "wstawia strof\u0119"
+    model: toolbar.button
+    pk: 81
+-   fields:
+        group: [11]
+        accesskey: ''
+        label: "tag g\u0142\xF3wny"
+        link: ''
+        params: '{"tag": "utwor"}'
+        scriptlet: insert_tag
+        slug: tag-glowny
+        tooltip: ''
+    model: toolbar.button
+    pk: 17
+-   fields:
+        group: [2]
+        accesskey: u
+        label: "A<sup>\u2193</sup>"
+        link: ''
+        params: '[]'
+        scriptlet: lowercase
+        slug: tolowercase
+        tooltip: "Zamie\u0144 wielkie litery na ma\u0142e"
+    model: toolbar.button
+    pk: 76
+-   fields:
+        group: [15]
+        accesskey: ''
+        label: "tytu\u0142 dzie\u0142a"
+        link: ''
+        params: '{"tag": "tytul_dziela"}'
+        scriptlet: insert_tag
+        slug: tytul-dziela
+        tooltip: ''
+    model: toolbar.button
+    pk: 92
+-   fields:
+        group: [15]
+        accesskey: ''
+        label: "tytu\u0142 dzie\u0142a typ 1"
+        link: ''
+        params: '{"tag": "tytul_dziela", "attrs": {"typ": "1"}}'
+        scriptlet: insert_tag
+        slug: tytul-dziela-typ
+        tooltip: "tytu\u0142 dzie\u0142a w cytowanym tytule dzie\u0142a"
+    model: toolbar.button
+    pk: 45
+-   fields:
+        group: [27]
+        accesskey: ''
+        label: uwaga
+        link: ''
+        params: '{"tag": "uwaga"}'
+        scriptlet: insert_tag
+        slug: uwaga
+        tooltip: 'uwagi redaktorsko-korektorskie '
+    model: toolbar.button
+    pk: 51
+-   fields:
+        group: [14, 17]
+        accesskey: ''
+        label: wers akap.
+        link: ''
+        params: '{"tag": "wers_akap"}'
+        scriptlet: insert_tag
+        slug: wers-akap
+        tooltip: "wers rozpoczynaj\u0105cy si\u0119 wci\u0119ciem akapitowym"
+    model: toolbar.button
+    pk: 83
+-   fields:
+        group: [12, 17]
+        accesskey: ''
+        label: wers cd.
+        link: ''
+        params: '{"tag": "wers_cd"}'
+        scriptlet: insert_tag
+        slug: wers-cd
+        tooltip: "cz\u0119\u015B\u0107 wersu przeniesiona do innego wiersza"
+    model: toolbar.button
+    pk: 85
+-   fields:
+        group: [12, 17]
+        accesskey: w
+        label: "wers mocno wci\u0119ty"
+        link: ''
+        params: '{"tag": "wers_wciety", "attrs": {"typ": ""}}'
+        scriptlet: insert_tag
+        slug: wers-mocno-wciety
+        tooltip: "argumenty wersu wci\u0119tego: od 2 do 6"
+    model: toolbar.button
+    pk: 84
+-   fields:
+        group: [12, 17]
+        accesskey: q
+        label: "wers wci\u0119ty"
+        link: ''
+        params: '{"tag": "wers_wciety", "attrs": {"typ": "1"}}'
+        scriptlet: insert_tag
+        slug: wers-wciety
+        tooltip: "wstawia wers wci\u0119ty"
+    model: toolbar.button
+    pk: 91
+-   fields:
+        group: [15]
+        accesskey: ''
+        label: www
+        link: ''
+        params: '{"tag": "www"}'
+        scriptlet: insert_tag
+        slug: www
+        tooltip: ''
+    model: toolbar.button
+    pk: 48
+-   fields:
+        group: [15]
+        accesskey: ''
+        label: "wyr\xF3\u017Cnienie"
+        link: ''
+        params: '{"tag": "wyroznienie"}'
+        scriptlet: insert_tag
+        slug: wyroznienie
+        tooltip: "wyr\xF3\u017Cnienie autorskie"
+    model: toolbar.button
+    pk: 44
+-   fields:
+        group: [11]
+        accesskey: ''
+        label: wywiad
+        link: ''
+        params: '{"tag": "wywiad"}'
+        scriptlet: insert_tag
+        slug: wywiad
+        tooltip: ''
+    model: toolbar.button
+    pk: 25
+-   fields:
+        group: [21]
+        accesskey: ''
+        label: "wywiad odpowied\u017A"
+        link: ''
+        params: '{"tag": "wywiad_odp"}'
+        scriptlet: insert_tag
+        slug: wywiad-odpowiedz
+        tooltip: ''
+    model: toolbar.button
+    pk: 73
+-   fields:
+        group: [21]
+        accesskey: ''
+        label: wywiad pytanie
+        link: ''
+        params: '{"tag": "wywiad_pyt"}'
+        scriptlet: insert_tag
+        slug: wywiad-pytanie
+        tooltip: ''
+    model: toolbar.button
+    pk: 72
+-   fields:
+        group: [2]
+        accesskey: ''
+        label: "Zamie\u0144 dywiz"
+        link: ''
+        params: '{"exprs": [["(\\s)-(\\s)", "$1---$2"], ["^(\\s*)-(\\s)", "$1---$2"],
+            ["(\\s)-(\\s*)$", "$1---$2"], ["(\\d)[\u2014\u2013\u2010-](\\d)", "$1--$2"],
+            ["\u2014\u2013\u2010", "---"]]}'
+        scriptlet: lineregexp
+        slug: zamien_dywiz
+        tooltip: "Zamienia '\u2014' na '---', oraz '1\u20142' na '1--2'."
+    model: toolbar.button
+    pk: 2
+-   fields:
+        group: [16]
+        accesskey: ''
+        label: "zast\u0119pnik wersu"
+        link: ''
+        params: '{"tag": "zastepnik_wersu"}'
+        scriptlet: insert_tag
+        slug: zastepnik-wersu
+        tooltip: wykropkowanie wersu
+    model: toolbar.button
+    pk: 56
+-   fields: {code: "var texteditor = panel.texteditor;\nvar text = texteditor.selection();\n\
+            var start_tag = '<'+params.tag;\nfor (var attr in params.attrs) {\n  \
+            \  start_tag += ' '+attr+'=\"' + params.attrs[attr] + '\"';\n};\nstart_tag\
+            \ += '>';\nvar end_tag = '</'+params.tag+'>';\n\nif(text.length > 0) {\n\
+            // tokenize\nvar output = ''\nvar token = ''\nfor(var index=0; index <\
+            \ text.length; index++)\n{\n    if (text[index].match(/\\s/)) { // whitespace\n\
+            \        token += text[index];\n    }\n    else { // character\n     \
+            \   output += token;\n        if(output == token) output += start_tag;\n\
+            \        token = ''\n        output += text[index];\n    }\n}\n\nif( output[output.length-1]\
+            \ == '\\\\' ) {\n    output = output.substr(0, output.length-1) + end_tag\
+            \ + '\\\\';\n} else {\n    output += end_tag;\n}\noutput += token;\n}\n\
+            else {\n output = start_tag + end_tag;\n}\n\ntexteditor.replaceSelection(output);\n\
+            \nif (text.length == 0) {\n    var pos = texteditor.cursorPosition();\n\
+            \    texteditor.selectLines(pos.line, pos.character + params.tag.length\
+            \ + 2);\n}\n\npanel.fireEvent('contentChanged');"}
+    model: toolbar.scriptlet
+    pk: insert_tag
+-   fields: {code: "editor.showPopup('generic-info', 'Przetwarzanie zaznaczonego tekstu...',\
+            \ '', -1);\n\nvar cm = panel.texteditor;\nvar exprs = $.map(params.exprs,\
+            \ function(expr) {\n\n    var opts = \"g\";\n\n    if(expr.length > 2)\n\
+            \n        opts = expr[2];\n\n    return {rx: new RegExp(expr[0], opts),\
+            \ repl: expr[1]};\n\n});\n\n\n\nvar partial = true;\n\nvar text = cm.selection();\n\
+            \n\n\nif(!text) {\n\n    var cpos = cm.cursorPosition();\n\n    cpos.line\
+            \ = cm.lineNumber(cpos.line)\n\n    cm.selectLines(cm.firstLine(), 0,\
+            \ cm.lastLine(), 0);\n\n    text = cm.selection();\n\n    partial = false;\n\
+            \n}\n\n\n\nvar changed = 0;\nvar lines = text.split('\\n');\nvar lines\
+            \ = $.map(lines, function(line) { \n    var old_line = line;\n    $(exprs).each(function()\
+            \ { \n        var expr = this;\n        line = line.replace(expr.rx, expr.repl);\n\
+            \    });\n\n    if(old_line != line) changed += 1;\n    return line;\n\
+            });\n\nif(changed > 0) \n{\n    cm.replaceSelection( lines.join('\\n')\
+            \ );\n    panel.fireEvent('contentChanged');\n    editor.showPopup('generic-yes',\
+            \ 'Zmieniono ' + changed + ' linii.', 1500);\n    editor.advancePopupQueue();\n\
+            }\nelse {\n    editor.showPopup('generic-info',  'Brak zmian w tek\u015B\
+            cie', 1500);\n    editor.advancePopupQueue();\n}\n\nif(!partial)\n   \
+            \ cm.selectLines( cm.nthLine(cpos.line), cpos.character )"}
+    model: toolbar.scriptlet
+    pk: lineregexp
+-   fields: {code: "editor.showPopup('generic-info', 'Przetwarzanie zaznaczonego tekstu...',\
+            \ '', -1);\n$.log(editor, panel, params);\nvar cm = panel.texteditor;\n\
+            var exprs = $.map(params.exprs, function(expr) {\n    var opts = \"mg\"\
+            ;\n    if(expr.length > 2)\n        opts = expr[2];\n\n    return {rx:\
+            \ new RegExp(expr[0], opts), repl: expr[1]};\n});\n\nvar partial = true;\n\
+            var text = cm.selection();\n\nif(!text) {\n    var cpos = cm.cursorPosition();\n\
+            \    cpos.line = cm.lineNumber(cpos.line)\n    cm.selectLines(cm.firstLine(),\
+            \ 0, cm.lastLine(), 0);\n\n    text = cm.selection();\n    partial = false;\n\
+            }\n\nvar original = text;\n$(exprs).each(function() { \n    text = text.replace(this.rx,\
+            \ this.repl);\n});\n\nif( original != text) \n{    \n    cm.replaceSelection(text);\n\
+            \    panel.fireEvent('contentChanged');\n    editor.showPopup('generic-yes',\
+            \ 'Zmieniono tekst' );\n    editor.advancePopupQueue();\n}\nelse {\n \
+            \   editor.showPopup('generic-info', 'Brak zmian w tek\u015Bcie.');\n\
+            \    editor.advancePopupQueue();\n}\n\nif(!partial) {\n    cm.selectLines(\
+            \ cm.nthLine(cpos.line), cpos.character );\n}"}
+    model: toolbar.scriptlet
+    pk: fulltextregexp
+-   fields: {code: "$(params).each(function() {\n    $.log(this[0], this[1]);\n  \
+            \  editor.callScriptlet(this[0], panel, this[1]);\n\n});"}
+    model: toolbar.scriptlet
+    pk: macro
+-   fields: {code: "var cm = panel.texteditor;\r\nvar text = cm.selection();\r\n\r\
+            \nif(!text) return;\r\nvar repl = '';\r\nvar lcase = text.toLowerCase();\r\
+            \nvar ucase = text.toUpperCase();\r\n\r\nif(lcase == text) repl = ucase;\
+            \ /* was lowercase */\r\nelse if(ucase != text) repl = lcase; /* neither\
+            \ lower- or upper-case */\r\nelse { /* upper case -> title-case */\r\n\
+            \   var words = $(lcase.split(/\\s/)).map(function() { \r\n        if(this.length\
+            \ > 0) { return this[0].toUpperCase() + this.slice(1); } else { return\
+            \ ''}\r\n   }); \r\n   repl = words.join(' ');\r\n} \r\n\r\nif(repl !=\
+            \ text) {\r\n    cm.replaceSelection(repl);\r\n    panel.fireEvent('contentChanged');\r\
+            \n};"}
+    model: toolbar.scriptlet
+    pk: lowercase
+-   fields: {code: "var texteditor = panel.texteditor;\r\nvar text = texteditor.selection();\r\
+            \n\r\nif(text) {\r\n  var verses = text.split('\\n');\r\n  var text =\
+            \ ''; var buf = ''; var ebuf = '';\r\n  var first = true;\r\n\r\n  for(var\
+            \ i=0;  i < verses.length; i++) {\r\n    verse = verses[i].replace(/^\\\
+            s+/, \"\").replace(/\\s+$/, \"\");   \r\n    if(verse) {\r\n      text\
+            \ += (buf ? buf + '/\\n' : '') + ebuf;\r\n      buf = (first ? '<strofa>\\\
+            n' : '') + verses[i];\r\n      ebuf = '';\r\n      first = false;\r\n\
+            \    } else {    \r\n      ebuf += '\\n' + verses[i];\r\n    }\r\n  };\r\
+            \n  text = text + buf + '\\n</strofa>' + ebuf; \r\n  texteditor.replaceSelection(text);\r\
+            \n}\r\n\r\nif (!text) {\r\n    var pos = texteditor.cursorPosition();\r\
+            \n    texteditor.selectLines(pos.line, pos.character + 6 + 2);\r\n}\r\n\
+            \r\n\r\n\r\n\r\n\r\n\r\n\r\npanel.fireEvent('contentChanged');"}
+    model: toolbar.scriptlet
+    pk: insert_stanza
+
diff --git a/apps/toolbar/fixtures/toolbar.yaml b/apps/toolbar/fixtures/toolbar.yaml
deleted file mode 100644 (file)
index bcc039f..0000000
+++ /dev/null
@@ -1,964 +0,0 @@
--   fields: {name: Akapity, position: 0, slug: akapity}
-    model: toolbar.buttongroup
-    pk: 14
--   fields: {name: Autokorekta, position: 0, slug: autokorekta}
-    model: toolbar.buttongroup
-    pk: 2
--   fields: {name: Bloki, position: 0, slug: bloki}
-    model: toolbar.buttongroup
-    pk: 21
--   fields: {name: 'Dramat ', position: 0, slug: dramat}
-    model: toolbar.buttongroup
-    pk: 12
--   fields: {name: "Elementy pocz\u0105tkowe", position: 0, slug: elementy-poczatkowe}
-    model: toolbar.buttongroup
-    pk: 13
--   fields: {name: Mastery, position: 0, slug: mastery}
-    model: toolbar.buttongroup
-    pk: 11
--   fields: {name: "Nag\u0142\xF3wki", position: 0, slug: naglowki}
-    model: toolbar.buttongroup
-    pk: 1
--   fields: {name: "Pocz\u0105tek dramatu", position: 0, slug: poczatek-dramatu}
-    model: toolbar.buttongroup
-    pk: 22
--   fields: {name: Polecenia, position: 0, slug: polecenia}
-    model: toolbar.buttongroup
-    pk: 27
--   fields: {name: Przypisy, position: 0, slug: przypisy}
-    model: toolbar.buttongroup
-    pk: 26
--   fields: {name: Separatory, position: 0, slug: separatory}
-    model: toolbar.buttongroup
-    pk: 16
--   fields: {name: Style znakowe, position: 0, slug: style-znakowe}
-    model: toolbar.buttongroup
-    pk: 15
--   fields: {name: Wersy, position: 0, slug: wersy}
-    model: toolbar.buttongroup
-    pk: 17
--   fields:
-        group: [14, 12]
-        key: a
-        key_mod: 1
-        label: akapit
-        link: ''
-        params: '{"tag": "akap"}'
-        scriptlet: insert_tag
-        slug: akapit
-        tooltip: wstawia akapit
-    model: toolbar.button
-    pk: 39
--   fields:
-        group: [14]
-        key: ''
-        key_mod: 0
-        label: akapit cd.
-        link: ''
-        params: '{"tag": "akap_cd"}'
-        scriptlet: insert_tag
-        slug: akapit-cd
-        tooltip: "ci\u0105g dalszy akapitu po wewn\u0105trzakapitowym wtr\u0105ceniu"
-    model: toolbar.button
-    pk: 40
--   fields:
-        group: [14]
-        key: d
-        key_mod: 1
-        label: akapit dialogowy
-        link: ''
-        params: '{"tag": "akap_dialog"}'
-        scriptlet: insert_tag
-        slug: akapit-dialogowy
-        tooltip: wstawia akapit dialogowy
-    model: toolbar.button
-    pk: 41
--   fields:
-        group: [1]
-        key: ''
-        key_mod: 0
-        label: akt
-        link: ''
-        params: '{"tag": "akt"}'
-        scriptlet: insert_tag
-        slug: akt
-        tooltip: ''
-    model: toolbar.button
-    pk: 14
--   fields:
-        group: [13]
-        key: ''
-        key_mod: 0
-        label: autor
-        link: ''
-        params: '{"tag": "autor_utworu"}'
-        scriptlet: insert_tag
-        slug: autor
-        tooltip: ''
-    model: toolbar.button
-    pk: 32
--   fields:
-        group: [2]
-        key: ''
-        key_mod: 0
-        label: Podstawowa
-        link: ''
-        params: '[["fulltextregexp", {"exprs": [["\ufeff", ""], ["$[\\s]*\\d+[\\s]*^",
-            ""], ["-\\s*^", ""], ["\\,\\.\\.|\\.\\,\\.|\\.\\.\\,", "..."]]}], ["lineregexp",
-            {"exprs": [["^\\s+|\\s+$", ""], ["\\s+", " "], ["(,,)\\s+|\\s+(\")", "$1"],
-            ["(\\d)[\u2014-](\\d)", "$1--$2"], ["[\u2014]", "---"], ["<(/?)P([aert])",
-            "<$1p$2"], ["([^\\.])(\\s*)</p", "$1.$2</p"], ["([,\\.:;!\\?])([^\\s\\\\])",
-            "$1 $2"], ["([^\\s])\\s+([,\\.:;!\\?])", "$1$2"]]}]]'
-        scriptlet: macro
-        slug: basic_correction
-        tooltip: "Wykonuj\u0119 operacj\u0119 z novel-pages i poem-pages."
-    model: toolbar.button
-    pk: 4
--   fields:
-        group: [2]
-        key: ''
-        key_mod: 0
-        label: "zamiana cudzys\u0142ow\xF3w 1"
-        link: ''
-        params: '{"exprs": [["\u00ab|\u201e", ",,"], ["\u00bb", "\""], ["([^=])\"([\u0104\u0118\u00d3\u0141\u017b\u0179\u0106\u0143\u0105\u017c\u017a\u015b\u0144\u00f3\u0142\u0107\\w])",
-            "$1,,$2"], ["^\"([\u0104\u0118\u00d3\u0141\u017b\u0179\u0106\u0143\u0105\u017c\u017a\u015b\u0144\u00f3\u0142\u0107\\w])",
-            ",,$1"], ["(,,)\\s+|\\s+(\")", "$1"]]}'
-        scriptlet: lineregexp
-        slug: cudzyslow-francuski
-        tooltip: "zamiana \" na ,, oraz  \xABa\xBB na ,,a\""
-    model: toolbar.button
-    pk: 89
--   fields:
-        group: [2]
-        key: ''
-        key_mod: 0
-        label: "zamiana cudzys\u0142ow\xF3w 2"
-        link: ''
-        params: '{"exprs": [["\u00bb|\u201e", ",,"], ["\u00ab", "\""], ["([^=])\"([\u0104\u0118\u00d3\u0141\u017b\u0179\u0106\u0143\u0105\u017c\u017a\u015b\u0144\u00f3\u0142\u0107\\w])",
-            "$1,,$2"], ["^\"([\u0104\u0118\u00d3\u0141\u017b\u0179\u0106\u0143\u0105\u017c\u017a\u015b\u0144\u00f3\u0142\u0107\\w])",
-            ",,$1"], ["(,,)\\s+|\\s+(\")", "$1"]]}'
-        scriptlet: lineregexp
-        slug: cudzyslow-niemiecki
-        tooltip: "zamienia \" na ,, oraz \xBBa\xAB na ,,a\""
-    model: toolbar.button
-    pk: 77
--   fields:
-        group: [1]
-        key: ''
-        key_mod: 0
-        label: "cz\u0119\u015B\u0107/ksi\u0119ga"
-        link: ''
-        params: '{"tag": "naglowek_czesc"}'
-        scriptlet: insert_tag
-        slug: czesc
-        tooltip: ''
-    model: toolbar.button
-    pk: 10
--   fields:
-        group: [13, 22]
-        key: ''
-        key_mod: 0
-        label: dedykacja
-        link: ''
-        params: '{"tag": "dedykacja"}'
-        scriptlet: insert_tag
-        slug: dedykacja
-        tooltip: ''
-    model: toolbar.button
-    pk: 74
--   fields:
-        group: [12]
-        key: ''
-        key_mod: 0
-        label: didaskalia
-        link: ''
-        params: '{"tag": "didaskalia"}'
-        scriptlet: insert_tag
-        slug: didaskalia
-        tooltip: ''
-    model: toolbar.button
-    pk: 62
--   fields:
-        group: [22]
-        key: ''
-        key_mod: 0
-        label: "didaskalia pocz\u0105tkowe"
-        link: ''
-        params: '{"tag": "miejsce_czas"}'
-        scriptlet: insert_tag
-        slug: didaskalia-poczatkowe
-        tooltip: "komentarze wprowadzaj\u0105ce przed tekstem dramatu"
-    model: toolbar.button
-    pk: 79
--   fields:
-        group: [12]
-        key: ''
-        key_mod: 0
-        label: didaskalia tekstowe
-        link: ''
-        params: '{"tag": "didask_tekst"}'
-        scriptlet: insert_tag
-        slug: didaskalia-tekstowe
-        tooltip: "didaskalia umieszczone w obr\u0119bie innego tekstu"
-    model: toolbar.button
-    pk: 63
--   fields:
-        group: [21]
-        key: ''
-        key_mod: 0
-        label: "d\u0142ugi cyt. poet."
-        link: ''
-        params: '{"tag": "poezja_cyt"}'
-        scriptlet: insert_tag
-        slug: dlugi-cyt-poet
-        tooltip: "d\u0142ugi cytat wierszowany wyr\xF3\u017Cniony sk\u0142adem"
-    model: toolbar.button
-    pk: 67
--   fields:
-        group: [21]
-        key: ''
-        key_mod: 0
-        label: "d\u0142ugi cytat"
-        link: ''
-        params: '{"tag": "dlugi_cyt"}'
-        scriptlet: insert_tag
-        slug: dlugi-cytat
-        tooltip: "d\u0142ugi cytat wyr\xF3\u017Cniony sk\u0142adem"
-    model: toolbar.button
-    pk: 42
--   fields:
-        group: [11]
-        key: ''
-        key_mod: 0
-        label: dramat wiersz.
-        link: ''
-        params: '{"tag": "dramat_wierszowany_l"}'
-        scriptlet: insert_tag
-        slug: dramat-wiersz
-        tooltip: ''
-    model: toolbar.button
-    pk: 20
--   fields:
-        group: [11]
-        key: ''
-        key_mod: 0
-        label: "dramat wiersz./w. \u0142am"
-        link: ''
-        params: '{"tag": "dramat_wierszowany_lp"}'
-        scriptlet: insert_tag
-        slug: dramat-wiersz-w-lam
-        tooltip: "dramat wierszowany o zw\u0119\u017Conej szeroko\u015Bci \u0142amu"
-    model: toolbar.button
-    pk: 22
--   fields:
-        group: [11]
-        key: ''
-        key_mod: 0
-        label: "dramat wsp\xF3\u0142czesny"
-        link: ''
-        params: '{"tag": "dramat_wspolczesny"}'
-        scriptlet: insert_tag
-        slug: dramat-wspolczesny
-        tooltip: "dramat wsp\xF3\u0142czesny (proz\u0105)"
-    model: toolbar.button
-    pk: 21
--   fields:
-        group: [13]
-        key: ''
-        key_mod: 0
-        label: "dzie\u0142o nadrz\u0119dne"
-        link: ''
-        params: '{"tag": "dzielo_nadrzedne"}'
-        scriptlet: insert_tag
-        slug: dzielo-nadrzedne
-        tooltip: ''
-    model: toolbar.button
-    pk: 38
--   fields:
-        group: [27]
-        key: ''
-        key_mod: 0
-        label: extra
-        link: ''
-        params: '{"tag": "extra"}'
-        scriptlet: insert_tag
-        slug: extra
-        tooltip: "uwagi dotycz\u0105ce sk\u0142adu"
-    model: toolbar.button
-    pk: 96
--   fields:
-        group: []
-        key: ''
-        key_mod: 0
-        label: Wydrukuj
-        link: print/html
-        params: '[]'
-        scriptlet: insert_tag
-        slug: htmleditor-print
-        tooltip: ''
-    model: toolbar.button
-    pk: 87
--   fields:
-        group: [12]
-        key: k
-        key_mod: 1
-        label: kwestia
-        link: ''
-        params: '{"tag": "kwestia"}'
-        scriptlet: insert_tag
-        slug: kwestia
-        tooltip: "wstawia kwesti\u0119"
-    model: toolbar.button
-    pk: 82
--   fields:
-        group: [11]
-        key: ''
-        key_mod: 0
-        label: liryka
-        link: ''
-        params: '{"tag": "liryka_l"}'
-        scriptlet: insert_tag
-        slug: liryka
-        tooltip: ''
-    model: toolbar.button
-    pk: 23
--   fields:
-        group: [11]
-        key: ''
-        key_mod: 0
-        label: "liryka/w. \u0142am"
-        link: ''
-        params: '{"tag": "liryka_lp"}'
-        scriptlet: insert_tag
-        slug: liryka-w-lam
-        tooltip: "utw\xF3r liryczny o zw\u0119\u017Conej szeroko\u015Bci \u0142amu"
-    model: toolbar.button
-    pk: 24
--   fields:
-        group: [22]
-        key: ''
-        key_mod: 0
-        label: "lista os\xF3b"
-        link: ''
-        params: '{"tag": "lista_osob"}'
-        scriptlet: insert_tag
-        slug: lista-osob
-        tooltip: "lista os\xF3b poprzedzaj\u0105ca tekst dramatu"
-    model: toolbar.button
-    pk: 93
--   fields:
-        group: [22]
-        key: ''
-        key_mod: 0
-        label: 'typ osoby '
-        link: ''
-        params: '{"tag": "lista_osoba", "attrs": {"typ": ""}}'
-        scriptlet: insert_tag
-        slug: lista-osob-pole
-        tooltip: osoby z takim samym opisem
-    model: toolbar.button
-    pk: 78
--   fields:
-        group: [15]
-        key: ''
-        key_mod: 0
-        label: matemat.
-        link: ''
-        params: '{"tag": "mat"}'
-        scriptlet: insert_tag
-        slug: matemat
-        tooltip: "wyra\u017Cenia matematyczne lub zmienne symboliczne"
-    model: toolbar.button
-    pk: 47
--   fields:
-        group: [13, 22]
-        key: ''
-        key_mod: 0
-        label: motto
-        link: ''
-        params: '{"tag": "motto"}'
-        scriptlet: insert_tag
-        slug: motto
-        tooltip: ''
-    model: toolbar.button
-    pk: 75
--   fields:
-        group: [13, 22]
-        key: ''
-        key_mod: 0
-        label: motto podpis
-        link: ''
-        params: '{"tag": "motto_podpis"}'
-        scriptlet: insert_tag
-        slug: motto-podpis
-        tooltip: ''
-    model: toolbar.button
-    pk: 37
--   fields:
-        group: [12]
-        key: ''
-        key_mod: 0
-        label: "nag\u0142\xF3wek kwestii"
-        link: ''
-        params: '{"tag": "naglowek_osoba"}'
-        scriptlet: insert_tag
-        slug: naglowek-kwestii
-        tooltip: "nag\u0142\xF3wek kwestii - nazwa osoby"
-    model: toolbar.button
-    pk: 16
--   fields:
-        group: [22]
-        key: ''
-        key_mod: 0
-        label: "nag\u0142\xF3wek listy"
-        link: ''
-        params: '{"tag": "naglowek_listy"}'
-        scriptlet: insert_tag
-        slug: naglowek-listy
-        tooltip: "nag\u0142\xF3wek listy os\xF3b"
-    model: toolbar.button
-    pk: 94
--   fields:
-        group: [13]
-        key: ''
-        key_mod: 0
-        label: nazwa utworu
-        link: ''
-        params: '{"tag": "nazwa_utworu"}'
-        scriptlet: insert_tag
-        slug: nazwa-utworu
-        tooltip: ''
-    model: toolbar.button
-    pk: 33
--   fields:
-        group: [13]
-        key: ''
-        key_mod: 0
-        label: nota
-        link: ''
-        params: '{"tag": "nota"}'
-        scriptlet: insert_tag
-        slug: nota
-        tooltip: ''
-    model: toolbar.button
-    pk: 35
--   fields:
-        group: [11]
-        key: ''
-        key_mod: 0
-        label: opowiadanie
-        link: ''
-        params: '{"tag": "opowiadanie"}'
-        scriptlet: insert_tag
-        slug: opowiadanie
-        tooltip: ''
-    model: toolbar.button
-    pk: 18
--   fields:
-        group: [12]
-        key: b
-        key_mod: 1
-        label: osoba
-        link: ''
-        params: '{"tag": "osoba"}'
-        scriptlet: insert_tag
-        slug: osoba
-        tooltip: "wstawia nazw\u0119 osoby w didaskaliach"
-    model: toolbar.button
-    pk: 64
--   fields:
-        group: [22]
-        key: ''
-        key_mod: 0
-        label: osoba na liscie
-        link: ''
-        params: '{"tag": "lista_osoba"}'
-        scriptlet: insert_tag
-        slug: osoba-na-liscie
-        tooltip: "nazwa osoby na liscie os\xF3b"
-    model: toolbar.button
-    pk: 95
--   fields:
-        group: [1]
-        key: ''
-        key_mod: 0
-        label: "podrozdzia\u0142"
-        link: ''
-        params: '{"tag": "naglowek_podrozdzial"}'
-        scriptlet: insert_tag
-        slug: podrozdzial
-        tooltip: ''
-    model: toolbar.button
-    pk: 12
--   fields:
-        group: [1]
-        key: ''
-        key_mod: 0
-        label: "podtytu\u0142"
-        link: ''
-        params: '{"tag": "podtytul"}'
-        scriptlet: insert_tag
-        slug: podtytul
-        tooltip: ''
-    model: toolbar.button
-    pk: 34
--   fields:
-        group: [11]
-        key: ''
-        key_mod: 0
-        label: "powie\u015B\u0107"
-        link: ''
-        params: '{"tag": "powiesc"}'
-        scriptlet: insert_tag
-        slug: powiesc
-        tooltip: ''
-    model: toolbar.button
-    pk: 19
--   fields:
-        group: []
-        key: ''
-        key_mod: 0
-        label: Wydrukuj
-        link: print/xml
-        params: '[]'
-        scriptlet: insert_tag
-        slug: print-xml
-        tooltip: ''
-    model: toolbar.button
-    pk: 86
--   fields:
-        group: [26]
-        key: ''
-        key_mod: 0
-        label: przypis autorski
-        link: ''
-        params: '{"tag": "pa"}'
-        scriptlet: insert_tag
-        slug: przypis-autorski
-        tooltip: ''
-    model: toolbar.button
-    pk: 68
--   fields:
-        group: [26]
-        key: ''
-        key_mod: 0
-        label: przypis edytorski
-        link: ''
-        params: '{"tag": "pe"}'
-        scriptlet: insert_tag
-        slug: przypis-edytorski
-        tooltip: ''
-    model: toolbar.button
-    pk: 71
--   fields:
-        group: [26]
-        key: ''
-        key_mod: 0
-        label: przypis redaktorski
-        link: ''
-        params: '{"tag": "pr"}'
-        scriptlet: insert_tag
-        slug: przypis-redaktorski
-        tooltip: ''
-    model: toolbar.button
-    pk: 70
--   fields:
-        group: [26]
-        key: ''
-        key_mod: 0
-        label: "przypis t\u0142umacza"
-        link: ''
-        params: '{"tag": "pt"}'
-        scriptlet: insert_tag
-        slug: przypis-tlumacza
-        tooltip: ''
-    model: toolbar.button
-    pk: 69
--   fields:
-        group: [1]
-        key: ''
-        key_mod: 0
-        label: "rozdzia\u0142"
-        link: ''
-        params: '{"tag": "naglowek_rozdzial"}'
-        scriptlet: insert_tag
-        slug: rozdzial
-        tooltip: ''
-    model: toolbar.button
-    pk: 11
--   fields:
-        group: [1]
-        key: ''
-        key_mod: 0
-        label: scena
-        link: ''
-        params: '{"tag": "naglowek_scena"}'
-        scriptlet: insert_tag
-        slug: scena
-        tooltip: ''
-    model: toolbar.button
-    pk: 15
--   fields:
-        group: [16]
-        key: ''
-        key_mod: 0
-        label: asterysk
-        link: ''
-        params: '{"nocontent": "true", "tag": "sekcja_asterysk"}'
-        scriptlet: insert_tag
-        slug: sep-asterysk
-        tooltip: rozdzielenie partii tekstu asteryskiem
-    model: toolbar.button
-    pk: 54
--   fields:
-        group: [16]
-        key: ''
-        key_mod: 0
-        label: linia
-        link: ''
-        params: '{"nocontent": "true", "tag": "separator_linia"}'
-        scriptlet: insert_tag
-        slug: sep-linia
-        tooltip: "rozdzielenie partii tekstu pozioma lini\u0105"
-    model: toolbar.button
-    pk: 55
--   fields:
-        group: [16]
-        key: ''
-        key_mod: 0
-        label: "\u015Bwiat\u0142o"
-        link: ''
-        params: '{"nocontent": "true", "tag": "sekcja_swiatlo"}'
-        scriptlet: insert_tag
-        slug: sep-swiatlo
-        tooltip: "\u015Bwiat\u0142o rozdzielaj\u0105ce sekcje tekstu"
-    model: toolbar.button
-    pk: 53
--   fields:
-        group: [15]
-        key: ''
-        key_mod: 0
-        label: "s\u0142owo obce"
-        link: ''
-        params: '{"tag": "slowo_obce"}'
-        scriptlet: insert_tag
-        slug: slowo-obce
-        tooltip: "frazy w j\u0119zykach innych ni\u017C polski/definiendum w przypisie"
-    model: toolbar.button
-    pk: 46
--   fields:
-        group: [1]
-        key: ''
-        key_mod: 0
-        label: "\u015Br\xF3dtytu\u0142"
-        link: ''
-        params: '{"tag": "srodtytul"}'
-        scriptlet: insert_tag
-        slug: srodtytul
-        tooltip: ''
-    model: toolbar.button
-    pk: 13
--   fields:
-        group: [2]
-        key: ''
-        key_mod: 0
-        label: "Usu\u0144 spacj\u0119"
-        link: ''
-        params: '{"exprs": [["^\\s+|\\s+$", ""], ["\\s+", " "], ["(,,)\\s+", "$1"],
-            ["\\s+(\")", "$1"]]}'
-        scriptlet: lineregexp
-        slug: strip_whitespace
-        tooltip: "Usuwa zb\u0119dne spacj\u0119 z dokumentu."
-    model: toolbar.button
-    pk: 3
--   fields:
-        group: [12, 17]
-        key: s
-        key_mod: 1
-        label: strofa
-        link: ''
-        params: '{"tag": "strofa"}'
-        scriptlet: insert_stanza
-        slug: strofa
-        tooltip: "wstawia strof\u0119"
-    model: toolbar.button
-    pk: 81
--   fields:
-        group: [11]
-        key: ''
-        key_mod: 0
-        label: "tag g\u0142\xF3wny"
-        link: ''
-        params: '{"tag": "utwor"}'
-        scriptlet: insert_tag
-        slug: tag-glowny
-        tooltip: ''
-    model: toolbar.button
-    pk: 17
--   fields:
-        group: [2]
-        key: u
-        key_mod: 5
-        label: "A<sup>\u2193</sup>"
-        link: ''
-        params: '[]'
-        scriptlet: lowercase
-        slug: tolowercase
-        tooltip: "Zamie\u0144 wielkie litery na ma\u0142e"
-    model: toolbar.button
-    pk: 76
--   fields:
-        group: [15]
-        key: ''
-        key_mod: 0
-        label: "tytu\u0142 dzie\u0142a"
-        link: ''
-        params: '{"tag": "tytul_dziela"}'
-        scriptlet: insert_tag
-        slug: tytul-dziela
-        tooltip: ''
-    model: toolbar.button
-    pk: 92
--   fields:
-        group: [15]
-        key: ''
-        key_mod: 0
-        label: "tytu\u0142 dzie\u0142a typ 1"
-        link: ''
-        params: '{"tag": "tytul_dziela", "attrs": {"typ": "1"}}'
-        scriptlet: insert_tag
-        slug: tytul-dziela-typ
-        tooltip: "tytu\u0142 dzie\u0142a w cytowanym tytule dzie\u0142a"
-    model: toolbar.button
-    pk: 45
--   fields:
-        group: [27]
-        key: ''
-        key_mod: 0
-        label: uwaga
-        link: ''
-        params: '{"tag": "uwaga"}'
-        scriptlet: insert_tag
-        slug: uwaga
-        tooltip: 'uwagi redaktorsko-korektorskie '
-    model: toolbar.button
-    pk: 51
--   fields:
-        group: [14, 17]
-        key: ''
-        key_mod: 0
-        label: wers akap.
-        link: ''
-        params: '{"tag": "wers_akap"}'
-        scriptlet: insert_tag
-        slug: wers-akap
-        tooltip: "wers rozpoczynaj\u0105cy si\u0119 wci\u0119ciem akapitowym"
-    model: toolbar.button
-    pk: 83
--   fields:
-        group: [12, 17]
-        key: ''
-        key_mod: 0
-        label: wers cd.
-        link: ''
-        params: '{"tag": "wers_cd"}'
-        scriptlet: insert_tag
-        slug: wers-cd
-        tooltip: "cz\u0119\u015B\u0107 wersu przeniesiona do innego wiersza"
-    model: toolbar.button
-    pk: 85
--   fields:
-        group: [12, 17]
-        key: w
-        key_mod: 1
-        label: "wers mocno wci\u0119ty"
-        link: ''
-        params: '{"tag": "wers_wciety", "attrs": {"typ": ""}}'
-        scriptlet: insert_tag
-        slug: wers-mocno-wciety
-        tooltip: "argumenty wersu wci\u0119tego: od 2 do 6"
-    model: toolbar.button
-    pk: 84
--   fields:
-        group: [12, 17]
-        key: q
-        key_mod: 1
-        label: "wers wci\u0119ty"
-        link: ''
-        params: '{"tag": "wers_wciety", "attrs": {"typ": "1"}}'
-        scriptlet: insert_tag
-        slug: wers-wciety
-        tooltip: "wstawia wers wci\u0119ty"
-    model: toolbar.button
-    pk: 91
--   fields:
-        group: [15]
-        key: ''
-        key_mod: 0
-        label: www
-        link: ''
-        params: '{"tag": "www"}'
-        scriptlet: insert_tag
-        slug: www
-        tooltip: ''
-    model: toolbar.button
-    pk: 48
--   fields:
-        group: [15]
-        key: ''
-        key_mod: 0
-        label: "wyr\xF3\u017Cnienie"
-        link: ''
-        params: '{"tag": "wyroznienie"}'
-        scriptlet: insert_tag
-        slug: wyroznienie
-        tooltip: "wyr\xF3\u017Cnienie autorskie"
-    model: toolbar.button
-    pk: 44
--   fields:
-        group: [11]
-        key: ''
-        key_mod: 0
-        label: wywiad
-        link: ''
-        params: '{"tag": "wywiad"}'
-        scriptlet: insert_tag
-        slug: wywiad
-        tooltip: ''
-    model: toolbar.button
-    pk: 25
--   fields:
-        group: [21]
-        key: ''
-        key_mod: 0
-        label: "wywiad odpowied\u017A"
-        link: ''
-        params: '{"tag": "wywiad_odp"}'
-        scriptlet: insert_tag
-        slug: wywiad-odpowiedz
-        tooltip: ''
-    model: toolbar.button
-    pk: 73
--   fields:
-        group: [21]
-        key: ''
-        key_mod: 0
-        label: wywiad pytanie
-        link: ''
-        params: '{"tag": "wywiad_pyt"}'
-        scriptlet: insert_tag
-        slug: wywiad-pytanie
-        tooltip: ''
-    model: toolbar.button
-    pk: 72
--   fields:
-        group: [2]
-        key: ''
-        key_mod: 0
-        label: "Zamie\u0144 dywiz"
-        link: ''
-        params: '{"exprs": [["(\\s)-(\\s)", "$1---$2"], ["^(\\s*)-(\\s)", "$1---$2"],
-            ["(\\s)-(\\s*)$", "$1---$2"], ["(\\d)[\u2014\u2013\u2010-](\\d)", "$1--$2"],
-            ["\u2014\u2013\u2010", "---"]]}'
-        scriptlet: lineregexp
-        slug: zamien_dywiz
-        tooltip: "Zamienia '\u2014' na '---', oraz '1\u20142' na '1--2'."
-    model: toolbar.button
-    pk: 2
--   fields:
-        group: [16]
-        key: ''
-        key_mod: 0
-        label: "zast\u0119pnik wersu"
-        link: ''
-        params: '{"tag": "zastepnik_wersu"}'
-        scriptlet: insert_tag
-        slug: zastepnik-wersu
-        tooltip: wykropkowanie wersu
-    model: toolbar.button
-    pk: 56
--   fields: {code: "var texteditor = panel.texteditor;\nvar text = texteditor.selection();\n\
-            var start_tag = '<'+params.tag;\nfor (var attr in params.attrs) {\n  \
-            \  start_tag += ' '+attr+'=\"' + params.attrs[attr] + '\"';\n};\nstart_tag\
-            \ += '>';\nvar end_tag = '</'+params.tag+'>';\n\nif(text.length > 0) {\n\
-            // tokenize\nvar output = ''\nvar token = ''\nfor(var index=0; index <\
-            \ text.length; index++)\n{\n    if (text[index].match(/\\s/)) { // whitespace\n\
-            \        token += text[index];\n    }\n    else { // character\n     \
-            \   output += token;\n        if(output == token) output += start_tag;\n\
-            \        token = ''\n        output += text[index];\n    }\n}\n\nif( output[output.length-1]\
-            \ == '\\\\' ) {\n    output = output.substr(0, output.length-1) + end_tag\
-            \ + '\\\\';\n} else {\n    output += end_tag;\n}\noutput += token;\n}\n\
-            else {\n output = start_tag + end_tag;\n}\n\ntexteditor.replaceSelection(output);\n\
-            \nif (text.length == 0) {\n    var pos = texteditor.cursorPosition();\n\
-            \    texteditor.selectLines(pos.line, pos.character + params.tag.length\
-            \ + 2);\n}\n\npanel.fireEvent('contentChanged');"}
-    model: toolbar.scriptlet
-    pk: insert_tag
--   fields: {code: "editor.showPopup('generic-info', 'Przetwarzanie zaznaczonego tekstu...',\
-            \ '', -1);\n\nvar cm = panel.texteditor;\nvar exprs = $.map(params.exprs,\
-            \ function(expr) {\n\n    var opts = \"g\";\n\n    if(expr.length > 2)\n\
-            \n        opts = expr[2];\n\n    return {rx: new RegExp(expr[0], opts),\
-            \ repl: expr[1]};\n\n});\n\n\n\nvar partial = true;\n\nvar text = cm.selection();\n\
-            \n\n\nif(!text) {\n\n    var cpos = cm.cursorPosition();\n\n    cpos.line\
-            \ = cm.lineNumber(cpos.line)\n\n    cm.selectLines(cm.firstLine(), 0,\
-            \ cm.lastLine(), 0);\n\n    text = cm.selection();\n\n    partial = false;\n\
-            \n}\n\n\n\nvar changed = 0;\nvar lines = text.split('\\n');\nvar lines\
-            \ = $.map(lines, function(line) { \n    var old_line = line;\n    $(exprs).each(function()\
-            \ { \n        var expr = this;\n        line = line.replace(expr.rx, expr.repl);\n\
-            \    });\n\n    if(old_line != line) changed += 1;\n    return line;\n\
-            });\n\nif(changed > 0) \n{\n    cm.replaceSelection( lines.join('\\n')\
-            \ );\n    panel.fireEvent('contentChanged');\n    editor.showPopup('generic-yes',\
-            \ 'Zmieniono ' + changed + ' linii.', 1500);\n    editor.advancePopupQueue();\n\
-            }\nelse {\n    editor.showPopup('generic-info',  'Brak zmian w tek\u015B\
-            cie', 1500);\n    editor.advancePopupQueue();\n}\n\nif(!partial)\n   \
-            \ cm.selectLines( cm.nthLine(cpos.line), cpos.character )"}
-    model: toolbar.scriptlet
-    pk: lineregexp
--   fields: {code: "editor.showPopup('generic-info', 'Przetwarzanie zaznaczonego tekstu...',\
-            \ '', -1);\n$.log(editor, panel, params);\nvar cm = panel.texteditor;\n\
-            var exprs = $.map(params.exprs, function(expr) {\n    var opts = \"mg\"\
-            ;\n    if(expr.length > 2)\n        opts = expr[2];\n\n    return {rx:\
-            \ new RegExp(expr[0], opts), repl: expr[1]};\n});\n\nvar partial = true;\n\
-            var text = cm.selection();\n\nif(!text) {\n    var cpos = cm.cursorPosition();\n\
-            \    cpos.line = cm.lineNumber(cpos.line)\n    cm.selectLines(cm.firstLine(),\
-            \ 0, cm.lastLine(), 0);\n\n    text = cm.selection();\n    partial = false;\n\
-            }\n\nvar original = text;\n$(exprs).each(function() { \n    text = text.replace(this.rx,\
-            \ this.repl);\n});\n\nif( original != text) \n{    \n    cm.replaceSelection(text);\n\
-            \    panel.fireEvent('contentChanged');\n    editor.showPopup('generic-yes',\
-            \ 'Zmieniono tekst' );\n    editor.advancePopupQueue();\n}\nelse {\n \
-            \   editor.showPopup('generic-info', 'Brak zmian w tek\u015Bcie.');\n\
-            \    editor.advancePopupQueue();\n}\n\nif(!partial) {\n    cm.selectLines(\
-            \ cm.nthLine(cpos.line), cpos.character );\n}"}
-    model: toolbar.scriptlet
-    pk: fulltextregexp
--   fields: {code: "$(params).each(function() {\n    $.log(this[0], this[1]);\n  \
-            \  editor.callScriptlet(this[0], panel, this[1]);\n\n});"}
-    model: toolbar.scriptlet
-    pk: macro
--   fields: {code: "var cm = panel.texteditor;\r\nvar text = cm.selection();\r\n\r\
-            \nif(!text) return;\r\nvar repl = '';\r\nvar lcase = text.toLowerCase();\r\
-            \nvar ucase = text.toUpperCase();\r\n\r\nif(lcase == text) repl = ucase;\
-            \ /* was lowercase */\r\nelse if(ucase != text) repl = lcase; /* neither\
-            \ lower- or upper-case */\r\nelse { /* upper case -> title-case */\r\n\
-            \   var words = $(lcase.split(/\\s/)).map(function() { \r\n        if(this.length\
-            \ > 0) { return this[0].toUpperCase() + this.slice(1); } else { return\
-            \ ''}\r\n   }); \r\n   repl = words.join(' ');\r\n} \r\n\r\nif(repl !=\
-            \ text) {\r\n    cm.replaceSelection(repl);\r\n    panel.fireEvent('contentChanged');\r\
-            \n};"}
-    model: toolbar.scriptlet
-    pk: lowercase
--   fields: {code: "var texteditor = panel.texteditor;\r\nvar text = texteditor.selection();\r\
-            \n\r\nif(text) {\r\n  var verses = text.split('\\n');\r\n  var text =\
-            \ ''; var buf = ''; var ebuf = '';\r\n  var first = true;\r\n\r\n  for(var\
-            \ i=0;  i < verses.length; i++) {\r\n    verse = verses[i].replace(/^\\\
-            s+/, \"\").replace(/\\s+$/, \"\");   \r\n    if(verse) {\r\n      text\
-            \ += (buf ? buf + '/\\n' : '') + ebuf;\r\n      buf = (first ? '<strofa>\\\
-            n' : '') + verses[i];\r\n      ebuf = '';\r\n      first = false;\r\n\
-            \    } else {    \r\n      ebuf += '\\n' + verses[i];\r\n    }\r\n  };\r\
-            \n  text = text + buf + '\\n</strofa>' + ebuf; \r\n  texteditor.replaceSelection(text);\r\
-            \n}\r\n\r\nif (!text) {\r\n    var pos = texteditor.cursorPosition();\r\
-            \n    texteditor.selectLines(pos.line, pos.character + 6 + 2);\r\n}\r\n\
-            \r\n\r\n\r\n\r\n\r\n\r\n\r\npanel.fireEvent('contentChanged');"}
-    model: toolbar.scriptlet
-    pk: insert_stanza
-
diff --git a/apps/toolbar/migrations/0001_initial.py b/apps/toolbar/migrations/0001_initial.py
new file mode 100644 (file)
index 0000000..974ea66
--- /dev/null
@@ -0,0 +1,93 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+    
+    def forwards(self, orm):
+        
+        # Adding model 'ButtonGroup'
+        db.create_table('toolbar_buttongroup', (
+            ('position', self.gf('django.db.models.fields.IntegerField')(default=0)),
+            ('slug', self.gf('django.db.models.fields.SlugField')(max_length=50, db_index=True)),
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('name', self.gf('django.db.models.fields.CharField')(max_length=32)),
+        ))
+        db.send_create_signal('toolbar', ['ButtonGroup'])
+
+        # Adding model 'Button'
+        db.create_table('toolbar_button', (
+            ('key_mod', self.gf('django.db.models.fields.PositiveIntegerField')(default=1, blank=True)),
+            ('scriptlet', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['toolbar.Scriptlet'], null=True, blank=True)),
+            ('tooltip', self.gf('django.db.models.fields.CharField')(max_length=120, blank=True)),
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('link', self.gf('django.db.models.fields.CharField')(default='', max_length=256, blank=True)),
+            ('key', self.gf('django.db.models.fields.CharField')(max_length=1, blank=True)),
+            ('params', self.gf('django.db.models.fields.TextField')(default='[]')),
+            ('label', self.gf('django.db.models.fields.CharField')(max_length=32)),
+            ('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50, db_index=True)),
+        ))
+        db.send_create_signal('toolbar', ['Button'])
+
+        # Adding M2M table for field group on 'Button'
+        db.create_table('toolbar_button_group', (
+            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+            ('button', models.ForeignKey(orm['toolbar.button'], null=False)),
+            ('buttongroup', models.ForeignKey(orm['toolbar.buttongroup'], null=False))
+        ))
+        db.create_unique('toolbar_button_group', ['button_id', 'buttongroup_id'])
+
+        # Adding model 'Scriptlet'
+        db.create_table('toolbar_scriptlet', (
+            ('code', self.gf('django.db.models.fields.TextField')()),
+            ('name', self.gf('django.db.models.fields.CharField')(max_length=64, primary_key=True)),
+        ))
+        db.send_create_signal('toolbar', ['Scriptlet'])
+    
+    
+    def backwards(self, orm):
+        
+        # Deleting model 'ButtonGroup'
+        db.delete_table('toolbar_buttongroup')
+
+        # Deleting model 'Button'
+        db.delete_table('toolbar_button')
+
+        # Removing M2M table for field group on 'Button'
+        db.delete_table('toolbar_button_group')
+
+        # Deleting model 'Scriptlet'
+        db.delete_table('toolbar_scriptlet')
+    
+    
+    models = {
+        'toolbar.button': {
+            'Meta': {'object_name': 'Button'},
+            'group': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['toolbar.ButtonGroup']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'key': ('django.db.models.fields.CharField', [], {'max_length': '1', 'blank': 'True'}),
+            'key_mod': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'blank': 'True'}),
+            'label': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
+            'link': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '256', 'blank': 'True'}),
+            'params': ('django.db.models.fields.TextField', [], {'default': "'[]'"}),
+            'scriptlet': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['toolbar.Scriptlet']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}),
+            'tooltip': ('django.db.models.fields.CharField', [], {'max_length': '120', 'blank': 'True'})
+        },
+        'toolbar.buttongroup': {
+            'Meta': {'object_name': 'ButtonGroup'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
+            'position': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'})
+        },
+        'toolbar.scriptlet': {
+            'Meta': {'object_name': 'Scriptlet'},
+            'code': ('django.db.models.fields.TextField', [], {}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'primary_key': 'True'})
+        }
+    }
+    
+    complete_apps = ['toolbar']
diff --git a/apps/toolbar/migrations/0002_auto__del_field_button_key_mod__chg_field_button_key.py b/apps/toolbar/migrations/0002_auto__del_field_button_key_mod__chg_field_button_key.py
new file mode 100644 (file)
index 0000000..09ddd32
--- /dev/null
@@ -0,0 +1,52 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+    
+    def forwards(self, orm):
+        
+        # Deleting field 'Button.key_mod'
+        db.delete_column('toolbar_button', 'key_mod')
+
+        # Changing field 'Button.key'
+        db.alter_column('toolbar_button', 'key', self.gf('django.db.models.fields.CharField')(max_length=1, null=True))
+    
+    def backwards(self, orm):
+        
+        # Adding field 'Button.key_mod'
+        db.add_column('toolbar_button', 'key_mod', self.gf('django.db.models.fields.PositiveIntegerField')(default=1, blank=True), keep_default=False)
+
+        # Changing field 'Button.key'
+        db.alter_column('toolbar_button', 'key', self.gf('django.db.models.fields.CharField')(max_length=1, blank=True))    
+    
+    models = {
+        'toolbar.button': {
+            'Meta': {'object_name': 'Button'},
+            'group': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['toolbar.ButtonGroup']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'key': ('django.db.models.fields.CharField', [], {'max_length': '1', 'null': 'True'}),
+            'label': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
+            'link': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '256', 'blank': 'True'}),
+            'params': ('django.db.models.fields.TextField', [], {'default': "'[]'"}),
+            'scriptlet': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['toolbar.Scriptlet']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}),
+            'tooltip': ('django.db.models.fields.CharField', [], {'max_length': '120', 'blank': 'True'})
+        },
+        'toolbar.buttongroup': {
+            'Meta': {'object_name': 'ButtonGroup'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
+            'position': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'})
+        },
+        'toolbar.scriptlet': {
+            'Meta': {'object_name': 'Scriptlet'},
+            'code': ('django.db.models.fields.TextField', [], {}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'primary_key': 'True'})
+        }
+    }
+    
+    complete_apps = ['toolbar']
diff --git a/apps/toolbar/migrations/0003_button_key_rename_to_accesskey.py b/apps/toolbar/migrations/0003_button_key_rename_to_accesskey.py
new file mode 100644 (file)
index 0000000..0d2e906
--- /dev/null
@@ -0,0 +1,47 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+    
+    def forwards(self, orm):
+        
+        # Deleting field 'Button.key'
+        db.rename_column('toolbar_button', 'key', 'accesskey')
+
+    
+    
+    def backwards(self, orm):        
+        db.rename_column('toolbar_button', 'accesskey', 'key')
+    
+    
+    models = {
+        'toolbar.button': {
+            'Meta': {'object_name': 'Button'},
+            'accesskey': ('django.db.models.fields.CharField', [], {'max_length': '1', 'null': 'True'}),
+            'group': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['toolbar.ButtonGroup']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'label': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
+            'link': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '256', 'blank': 'True'}),
+            'params': ('django.db.models.fields.TextField', [], {'default': "'[]'"}),
+            'scriptlet': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['toolbar.Scriptlet']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}),
+            'tooltip': ('django.db.models.fields.CharField', [], {'max_length': '120', 'blank': 'True'})
+        },
+        'toolbar.buttongroup': {
+            'Meta': {'object_name': 'ButtonGroup'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
+            'position': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'})
+        },
+        'toolbar.scriptlet': {
+            'Meta': {'object_name': 'Scriptlet'},
+            'code': ('django.db.models.fields.TextField', [], {}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'primary_key': 'True'})
+        }
+    }
+    
+    complete_apps = ['toolbar']
diff --git a/apps/toolbar/migrations/__init__.py b/apps/toolbar/migrations/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
index 6a20263..d736c02 100644 (file)
@@ -56,8 +56,8 @@ class Button(models.Model):
     link = models.CharField(max_length = 256, blank = True, default = '')
 
     # ui related stuff
-    key = models.CharField(blank = True, max_length = 1)
-    key_mod = models.PositiveIntegerField(blank = True, default = 1)
+    accesskey = models.CharField(null = True, max_length = 1)
+        
     tooltip = models.CharField(blank = True, max_length = 120)
 
     # Why the button is restricted to have the same position in each group ?
@@ -68,32 +68,15 @@ class Button(models.Model):
         ordering = ('slug',)
         verbose_name, verbose_name_plural = _('button'), _('buttons')
 
-    @property
-    def hotkey_code(self):
-        return ord(self.key.upper()) | (self.key_mod << 8)
-
-    @property
-    def hotkey_name(self):
-        if not self.key:
-            return ''
-
-        mods = []
-        if self.key_mod & 0x01: mods.append('Alt')
-        if self.key_mod & 0x02: mods.append('Ctrl')
-        if self.key_mod & 0x04: mods.append('Shift')
-        mods.append(str(self.key))
-        return '[' + '+'.join(mods) + ']'
-
     @property
     def full_tooltip(self):
-        return self.tooltip + (' ' + self.hotkey_name if self.key else '')
+        return u"%s %s" % (self.tooltip, "[Alt+%s]" % self.accesskey if self.accesskey else "")
 
     def to_dict(self):
         return {
             'label': self.label,
-            'tooltip': (self.tooltip or '') + self.hotkey_name(),
-            'key': self.key,
-            'key_mod': self.key_mod,
+            'tooltip': self.tooltip,
+            'accesskey': self.accesskey,            
             'params': self.params,
             'scriptlet_id': self.scriptlet_id
         }
@@ -105,8 +88,5 @@ class Scriptlet(models.Model):
     name = models.CharField(max_length = 64, primary_key = True)
     code = models.TextField()
 
-    # TODO: add this later and remap code property to this
-    # code_min = models.TextField()
-
     def __unicode__(self):
         return _(u'javascript') + u':' + self.name
index 92c51a1..2ecb1ab 100644 (file)
@@ -4,9 +4,9 @@
 <button type="button"\r
        data-ui-action="{{ button.scriptlet_id }}"\r
        data-ui-action-params="{{ button.params|escape }}"\r
-        {% if button.key %}ui:hotkey="{{ button.hotkey_code }}"{% endif %}\r
-        {% if button.tooltip %}title="{{ button.full_tooltip }}"{% endif %} >\r
-        {{ button.label|safe }}\r
+       data-ui-accesskey="{{ button.accesskey }}"\r
+       {% if button.tooltip %}title="{{ button.full_tooltip }}"{% endif %} >\r
+       {{ button.label|safe }}\r
 </button>\r
 {% if button.link %}\r
 </a>\r
index cbed276..9031d19 100644 (file)
@@ -5,6 +5,7 @@
 {% load compressed %}
 {% compressed_css 'detail' %}
 {% endblock %}
+
 {% block extrabody %}
 <script type="text/javascript" charset="utf-8">
     var STATIC_URL = '{{STATIC_URL}}';
index ef127e3..9693ce2 100644 (file)
@@ -25,6 +25,10 @@ $(function()
                        doc: CurrentDocument
                });
                
+               $(document).keydown(function(event) {
+                       console.log("Received key:", event);
+               });
+               
                /* The save button */
         $('#save-button').click(function(event){
             event.preventDefault();
index 9ca3f64..9cfa510 100644 (file)
                                tabMode: 'spaces',
                                indentUnit: 0,
                                initCallback: function(){
+                                       
+                                        self.codemirror.grabKeys(function(event) {                     
+                                               if (event.button) {
+                                                       $(event.button).trigger('click');
+                                                       event.button = null;
+                                               }
+                                       }, function(event) {
+                                               /* CM reports characters 2 times - as event and as code */  
+                                               if((typeof event) != "object")
+                                                       return false;
+                                                       
+                                               if(!event.altKey)
+                                                       return false;   
+                                               
+                                               var c = String.fromCharCode(event.keyCode).toLowerCase();                                                       
+                                               var button = $("#source-editor button[data-ui-accesskey='"+c+"']");                                             
+                                               if(button.length == 0)
+                                                       return false;
+                                                       
+                                               /* it doesn't matter which button we pick - all do the same */
+                                               event.button = button[0];
+                                               return true;                                                                    
+                                       }); 
+                                       
                                        $('#source-editor .toolbar button').click(function(event){
                                                event.preventDefault();
                                                var params = eval("(" + $(this).attr('data-ui-action-params') + ")");