b6e5c7503aa8fbb66959c15939a7143a1c27f61c
[Packages/TYPO3.CMS.git] / typo3 / sysext / em / res / js / em_languages.js
1 /**
2 * ExtJS for the extension manager.
3 *
4 *
5 * @author Steffen Kamper <info@sk-typo3.de>
6 * @package TYPO3
7 * @subpackage extension manager
8 */
9
10 Ext.ns('TYPO3.EM');
11
12 /** override mousedown for grid to select checkbox respecting singleSelect */
13 Ext.override(Ext.grid.CheckboxSelectionModel, {
14 handleMouseDown: function(g, rowIndex, e) {
15 e.stopEvent();
16 if (this.isSelected(rowIndex)) {
17 this.deselectRow(rowIndex);
18 } else {
19 this.selectRow(rowIndex, true);
20 this.grid.getView().focusRow(rowIndex);
21 }
22 }
23 });
24
25 Ext.grid.DynamicColumnModelForLanguages = function(store){
26 var cols = [];
27 var recordType = store.recordType;
28 var fields = recordType.prototype.fields;
29
30 for (var i = 0; i < fields.keys.length; i++) {
31 var fieldName = fields.keys[i];
32 var field = recordType.getField(fieldName);
33
34 if (i === 0) {
35 cols[i] = {
36 header: 'Extension',
37 dataIndex: field.name,
38 width: 200,
39 fixed: true,
40 sortable: false,
41 hidable: false,
42 menuDisabled: true,
43 renderer: function(value, metaData, record, rowIndex, colIndex, store){
44 metaData.css += ' extLangTitleWithIcon';
45 return record.data.icon + ' <strong>' + value + '</strong>';
46 }
47 };
48 } else if (i === 1 || i === 2 || i === 3) {
49 //bypass
50 } else {
51 cols[i - 3] = {
52 header: field.name,
53 dataIndex: field.name,
54 hidden: true,
55 fixed: true,
56 sortable: false,
57 hidable: false,
58 menuDisabled: true,
59 renderer: function(value, metaData, record, rowIndex, colIndex, store) {
60 if (value == TYPO3.l10n.localize('translation_checking')) {
61 return '<span class="x-mask-loading">&nbsp;</span>' + value;
62 }
63 return '<span class="x-mask-loading">&nbsp;</span>' + value;;
64 }
65 };
66
67 }
68 }
69 Ext.grid.DynamicColumnModelForLanguages.superclass.constructor.call(this, cols);
70 };
71 Ext.extend(Ext.grid.DynamicColumnModelForLanguages, Ext.grid.ColumnModel, {defaultWidth: 170});
72
73
74 TYPO3.EM.LanguagesSelectionModel = new Ext.grid.CheckboxSelectionModel({
75 singleSelect: false,
76 header: '',
77 dataIndex: 'selected',
78 checkOnly: false
79
80 });
81
82 TYPO3.EM.LanguagesColumnModel = new Ext.grid.ColumnModel([
83 TYPO3.EM.LanguagesSelectionModel, {
84 id: 'lang-label',
85 header: TYPO3.l10n.localize('lang_language'),
86 sortable: true,
87 menuDisabled: true,
88 dataIndex: 'label',
89 hidable: false,
90 renderer: function(value, metaData, record, rowIndex, colIndex, store) {
91 return '<span class="' + record.data.cls + '">&nbsp</span>' + value;
92 }
93 },{
94 id: 'lang-key',
95 header: TYPO3.l10n.localize('lang_short'),
96 menuDisabled: true,
97 sortable: true,
98 dataIndex: 'lang',
99 hidable: false
100 }
101 ]);
102
103 TYPO3.EM.LanguagesProgressBar = new Ext.ProgressBar ({
104 id: 'langpb',
105 cls: 'left-align',
106 autoWidth: true,
107 style: 'margin: 0 0 20px 0',
108 animate: true,
109 height: 20,
110 hidden: true
111 });
112
113
114
115 TYPO3.EM.Languages = Ext.extend(Ext.FormPanel, {
116 border:false,
117 layout: 'form',
118 id: 'em-labguage-modul',
119 extCount: 0,
120 fetchType: 0,
121 extkeyArray : [],
122 selectedLanguages: [],
123 cb: null,
124
125 initComponent: function() {
126 var langExtStore = new Ext.data.DirectStore({
127 storeId : 'em-languageext-store',
128 autoLoad : false,
129 directFn : TYPO3.EM.ExtDirect.getInstalledExtkeys,
130 root : 'data',
131 idProperty : 'extkey',
132 fields : [{name : 'extkey'},{name : 'icon'},{name: 'stype'}],
133 listeners : {
134 'load': function(store, records, options){
135 if(records.length) {
136 Ext.getCmp('lang-checkbutton').enable();
137 Ext.getCmp('lang-updatebutton').enable();
138 this.restoreExtLanguageGrid();
139 }
140 this.languageLoaded = true;
141 },
142 scope : this
143 }
144
145 });
146
147 this.langStore = new Ext.data.DirectStore({
148 storeId : 'em-language-store',
149 autoLoad : false,
150 directFn : TYPO3.EM.ExtDirect.getLanguages,
151 paramsAsHash: false,
152 root : 'data',
153 idProperty : 'lang',
154 fields : [
155 {name : 'lang', type : 'string'},
156 {name : 'label', type : 'string'},
157 {name : 'cls', type : 'string'},
158 {name : 'selected', type: 'bool'}
159 ],
160 listeners : {
161 'load': function(store, records){
162 // get selected languages and update selection and extGrid
163 TYPO3.settings.LangLoaded = false;
164 var a = [];
165 for (var i=0; i<records.length; i++) {
166 if(records[i].data.selected) {
167 a.push(records[i]);
168 }
169 }
170 TYPO3.EM.LanguagesSelectionModel.selectRecords(a);
171 langExtStore.load();
172 store.sort('label', 'ASC');
173 },
174 scope: this
175 }
176 });
177
178
179 Ext.apply(this, {
180 languagesLoaded: false,
181 layout:'hbox',
182 bodyStyle: 'padding: 10px 5px 0 5px;',
183 layoutConfig: {
184 align: 'stretch'
185 },
186 defaults: {
187 border: false
188 },
189 items: [{
190 width: 250,
191 layout: 'fit',
192 items: [{
193 xtype: 'grid',
194 id: 'em-languagegrid',
195 stripeRows: true,
196 store: this.langStore,
197 cm: TYPO3.EM.LanguagesColumnModel,
198 sm: TYPO3.EM.LanguagesSelectionModel,
199 enableColumnMove: false,
200 onRowClick: Ext.emptyFn,
201 viewConfig: {
202 forceFit: true
203 }
204 }]
205 }, {
206 flex: 1,
207 layout: 'fit',
208 items: [{
209 xtype:'fieldset',
210 //title: TYPO3.l10n.localize('translation_status'),
211 collapsible: false,
212 items: [
213 TYPO3.EM.LanguagesActionPanel,
214 {
215 xtype: 'container',
216 layout: 'hbox',
217 height: 40,
218 id: 'LanguagesActionPanel',
219 layoutConfig: {
220 align: 'stretch'
221 },
222 defaults: {
223 border:false,
224 flex: 1
225 },
226 items: [{
227 xtype: 'button',
228 text: TYPO3.l10n.localize('translation_check_status_button'),
229 id: 'lang-checkbutton',
230 margins: '0 10 10 0'
231 }, {
232 xtype: 'button',
233 text: TYPO3.l10n.localize('translation_update_button'),
234 id: 'lang-updatebutton',
235 margins: '0 0 10 10'
236 }]
237 },
238 TYPO3.EM.LanguagesProgressBar,
239 {
240 xtype: 'grid',
241 id: 'em-extlanguagegrid',
242 stripeRows: true,
243 store: langExtStore,
244 loadMask: {msg: TYPO3.l10n.localize('translation_refresh_languages')},
245 enableColumnMove: false,
246 enableHdMenu : false,
247 autoheight: true,
248 cm: new Ext.grid.DynamicColumnModelForLanguages(langExtStore),
249 margins: '0 10 0 0',
250 anchor: '100% -40',
251 listeners: {
252 render: this.onExtensionLangguageGridRender
253 }
254 }]
255 }]
256 }]
257 });
258
259 // call parent
260 TYPO3.EM.Languages.superclass.initComponent.apply(this, arguments);
261 this.langGrid = Ext.getCmp('em-languagegrid');
262 this.langGrid.getSelectionModel().on('selectionchange', function(){
263 if (this.languageLoaded) {
264 this.langGrid.disable();
265 this.saveSelection();
266 }
267 }, this);
268 Ext.getCmp('lang-checkbutton').handler = this.langActionHandler.createDelegate(this);
269 Ext.getCmp('lang-updatebutton').handler = this.langActionHandler.createDelegate(this);
270 } ,
271
272 onExtensionLangguageGridRender: function(grid) {
273 grid.fetchingProcess = false;
274 this.on('cellclick', function(grid, rowIndex, columnIndex, event) {
275 if (!grid.fetchingProcess && columnIndex > 0) {
276 var record = grid.store.getAt(rowIndex);
277 var lang = grid.colModel.config[columnIndex].dataIndex;
278 Ext.Msg.confirm(
279 TYPO3.l10n.localize('menu_language_packges'),
280 String.format(TYPO3.l10n.localize('translation_singleCheckQuestion'), lang, '<strong>' + record.data.extkey + '</strong>'),
281 function(btn) {
282 if (btn === 'yes') {
283 this.waitBox = Ext.Msg.wait(
284 String.format(TYPO3.l10n.localize('translation_singleCheck'), lang, '<strong>' + record.data.extkey + '</strong>'),
285 TYPO3.l10n.localize('translation_checking')
286 );
287 TYPO3.EM.ExtDirect.fetchTranslations(record.data.extkey, 1, [lang], function(response) {
288 if (response && Ext.isArray(response)) {
289 record.set(lang, response[lang]);
290 record.commit();
291 } else {
292 TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.l10n.localize('extDirect_timeoutHeader'), TYPO3.l10n.localize('extDirect_timeoutMessage'), 5);
293 }
294 this.waitBox.hide()
295 }, this);
296 }
297 },
298 this
299 );
300 }
301 }, this);
302 },
303
304 langActionHandler: function(button, event) {
305 var languagegrid = Ext.getCmp('em-languagegrid');
306 var buttonPanel = Ext.getCmp('LanguagesActionPanel');
307 var progressBar = Ext.getCmp('langpb');
308 var grid = Ext.getCmp('em-extlanguagegrid');
309
310 buttonPanel.hide();
311 progressBar.show();
312 languagegrid.disable();
313
314
315 if (button.id === 'lang-checkbutton') {
316 // check languages
317 this.startFetchLanguages(0, Ext.StoreMgr.get('em-languageext-store'), function(){
318 TYPO3.EM.LanguagesProgressBar.updateText(this.interruptProcess ? TYPO3.l10n.localize('msg_interrupted') : TYPO3.l10n.localize('msg_finished'));
319 (function() {
320 progressBar.hide();
321 buttonPanel.show();
322 languagegrid.enable();
323 grid.fetchingProcess = false;
324 }).defer(1000, this);
325 if (!this.interruptProcess) {
326 TYPO3.Flashmessage.display(TYPO3.Severity.information, TYPO3.l10n.localize('translation_checking_extension'), TYPO3.l10n.localize('translation_check_done'), 3);
327 Ext.getCmp('em-extlanguagegrid').getSelectionModel().clearSelections();
328 }
329 });
330 } else {
331 // update languages
332 this.startFetchLanguages(1, Ext.StoreMgr.get('em-languageext-store'), function(){
333 TYPO3.EM.LanguagesProgressBar.updateText(this.interruptProcess ? TYPO3.l10n.localize('msg_interrupted') : TYPO3.l10n.localize('msg_finished'));
334 if (!this.interruptProcess) {
335 TYPO3.Flashmessage.display(TYPO3.Severity.information, TYPO3.l10n.localize('translation_update_extension'), TYPO3.l10n.localize('translation_update_done'), 3);
336 Ext.getCmp('em-extlanguagegrid').getSelectionModel().clearSelections();
337 }
338 progressBar.hide();
339 buttonPanel.show();
340 languagegrid.enable();
341 grid.fetchingProcess = false;
342 });
343 }
344 },
345
346 getSelectedLanguages: function() {
347 var selLanguages = this.langGrid.getSelectionModel().getSelections();
348 this.selectedLanguages = [];
349 if (selLanguages.length > 0 ) {
350 for (var i=0; i<selLanguages.length; i++) {
351 this.selectedLanguages.push(selLanguages[i].data.lang);
352 }
353 }
354 },
355
356 saveSelection: function() {
357 if (this.languageLoaded === true) {
358 this.getSelectedLanguages();
359 TYPO3.EM.ExtDirect.saveLanguageSelection(this.selectedLanguages, function(response) {
360 this.languageLoaded = false;
361 if (response.success) {
362 for (var i = 0; i < response.diff.length; i++) {
363 record = this.langStore.getById(response.diff[i]);
364 this.addRemoveExtLanguageGridColumn(record.data);
365 if (response.dir > 0) {
366 // Languages were added
367 this.langGrid.getSelectionModel().selectRow(this.langGrid.store.indexOf(record), true);
368 } else {
369 // Languages were removed
370 this.langGrid.getSelectionModel().deselectRow(this.langGrid.store.indexOf(record), true);
371 }
372 }
373 } else {
374 // Action not possible because of dependencies
375 // Select all languages saved again and output the message
376 for (var i = 0; i < response.languages.length; i++) {
377 record = this.langStore.getById(response.languages[i]);
378 this.langGrid.getSelectionModel().selectRow(this.langGrid.store.indexOf(record), true);
379 }
380 TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.l10n.localize('translation_settings'), TYPO3.l10n.localize('translation_selection_impossible'), 5);
381 this.langGrid.enable();
382 }
383 this.languageLoaded = true;
384 }, this);
385 if (this.selectedLanguages.length) {
386 Ext.getCmp('lang-checkbutton').enable();
387 Ext.getCmp('lang-updatebutton').enable();
388 } else {
389 Ext.getCmp('lang-checkbutton').disable();
390 Ext.getCmp('lang-updatebutton').disable();
391 }
392 }
393 },
394
395 startFetchLanguages: function(type, store, callback) {
396 this.fetchType = type;
397 this.extCount = store.data.items.length;
398 this.cb = callback;
399
400
401 // fill arrays
402 this.extkeyArray = [];
403 for (var i = 0; i < this.extCount; i++) {
404 this.extkeyArray.push(store.data.items[i].data.extkey);
405 }
406 if (!this.selectedLanguages.length) {
407 this.getSelectedLanguages();
408 }
409 // start process
410 this.interruptProcess = false;
411 Ext.getCmp('em-extlanguagegrid').fetchingProcess = true;
412 this.fetchLanguage();
413 },
414
415 fetchLanguage: function(response) {
416 var grid = Ext.getCmp('em-extlanguagegrid');
417 var row = this.extCount - this.extkeyArray.length;
418 var record = grid.store.getAt(row);
419 var i;
420
421
422 if (response) {
423 // update fetched record
424 var fetchedRecord = grid.store.getAt(row - 1);
425 for (i = 0; i < this.selectedLanguages.length; i++) {
426 fetchedRecord.set(this.selectedLanguages[i], response[this.selectedLanguages[i]]);
427 }
428 fetchedRecord.commit();
429 }
430
431 if(this.extkeyArray.length > 0 && !this.interruptProcess) {
432 var ext = this.extkeyArray.shift();
433
434
435 //update Grid
436 grid.getView().focusRow(row);
437 grid.getSelectionModel().selectRow(row);
438 for (i = 0; i < this.selectedLanguages.length; i++) {
439 record.set(this.selectedLanguages[i], '<span class="loading-indicator"></span>' + TYPO3.l10n.localize('translation_checking'));
440 }
441 record.commit();
442 var prefix = TYPO3.l10n.localize('msg_checking');
443 if (this.fetchType === 1) {
444 prefix = TYPO3.l10n.localize('msg_updating');
445 }
446 // update Progressbar
447 Ext.getCmp('langpb').updateProgress(
448 (row + 1) / this.extCount,
449 prefix+ ': ' +
450 String.format(TYPO3.l10n.localize('translation_fetch_extension'), ext, (row+1), this.extCount));
451
452 // fetch language request
453 TYPO3.EM.ExtDirect.fetchTranslations(ext, this.fetchType, this.selectedLanguages, function(response) {
454 this.fetchLanguage(response);
455 }, this);
456 } else {
457 // finished
458 Ext.getCmp('lang-checkbutton').enable();
459 Ext.getCmp('lang-updatebutton').enable();
460 Ext.getCmp('em-extlanguagegrid').getSelectionModel().clearSelections();
461 // call callback
462 this.cb();
463 }
464 },
465
466
467 restoreExtLanguageGrid: function() {
468
469 var extLangGrid = Ext.getCmp('em-extlanguagegrid');
470 var i;
471
472 var selLanguages = Ext.getCmp('em-languagegrid').getSelectionModel().getSelections();
473 var columns = extLangGrid.getColumnModel();
474 var count = columns.getColumnCount();
475
476 if (selLanguages.length > 0 ) {
477 for (i=0; i < selLanguages.length; i++) {
478 this.addRemoveExtLanguageGridColumn(selLanguages[i].data);
479 }
480 }
481 },
482
483 addRemoveExtLanguageGridColumn: function(record) {
484 var extLangGrid = Ext.getCmp('em-extlanguagegrid');
485 var columns = extLangGrid.getColumnModel();
486 var index = columns.getIndexById(record.lang);
487
488 if (index === -1) {
489 extLangGrid.addColumn({
490 name: record.lang,
491 defaultValue: TYPO3.l10n.localize('translation_status_notchecked')
492 }, {
493 header: '<span class="' + record.cls + '">&nbsp</span>' + record.label,
494 dataIndex: record.lang,
495 id: record.lang,
496 css: 'cursor:pointer;',
497 tooltip: TYPO3.l10n.localize('translation_singleCheckTip')
498 });
499 } else {
500 columns.removeColumn(index);
501 }
502 this.langGrid.enable();
503 },
504
505 afterRender: function() {
506 // call parent
507 TYPO3.EM.Languages.superclass.afterRender.apply(this, arguments);
508 //The following are all of the possible keys that can be implemented: enter, left, right, up, down, tab, esc, pageUp, pageDown, del, home, end
509 this.progressNavigation = new Ext.KeyNav(this.getEl(),{
510 'esc': function() {
511 this.interruptProcess = true;
512 },
513 scope: this
514 });
515
516
517 }
518 });
519 Ext.reg('extlanguages', TYPO3.EM.Languages);