From: Ɓukasz Rekucki Date: Sat, 10 Apr 2010 23:44:04 +0000 (+0200) Subject: Key shortcuts in source editor work as expected, but only with "Alt" key. Support... X-Git-Url: https://git.mdrn.pl/redakcja.git/commitdiff_plain/58e0903a3f0e1e105a11638b18b588e9eb6a8b9e Key shortcuts in source editor work as expected, but only with "Alt" key. Support for other modifiers was removed as it didn't really worked too good on all browsers. --- diff --git a/apps/toolbar/admin.py b/apps/toolbar/admin.py index 93fedbba..7edd26b5 100644 --- a/apps/toolbar/admin.py +++ b/apps/toolbar/admin.py @@ -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'

' + widgets[0] + u' Alt

' - out += u'

' + widgets[1] + u' Ctrl

' - out += u'

' + widgets[2] + u' Shift

' - 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 index 00000000..723732d2 --- /dev/null +++ b/apps/toolbar/fixtures/initial_data.yaml @@ -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*)\u2193" + 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 = '';\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 ? '\\\ + 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' + 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 index bcc039f6..00000000 --- a/apps/toolbar/fixtures/toolbar.yaml +++ /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*)\u2193" - 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 = '';\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 ? '\\\ - 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' + 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 index 00000000..974ea662 --- /dev/null +++ b/apps/toolbar/migrations/0001_initial.py @@ -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 index 00000000..09ddd323 --- /dev/null +++ b/apps/toolbar/migrations/0002_auto__del_field_button_key_mod__chg_field_button_key.py @@ -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 index 00000000..0d2e9068 --- /dev/null +++ b/apps/toolbar/migrations/0003_button_key_rename_to_accesskey.py @@ -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 index 00000000..e69de29b diff --git a/apps/toolbar/models.py b/apps/toolbar/models.py index 6a20263e..d736c027 100644 --- a/apps/toolbar/models.py +++ b/apps/toolbar/models.py @@ -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 diff --git a/apps/toolbar/templates/toolbar/button.html b/apps/toolbar/templates/toolbar/button.html index 92c51a18..2ecb1ab9 100644 --- a/apps/toolbar/templates/toolbar/button.html +++ b/apps/toolbar/templates/toolbar/button.html @@ -4,9 +4,9 @@ {% if button.link %} diff --git a/apps/wiki/templates/wiki/document_details.html b/apps/wiki/templates/wiki/document_details.html index cbed276c..9031d19d 100644 --- a/apps/wiki/templates/wiki/document_details.html +++ b/apps/wiki/templates/wiki/document_details.html @@ -5,6 +5,7 @@ {% load compressed %} {% compressed_css 'detail' %} {% endblock %} + {% block extrabody %}