Builder/Provider/Project/Base.js
[app.Builder.js] / Builder / Provider / Project / Base.js
1 //<Script type="text/javascript">
2
3 /**
4  * Project Object
5  * 
6  * Projects can only contain one directory... - it can import other projects..(later)
7  * 
8  * we need to sort out that - paths is currently a key/value array..
9  * 
10  * 
11  * 
12  */
13
14 Gio = imports.gi.Gio;
15 GLib = imports.gi.GLib; 
16
17
18 console = imports.console;
19 XObject = imports.XObject.XObject;
20
21 ProjectManager = imports.Builder.Provider.ProjectManager.ProjectManager;
22 Observable = imports.Observable.Observable;
23
24 Base = XObject.define( 
25     function(cfg) {
26         
27         
28         this.addEvents({ 'changed'  : true });
29         var _this = this;
30         this.on('changed' , function() {
31             Seed.print("Calling PM - changed");
32             
33             ProjectManager.fireEvent('changed');
34         });
35         XObject.extend(this, cfg);
36         this.files = { }; 
37         /*
38         if (this.files ){
39             for (var f in this.files) {
40                 var xt = this.xtype;
41                 var cls = imports.Builder.Provider.File[xt][xt];
42                 this.files[f] = cls(this.files[f]);
43             }
44         }
45         */
46         
47         
48         this.scanDirs();
49         
50     },
51     Observable, 
52     {
53         id : false,
54         fn:  false, // the md5 sum for this one..
55         paths : false,
56         files : false,
57         tree : false,
58         xtype : false,
59         
60         load : function (o)  // is this used??
61         {
62             if (!this.fetchTree) {
63                 console.log("Project.getTree tree called on base object?!?!");
64                 return false;
65             }
66             
67             if (this.files) {
68                 return o.success.apply(o.scope || this, [this]);
69             }
70             return this.fetchTree(o);
71             
72         },
73         getPalete : function()
74         {
75             print("GET PROVIDER FOR " + this.xtype);
76             return  ProjectManager.getPalete(this.xtype);
77         },
78         toJSON : function()
79         {
80             var ret = { };
81             var _this = this;
82             ['id', 'fn', 'paths', 'xtype', 'name'].forEach(  function(k) {
83                 ret[k] = _this[k];
84                 
85             });
86             ret.files = { }; 
87             // deal with files..
88             for (var f in this.files) {
89                 print(f);
90                 ret.files[f] = this.files[f].toJsonArray();
91             }
92             
93             
94             return JSON.stringify(ret);
95           
96           
97         },
98         toTree : function()
99         {
100             
101             
102             // normally this will build tree's based on info in the file stuff..
103             // but for the time being, we just return an array of all the files.
104             
105             
106             
107             //if (this.tree) {
108              //   return this.tree;
109             //}
110             
111             this.tree = [];
112             /*
113             for (var f in this.files) {
114                 this.tree.push(this.files[f]);
115             }
116             return this.tree;
117             */
118             
119             // have parents -> add them to parent...
120             var files = {};
121             var parents = {};
122             for (var k in this.files) {
123                 
124                 var f = this.files[k];
125                 if (!f) {
126                     continue;
127                    }
128                 ///console.dump(f);
129                 f.hasParent = false;
130                 f.cn = [];
131                 //console.log(f.name);
132                 if (f.fullname) {
133                     files[f.fullname] = f;
134                 }
135             };
136             
137             // add Parent pointer..
138             for (var k in this.files) {
139                 var f = this.files[k];
140                 console.log(f.parent + ":" + f.name);
141                 if (f.parent && typeof(files[f.parent]) != 'undefined') {
142                     // add it to parent;
143                     
144                     files[f.parent].cn.push(f);
145                     f.hasParent = true;
146                     
147                 }
148                 
149                 
150             };
151             
152               
153             
154             var ret = [];
155             for (var k in this.files) {
156                 var f = this.files[k];
157                 
158                 f.sortCn();
159                 if (f.hasParent) {
160                     continue;
161                 }
162                 if (typeof(files[f.fullname]) != 'undefined') {
163                     ret.push(f);
164                 }
165                 
166             };
167             
168             
169             ret.sort(function(a,b) {
170                 return a.path > b.path ? 1 : -1;
171             });
172             this.tree = ret;
173             return this.tree;
174              
175             
176         },
177         getById : function(id)
178         {
179             var ret = false;
180             for (var k in this.files) {
181                 var f = this.files[k];
182                 
183                 console.log(f.id + '?=' + id);
184                 if (f.id == id) {
185                     return f;
186                 }
187             };
188             return ret;
189         },
190         
191         loadFileOnly : function(path)
192         {
193             
194             var xt = this.xtype;
195             var cls = imports.Builder.Provider.File[xt][xt];
196             return  new cls({
197                 path : path,
198                 parent : '',
199                 project : this
200             });
201         },
202         create : function(filename)
203         {
204             var ret = this.loadFileOnly(filename);
205             ret.save();
206             this.addFile(ret);
207             return ret;
208             
209         },
210         
211          
212         addFile: function(pfile) { // add a single file, and trigger changed.
213             this.files[pfile.path] = pfile
214             this.fireEvent('changed', this);
215         },
216         
217         add: function(path, type)
218         {
219             this.paths = this.paths || { };
220             this.paths[path] = type;
221             //Seed.print(" type is '" + type + "'");
222             if (type == 'dir') {
223                 this.scanDir(path);
224             //    console.dump(this.files);
225             }
226             if (type == 'file' ) {
227                 
228                 this.files[path] = this.loadFileOnly( path );
229             }
230             
231             // console.dump(this.files);
232             this.fireEvent('changed', this);
233             
234         },
235         
236         scanDirs: function()
237         {
238             this.files = this.files  || { };
239             for (var d in this.paths) {
240                 if (this.paths[d] == 'dir') {
241                     this.scanDir(d);
242                 }
243                 // otherwise add a file..
244             }
245             //console.dump(this.files);
246             
247         },
248         
249         
250         // list files.
251         scanDir : function(dir, dp) 
252         {
253             dp = dp || 0;
254             Seed.print("Running scandir on " + dir);
255             if (dp > 5) { // no more than 5 deep?
256                 return;
257             }
258             // this should be done async -- but since we are getting the proto up ...
259             var gdir = GLib.dir_open(dir,0);
260             var subs = [];
261             var _this = this;
262             while (true) {
263                 var fn = GLib.dir_read_name(gdir);
264                 console.log('trying ' + dir + '/' + fn);
265                 if (!fn) {
266                     GLib.dir_close(gdir);
267                     subs.forEach( function(s) {
268                         _this.scanDir(s, dp+1);
269                     });
270                     return;
271                 }
272                 if (fn[0] == '.') { // skip hidden
273                     continue;
274                 }
275                 
276                 if (GLib.file_test(dir  + '/' + fn, GLib.FileTest.IS_DIR)) {
277                     subs.push(dir  + '/' + fn);
278                     continue;
279                 }
280                 
281                 if (!fn.match(/\.bjs$/)) {
282                     continue;
283                 }
284                 var parent = '';
285                 //if (dp > 0 ) {
286                 var sp = dir.split('/');
287                 sp = sp.splice(sp.length - (dp +1), (dp +1));
288                 parent = sp.join('.');
289                 
290                 
291                 if (typeof(this.files[dir  + '/' + fn]) != 'undefined') {
292                     // we already have it..
293                     this.files[dir  + '/' + fn].parent = parent;
294                     continue;
295                 }
296                 var xt = this.xtype;
297                 var cls = imports.Builder.Provider.File[xt][xt];
298                 
299                 Seed.print("Adding file " + dir  + '/' + fn);
300                 this.files[dir  + '/' + fn] = new cls({
301                     path : dir  + '/' + fn,
302                     parent : parent,
303                     project : this
304                 });
305                 console.log(this.files[dir  + '/' + fn] );
306                 /*
307                 var f = Gio.file_new_for_path(dir + '/' + fn);
308                 var inf = f.query_info('standard::*');
309                 var tv = new GLib.TimeVal();
310                 inf.get_modification_time(tv);
311                 
312                 // should it do something about this information..
313                 // fixme... time data is busted..
314                 this.files[dir  + '/' + fn] = '' + tv.tv_sec + '.' + tv.tv_usec;
315                 */
316             }
317              
318             
319         }
320         
321         
322         
323         
324         
325
326     }
327 ); 
328
329
330      
331