init
[Pman.Core] / Pman.js
1 //<script type="text/javascript">
2
3 /**
4  * 
5  * >>> Pman.layout.getRegion('center').tabs.stripWrap
6  * ==> tab.???
7  * var tbh = Pman.layout.getRegion('center').tabs.stripWrap.child('div').createChild(
8  * 
9  * {tag: 'div', style: 'display:block;position:absolute;top:2;left:300;width:100%;height:25px'});
10  * 
11  */
12  
13 if (typeof(_T) == 'undefined') { _T={};}
14  
15
16   
17
18 Pman = new Roo.Document(
19 {
20    /// appVersion: '1.7', // fixme = needs to be removed - use Global AppVersion
21     subMenuItems : [],
22     topMenuItems : [],
23     rightNames: { }, /// register right names here - so they can be translated and rendered.
24     buildCompleted : false, // flag to say if we are building interface..
25     events : {
26         'beforeload' : true, // fired after page ready, before module building.
27         'load' : true, // fired after module building
28         'authrefreshed' : true // fire on auth updated?? - should be on Login?!?!?
29     },
30     
31     listeners : {
32         'ready' : function()
33         {
34             // kludge to fix firebug debugger
35             if (typeof(console) == 'undefined') {
36                 console = { log : function() {  } };
37             }
38             
39             // remove loader..
40             if (Ext.get('loading')) {
41                 Ext.get('loading').remove();
42             }
43             
44             Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
45             
46             // link errors...
47             
48             if (AppLinkError.length) {
49                 Ext.MessageBox.alert("Error", AppLinkError, function() {
50                     Pman.Login.onLoad();
51                 });
52                 return;
53             }
54             
55             
56             // reset password!!!!
57             if (showNewPass.length) {
58                 Pman.PasswordChange.show(  { passwordReset : showNewPass },
59                     function(data) {
60                         // fail and success we do  a load...
61                         Pman.Login.onLoad();
62                     }
63                 );
64                 return;
65             }
66              
67             Pman.Login.onLoad();
68             
69         },
70         'load' : function()
71         {
72             if (Roo.get('loading-logo-tile')) {
73                 Roo.get('loading-logo-tile').remove();
74             }
75             if (Roo.get('loading-logo-tile-top')) {
76                 Roo.get('loading-logo-tile-top').remove();
77             }
78             if (Roo.get('loading-logo-bottom')) {
79                 Roo.get('loading-logo-bottom').remove();
80             }
81             if (Roo.get('loading-logo-center')) {
82                 Roo.get('loading-logo-center').remove();
83             }
84         }   
85         
86     },
87    
88
89     
90     layout: false,
91     
92     onload: function() {
93         //this.fireEvent('beforeload',this);
94         
95         
96         
97         if (this.layout) {
98             return; // already loaded
99         } 
100         if (Ext.get('loading')) {
101             Ext.get('loading').remove();
102         }
103         if (Ext.get('loading-mask')) {
104             Ext.get('loading-mask').show();
105         }
106         
107         
108        
109         
110         /*
111         Ext.MessageBox.show({
112            title: "Please wait...",
113            msg: "Building Interface...",
114            width:340,
115            progress:true,
116            closable:false
117           
118         });
119         */
120         //Pman.onLoadBuild();
121         //Ext.get(document.body).mask("Building Interface");
122         //Pman.onLoadBuild.defer(100, Pman);
123        //Pman.onLoadBuild();
124                     
125    // },
126     //onLoadBuild : function() {
127         
128         var _this = this;
129         this.stime = new Date();
130         this.layout = new Ext.BorderLayout(document.body, {
131             north: {
132                 split:false,
133                 initialSize: 25,
134                 titlebar: false
135             },
136          
137              
138             center: {
139                 titlebar: false,
140                 autoScroll:false,
141                 closeOnTab: true,
142                 tabPosition: 'top',
143                 //resizeTabs: true,
144                 alwaysShowTabs: true,
145                 minTabWidth: 140
146             } /*,
147             south: {
148                 split:false,
149                 initialSize: 25,
150                 titlebar: false
151             }
152             */
153         });
154         
155         this.fireEvent('beforeload',this);
156         
157         
158         
159         this.layout.beginUpdate();
160         this.layout.add('north', new Ext.ContentPanel('title', 'North'));
161         var au = Pman.Login.authUser;
162         if (au.id > 0 && au.company_id_background_color.length) {
163             Ext.get('title').dom.style.backgroundColor = '#' + au.company_id_background_color;
164             Ext.get('headerInformation').dom.style.color = this.invertColor('#' + au.company_id_background_color);
165         }
166         if (au.id > 0 && au.company_id_logo_id * 1 > 0) {
167             Ext.get('headerInformation-company-logo').dom.src =  baseURL + 
168                 '/Images/' + au.company_id_logo_id + '/' + au.company_id_logo_id_filename;
169         } else {
170             Ext.get('headerInformation-company-logo').dom.src = Roo.BLANK_IMAGE_URL;
171         }
172         
173         Ext.get('headerInformation').dom.innerHTML = String.format(
174                 "You are Logged in as <b>{0} ({1})</b>", // to {4} v{3}", // for <b>{2}</b>",
175                 au.name, au.email, au.company_id_name, 
176                 AppVersion , appNameShort
177         );
178         
179         
180         document.title = appName + ' v' + AppVersion + ' - ' + au.company_id_name;
181         Ext.QuickTips.init(); 
182         if (Ext.isGecko) {
183            Ext.useShims = true;
184         }
185        
186         //this.mainLayout.beginUpdate();
187         //var maskDom = Ext.get(document.body)._maskMsg.dom
188         this.layout.beginUpdate();
189         
190         Pman.building = true;
191         
192         this.buildModules(this, 
193             function() {
194                 
195                 _this.layout.getRegion('center').showPanel(0);
196                 _this.layout.endUpdate(); 
197                 _this.addTopToolbar();  
198                 _this.finalize();
199                 _this.fireEvent('load',this);
200             }
201         );
202         
203         
204      
205     },
206     
207     addTopToolbar : function()
208     {
209           //console.log( "t6:" + ((new Date())-stime));
210         //this.mainLayout.endUpdate();
211         // make a new tab to hold administration stuff...
212         
213        
214         //console.log( "t7:" + ((new Date())-stime));
215         var se = Pman.layout.getRegion('center').tabs.stripEl;
216         var tbh = se.createChild( 
217                 { tag: 'td', style: 'width:100%;'  });
218         
219         var lotb = new Ext.Toolbar(tbh);
220         
221         if (Roo.isSafari) {
222             var tbl = se.child('table', true);
223             tbl.setAttribute('width', '100%');
224         }
225         lotb.add(
226             new Ext.Toolbar.Fill(), 
227      
228             {
229                 text: "Change Password",
230                 cls: 'x-btn-text-icon',
231                 icon: rootURL + '/Pman/templates/images/change-password.gif',
232                 handler : function(){
233                     Pman.PasswordChange.show({});
234                 }
235             }, '-'
236         );
237          
238         
239         if (this.topMenuItems.length) {
240             
241             Roo.each(this.topMenuItems, function (mi) {
242                 lotb.add(mi);
243             });
244             lotb.add('-');
245         }
246         
247         
248         
249         if (this.subMenuItems.length) {
250             
251             this.subMenuItems.sort(function (a,b) {
252                 return a.seqid > b.seqid ? 1 : -1;
253             });
254             // chop off last seperator.
255             // since we always add it.. just chop of last item
256             this.subMenuItems.pop(); 
257             
258             lotb.add(
259                 {
260                      
261                     text: "Add New Item",
262                     cls: 'x-btn-text-icon',
263                     icon: Ext.rootURL + 'images/default/dd/drop-add.gif',
264                     menu : {
265                         items : this.subMenuItems
266                     }     
267                 } ,'-'
268             );
269         }
270        
271         lotb.add(
272             {
273                 text: "Logout",
274                 cls: 'x-btn-text-icon',
275                 icon: rootURL + '/Pman/templates/images/logout.gif',
276                 handler: function() {
277                     Pman.Login.logout();
278                 }
279                  
280             }
281         );
282       
283        // this.layout.endUpdate();
284     },
285     
286     
287     finalize : function() {
288         
289       
290        
291         window.onbeforeunload = function(e) { 
292             var e = e || window.event;
293             var r = "Closing this window will loose changes, are you sure you want to do that?";
294
295             // For IE and Firefox
296             if (e) {
297                 e.returnValue = r;
298             }
299
300             // For Safari
301             return r;
302             
303         };
304         
305         Ext.MessageBox.hide();
306         if (Ext.get('loading-mask')) {
307            Ext.get('loading-mask').remove();
308         }
309         
310         
311         this.buildCompleted = true; // now we can force refreshes on everything..
312         
313         
314         // does the URL indicate we want to see a system..
315         if (AppTrackOnLoad * 1 > 0) {
316             this.onLoadTrack(AppTrackOnLoad,false);
317         }
318         
319         // Open system..
320         
321         var forceAdmin = function(data)
322         {
323             if (!data || !data.id) {
324                 Pman.Dialog.PersonStaff.show( 
325                     { 
326                         id : 0, 
327                         company_id : Pman.Login.authUser.company_id * 1, 
328                         company_id_name : Pman.Login.authUser.company_id_name
329                     }, function(data) {
330                         forceAdmin(data);
331                     }
332                 );
333                 return;
334             }
335             Ext.state.Manager.set('Pman.Login.username', data.email),
336             window.onbeforeunload = false;
337             document.location = baseURL + '?ts=' + Math.random();
338         }
339         
340         var forceCompany = function(data) {
341             if (Pman.Login.authUser.company_id * 1 > 0) {
342                 forceAdmin();
343                 return;
344             }
345             if (!data || !data.id) {
346                 Pman.Dialog.Companies.show( { id : 0, isOwner : 1, comptype: 'OWNER' }, function(data) {
347                     forceCompany(data);
348                 });
349                 return;
350             }
351             Pman.Login.authUser.company_id  = data.id;
352             Pman.Login.authUser.company_id_name  = data.name;
353             forceAdmin();
354         }
355         
356         if (Pman.Login.authUser.id < 0) {
357             forceCompany();
358             /// create account..
359             
360             
361         }
362         
363
364     },
365     
366     
367     
368     
369      
370     onLoadTrack : function(id,cb) {
371         this.onLoadTrackCall(id, cb, 'DocumentsCirc_');
372     },
373     onLoadTrackEdit : function(id,cb) {
374         this.onLoadTrackCall(id, cb, 'Documents_');
375     },
376     
377     
378     /// ----------- FIXME -----
379     
380     
381     onLoadTrackCall : function(id,cb, cls) {
382         Ext.get(document.body).mask("Loading Document details");
383
384         Pman.request({
385             url: baseURL + '/Roo/Documents.html',  
386             params: {
387                 _id: id
388             },  
389             method: 'GET',  
390             success : function(data) {
391                 Ext.get(document.body).unmask();
392              
393                 
394                 switch(data.in_out) {
395                     case 'IN' : cls+='In';break;
396                     case 'OUT' : cls+='Out';break;
397                     case 'WIP' : cls+='Wip';break;
398                     default: 
399                         Ext.MessageBox.alert("Error", "invalid in_out");
400                         return;
401                 }
402                 Pman.Dialog[cls].show(data, cb ? cb : Pman.refreshActivePanel);
403             }, 
404             
405             failure: function() {
406                 Ext.get(document.body).unmask();
407                 //if (cb) {
408                 //    cb.call(false);
409                 //}
410                  
411            }
412         });
413           
414     },
415     
416     /**
417      * eg. has Pman.hasPerm('Admin.Admin_Tab', 'S') == showlist..
418      * 
419      */
420     hasPerm: function(name, lvl) {
421         if (typeof(Pman.Login.authUser) != 'object') {
422             return false;
423         }
424         if (typeof(Pman.Login.authUser.perms[name]) != 'string') {
425             return false;
426         }
427         return Pman.Login.authUser.perms[name].indexOf(lvl) > -1;
428         
429     },
430     
431     
432     
433     
434     
435     
436     
437     
438     Readers : {},
439     ColModels : {},
440     Forms : {},
441     Tab : {},
442     Dialog : {},
443     
444     processResponse : function (response)
445     {
446         var res = '';
447         try {
448             res = Ext.decode(response.responseText);
449             // oops...
450             if (typeof(res) != 'object') {
451                 res = { success : false, errorMsg : res, errors : true };
452             }
453             if (typeof(res.success) == 'undefined') {
454                 res.success = false;
455             }
456             
457         } catch(e) {
458             res = { success : false,  errorMsg : response.responseText, errors : true };
459         }
460         return res;
461     },
462     genericDelete : function(tab,tbl) {
463         
464         var r = [];
465         
466             
467         var s = tab.grid.getSelectionModel().getSelections();
468         if (!s.length)  {
469             Ext.MessageBox.alert("Error", "Select at least one Row to delete" );
470             return '';
471         }
472         
473         for(var i = 0; i < s.length; i++) {
474             r.push(s[i].data.id);
475         }
476     
477         Ext.MessageBox.confirm("Confirm", "Are you sure you want to delete that?",
478             function(btn) {
479                 if (btn != 'yes') {
480                     return;
481                 }
482                 // what about the toolbar??
483                 tab.grid.getView().mainWrap.mask("Deleting");
484                 Pman.request({
485                     url: baseURL + '/Roo/'+tbl+'.php',
486                     method: 'GET',
487                     params: {
488                         _delete : r.join(',')
489                     },
490                     success: function(response) {
491                         tab.grid.getView().mainWrap.unmask();
492                         if ( tab.paging ) {
493                             tab.paging.onClick('refresh');   
494                         } else if (tab.refresh) {
495                             tab.refresh();
496                         } else if (tab.grid.footer && tab.grid.footer.onClick) {
497                             // new xtype built grids
498                             tab.grid.footer.onClick('refresh');   
499                         } else {
500                             tab.grid.getDataSource().load();
501                         }
502                         
503                         
504                         
505                     },
506                     failure: function(act) {
507                         tab.grid.getView().mainWrap.unmask();
508                         Ext.MessageBox.alert("Error", "Error Deleting");
509                     }
510                     
511                 });
512             }
513         );
514     },
515     refreshActivePanel : function() {
516         var actpan = this.layout.getRegion('center').getActivePanel();
517         if (actpan.controller && actpan.controller.paging) {
518             actpan.controller.paging.onClick('refresh');
519             return;
520         }
521         
522         var agid = Pman.layout.getRegion('center').getActivePanel().id;
523         if (!agid) {
524             return;
525         }
526         Pman.Tab[agid].paging.onClick('refresh');
527     },
528     toCidV : function(data) {
529         return 'C' + data.in_out.substring(0,1) + data.cid;
530     },
531     
532     standardActionFailed :  function(f, act, cb) {
533     
534         if (act.failureType == 'client') {
535             Ext.MessageBox.alert("Error", "Please Correct all the errors in red", cb);
536             return;
537         }
538         if (act.failureType == 'connect') {
539             Ext.MessageBox.alert("Error", "Problem Connecting to Server - please try again.", cb);
540             return;
541         }
542         
543         if (act.type == 'submit') {
544             
545             Ext.MessageBox.alert("Error", typeof(act.result.errorMsg) == 'string' ?
546                 String.format('{0}', act.result.errorMsg) : 
547                 "Saving failed = fix errors and try again", cb);
548             return;
549         }
550         
551         // what about load failing..
552         Ext.MessageBox.alert("Error", "Error loading details",cb); 
553     },
554     /**
555      * 
556      * similar to Ext.Ajax, but handles our responses better...
557      * c.url
558      * c.method
559      * c.params
560      * c.failure() == failure function..
561      * c.success(data) == success function..
562      * 
563      * 
564      */
565     request : function(c) {
566         
567         Ext.Ajax.request({
568             timeout : c.timeout || 30000,
569             url: c.url,
570             method : c.method,
571             params: c.params,
572             xmlData : c.xmlData,
573             success:  function(response, opts)  {  // check successfull...
574                
575                 var res = Pman.processResponse(response);
576                 
577                 if (!res.success) { // error!
578                     if (c.failure) {
579                         if (true === c.failure.call(this,response, opts)) {
580                             return;
581                         }
582                     }
583                     Roo.MessageBox.hide();
584                     Ext.MessageBox.alert("Error", res.errorMsg ? res.errorMsg : "Error Sending");
585                     return;
586                 }
587                 
588                 c.success.call(this, res.data);
589                 
590                 return; 
591             },
592             failure :  function(response, opts)  {  // check successfull...
593                 
594                 if (c.failure) {
595                     if (true === c.failure.call(this,response, opts)) {
596                         return;
597                     }
598                 }
599                 Roo.MessageBox.hide();
600                 Roo.MessageBox.alert("Error", "Connection timed out sending");
601                 console.log(response);
602                 
603             },
604             scope: this
605             
606         });
607     },
608     csvFrame : false,
609     
610     createCsvFrame: function()
611     {
612         
613         if (this.csvFrame) {
614             document.body.removeChild(this.csvFrame);
615         }
616             
617         var id = Ext.id();
618         this.csvFrame = document.createElement('iframe');
619         this.csvFrame.id = id;
620         this.csvFrame.name = id;
621         this.csvFrame.className = 'x-hidden';
622         if(Ext.isIE){
623             this.csvFrame.src = Ext.SSL_SECURE_URL;
624         }
625         document.body.appendChild(this.csvFrame);
626
627         if(Ext.isIE){
628             document.frames[id].name = id;
629         }
630         
631     },
632     /**
633      * download({
634           url: 
635          })
636      * 
637      * 
638      */
639     
640     
641     download : function(c) {
642         
643         if (c.newWindow) {
644             // as ie seems buggy...
645             window.open( c.url + '?' + Roo.urlEncode(c.params || {}), '_blank');
646             return;
647             
648         }
649         
650         this.createCsvFrame();
651         function cb(){
652             var r = { responseText : "", responseXML : null };
653
654             var frame = this.csvFrame;
655
656             try { 
657                 var doc = Ext.isIE ? 
658                     frame.contentWindow.document : 
659                     (frame.contentDocument || window.frames[this.csvFrame.id].document);
660                 
661                 if(doc && doc.body && doc.body.innerHTML.length){
662                   //  alert(doc.body.innerHTML);
663                     Ext.MessageBox.alert("Error download",doc.body.innerHTML);
664                 }
665                  
666             }
667             catch(e) {
668             }
669
670             Ext.EventManager.removeListener(frame, 'load', cb, this);
671  
672         }
673         Ext.EventManager.on( this.csvFrame, 'load', cb, this);
674         this.csvFrame.src = c.url;
675     },
676     downloadRevision : function(doc, rev)
677     {
678         this.download({
679             url: baseURL + '/Documents/Doc/DownloadRev/'+ doc.id + '/' + rev + '/' +
680                 doc.project_id_code + '-' + doc.cidV + '-' + rev  + '-' +  doc.filename
681         }); 
682                     
683     },
684     exportCSV : function(c) {
685         //this.createCsvFrame(); 
686         for(var i=0;i < c.csvFormat.length;i++) {
687             c.params['csvCols['+i+']'] = c.csvFormat[i][0];
688             c.params['csvTitles['+i+']'] = c.csvFormat[i][1];
689         }
690         
691         
692         c.url +=  '?' + Ext.urlEncode(c.params);
693         this.download(c);
694
695     },
696     prettyDate : function (value) 
697     {
698         if (typeof(value) == 'string') {
699             var ds = Date.parseDate(value, 'Y-m-d H:i:s');
700             if (ds) {
701                 return this.prettyDate(ds);
702             }
703             ds = Date.parseDate(value, 'Y-m-d');
704             if (ds) {
705                 return this.prettyDate(ds);
706             }
707             return '';
708         }
709 // last 7 days...
710         if (!value) {
711             return '';
712         }
713         var td = new Date();
714         var daysSince = Math.floor(td.getElapsed(value) / (1000 * 60*60*24));
715         if (daysSince < 7) {
716             return value.dateFormat('D H:i');
717         }
718         
719         // same month
720         if (td.dateFormat('m') == value.dateFormat('m')) {
721             return value.dateFormat('dS D');
722         }
723         // same year?
724         if (td.dateFormat('Y') == value.dateFormat('Y')) {
725             return value.dateFormat('dS M');
726         }
727         return value.dateFormat('d M Y');
728     },
729     loadException : function(a,b,c,d)
730     {
731         if (d && d.authFailure) {
732             Pman.Login.show();
733             return;
734         }
735         Roo.MessageBox.alert("Problem Loading Data", a.message || c.statusText);
736     },
737     
738     
739     /**
740      * 
741      * Routine to flash alerts in the title bar..
742      * 
743      * 
744      */
745     
746     notifyActive : false,
747     
748     notifyTitle: function(msg)
749     {
750         if (this.notifyActive ) {
751             return;
752         }
753         var stop = false;
754         
755         var stopper = function() {
756             stop = true;
757              document.title = oldtitle;
758         };
759         
760         Roo.get(document.body).on('mousemove', stopper, this);
761         var oldtitle = document.title;
762         var s = 1;
763         var _this = this;
764         var ivl = window.setInterval(function() {
765             
766             if (stop) {
767                 Roo.get(document.body).un('mousemove', stopper, this);
768                 _this.notifyActive = false;
769                 document.title = oldtitle;
770                 window.clearInterval(ivl);
771                 return true;
772             }
773             s = !s;
774             document.title = s ? msg : oldtitle;
775                   
776         }, 1000); // every 120 secs = 2mins..
777          document.title =   msg;
778         
779         
780         
781     },
782     
783     modules : false,
784     /**
785      * example:
786      * 
787      * Pman.register({
788           modKey : '00-admin-xxxx',
789           module : Pman.Tab.projectMgr,
790           region : 'center',
791           parent : Pman.layout
792         })
793      * 
794      */
795     register : function(obj) {
796         if (!obj.parent) {
797             if (obj.parent === false) {
798                 //console.log(obj);
799                 return;
800             }
801             
802             console.log(obj);
803         }
804         if (!obj.parent.modules) {
805             obj.parent.modules = new Roo.util.MixedCollection(false, function(o) { return o.modKey });
806         }
807         obj.parent.modules.add(obj);
808         
809     },
810     
811     buildModules : function(parent, onComplete) 
812     {
813         
814         var _this = this;
815         var cmp = function(a,b) {   
816             return String(a).toUpperCase() > String(b).toUpperCase() ? 1 : -1;
817             
818         };
819         if (!parent.modules) {
820             return;
821         }
822         parent.modules.keySort('ASC',  cmp );
823         var mods = [];
824         
825         
826         // add modules to their parents..
827         var addMod = function(m) {
828            // console.log(m.modKey);
829             
830             mods.push(m);
831             if (m.module.modules) {
832                 m.module.modules.keySort('ASC',  cmp );
833                 m.module.modules.each(addMod);
834             }
835             if (m.finalize) {
836                 m.finalize.name = m.name + " (clean up) ";
837                 mods.push(m.finalize);
838             }
839             
840         }
841  
842         parent.modules.each(addMod);
843         //this.allmods = mods;
844         //console.log(mods);
845         //return;
846         if (!mods.length) {
847             if (onComplete) onComplete();
848             return;
849         }
850         // flash it up as modal - so we store the mask!?
851         Ext.MessageBox.show({ title: 'loading' });
852         Ext.MessageBox.show({
853            title: "Please wait...",
854            msg: "Building Interface...",
855            width:450,
856            progress:true,
857            closable:false,
858            modal: false
859           
860         });
861         var n = 0;
862         var progressRun = function() {
863             
864             var m = mods[n];
865             
866             
867             Ext.MessageBox.updateProgress(
868                 (n+1)/mods.length,  "Building Interface " + (n+1) + 
869                     " of " + mods.length + 
870                     (m.name ? (' - ' + m.name) : '')
871                     );
872             
873             
874             
875             if (typeof(m) == 'function') {
876                 m();
877                 
878             } else {
879                 if (m.parent.layout && !m.module.disabled) {
880                     m.module.add(m.parent.layout, m.region);    
881                 }
882                 
883             }
884             
885             
886             n++;
887             if (n >= mods.length) {
888                 onComplete();  
889                 return;
890             }
891                 
892             
893             progressRun.defer(10, Pman);    
894         }
895         progressRun.defer(1, Pman);
896      
897         
898         
899     },
900     
901     gtranslate : function(str, src, dest, cb) {
902         // load script: 
903         
904         
905         var x = new Roo.data.ScriptTagProxy({ 
906             url:  'http://ajax.googleapis.com/ajax/services/language/translate', 
907             callbackParam : 'callback' 
908         });
909         x.load(
910             {
911                 v: '1.0',
912                 q : str,
913                 langpair : src + '|' +dest
914             }, // end params.
915             { // reader
916                 readRecords : function (o) {
917                     if (!o.responseData) {
918                         return o;
919                     }
920                     return o.responseData.translatedText;
921                 }
922             }, 
923             function (result) {
924                 cb(result);
925             },
926             this,
927             []
928         );
929         
930             
931         
932     } ,
933     invertColor : function(c)
934     {
935         // read..
936         var ca = [];
937         for(var i = 0; i < 3; i++){
938             ca[i] = parseInt(c.charAt((i*2)+1) + c.charAt((i*2)+2), 16);
939         }
940             
941         // invert..
942         var col = '';
943         Roo.each(ca, function(hi) {
944             var h = parseInt(255-hi).toString(16);
945             if(h < 16){
946                 h = '0' + h;
947             }
948             col += h;
949         });
950         return '#' + col;
951         
952     }
953     
954     
955     
956     
957     
958     
959     
960 });
961