Fixed buttons and hotkeys.
[redakcja.git] / project / static / js / views / xml.js
1 /*global View CodeMirror ButtonToolbarView render_template panels */
2 var XMLView = View.extend({
3     _className: 'XMLView',
4     element: null,
5     model: null,
6     template: 'xml-view-template',
7     editor: null,
8     buttonToolbar: null,
9   
10     init: function(element, model, parent, template) {
11         this._super(element, model, template);
12         this.parent = parent;
13         this.buttonToolbar = new ButtonToolbarView(
14             $('.xmlview-toolbar', this.element),
15             this.model.toolbarButtonsModel, parent);
16
17         this.hotkeys = [];
18         var self = this;
19
20         $('.xmlview-toolbar', this.element).bind('resize.xmlview', this.resized.bind(this));
21    
22     
23         this.parent.freeze('Ładowanie edytora...');
24         this.editor = new CodeMirror($('.xmlview', this.element).get(0), {
25             parserfile: 'parsexml.js',
26             path: "/static/js/lib/codemirror/",
27             stylesheet: "/static/css/xmlcolors.css",
28             parserConfig: {
29                 useHTMLKludges: false
30             },
31             textWrapping: false,
32             tabMode: 'spaces',
33             indentUnit: 0,
34             onChange: this.editorDataChanged.bind(this),
35             initCallback: this.editorDidLoad.bind(this)
36         });
37     },
38   
39     resized: function(event) {
40         var height = this.element.height() - $('.xmlview-toolbar', this.element).outerHeight();
41         $('.xmlview', this.element).height(height);
42     },
43   
44     reload: function() {
45         this.model.load(true);
46     },
47   
48     editorDidLoad: function(editor) {
49         $(editor.frame).css({
50             width: '100%',
51             height: '100%'
52         });
53         this.model
54         .addObserver(this, 'data', this.modelDataChanged.bind(this))
55         .addObserver(this, 'state', this.modelStateChanged.bind(this))
56         .load();
57     
58         this.parent.unfreeze();
59       
60         this.editor.setCode(this.model.get('data'));
61         this.modelStateChanged('state', this.model.get('state'));
62         
63         editor.grabKeys(
64             this.hotkeyPressed.bind(this),
65             this.isHotkey.bind(this)
66             );
67     },
68   
69     editorDataChanged: function() {
70         this.model.set('data', this.editor.getCode());
71     },
72   
73     modelDataChanged: function(property, value) {
74         if (this.editor.getCode() != value) {
75             this.editor.setCode(value);
76         }
77     },
78   
79     modelStateChanged: function(property, value) {
80         if (value == 'synced' || value == 'dirty') {
81             this.unfreeze();
82         } else if (value == 'unsynced') {
83             this.freeze('Niezsynchronizowany...');
84         } else if (value == 'loading') {
85             this.freeze('Ładowanie...');
86         } else if (value == 'saving') {
87             this.freeze('Zapisywanie...');
88         } else if (value == 'error') {
89             this.freeze(this.model.get('error'));
90         }
91     },
92     
93     dispose: function() {
94         this.model.removeObserver(this);
95         $(this.editor.frame).remove();
96         this._super();
97     },    
98
99     getHotkey: function(event) {
100         var code = event.keyCode;
101         var ch = String.fromCharCode(code & 0xff).toLowerCase();
102         var button = $('.buttontoolbarview-button[title='+ch+']', this.element)[0]
103
104         console.log(ch, '#', button);       
105         var mod = 0;
106             
107         if(event.altKey) mod |= 0x01;
108         if(event.ctrlKey) mod |= 0x02;
109         if(event.shiftKey) mod |= 0x04;
110
111         if(button) {
112             var match = null;
113
114             $(button).each(function() {
115                 if( parseInt($(this).attr('ui:hotkey_mod')) == mod ) {
116                     match = this;
117                     return;
118                 }
119             })
120
121             return match;
122         }
123         else {
124             return null;
125         }
126     },
127
128     isHotkey: function() {
129         console.log(arguments);
130         
131         if(this.getHotkey.apply(this, arguments))
132             return true;
133         else
134             return false;
135     },
136
137     hotkeyPressed: function() {
138         var button = this.getHotkey.apply(this, arguments);
139         this.buttonToolbar.buttonPressed({
140             target: button
141         });
142     }
143
144 });
145
146 function Hotkey(code) {
147     this.code = code;
148     this.has_alt = ((code & 0x01 << 8) !== 0);
149     this.has_ctrl = ((code & 0x01 << 9) !== 0);
150     this.has_shift = ((code & 0x01 << 10) !== 0);
151     this.character = String.fromCharCode(code & 0xff);
152 }
153
154 Hotkey.prototype.toString = function() {
155     var mods = [];
156     if(this.has_alt) mods.push('Alt');
157     if(this.has_ctrl) mods.push('Ctrl');
158     if(this.has_shift) mods.push('Shift');
159     mods.push('"'+this.character+'"');
160     return mods.join('+');
161 };
162
163 // Register view
164 panels['xml'] = XMLView;