640fce39b16f1142ad3a6a79f0a35a1c9ef79ed4
[blender-staging.git] / source / blender / editors / space_file / space_file.c
1 /**
2  * $Id:
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2008 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include <string.h>
30 #include <stdio.h>
31
32 #include "DNA_object_types.h"
33 #include "DNA_space_types.h"
34 #include "DNA_scene_types.h"
35 #include "DNA_screen_types.h"
36
37 #include "RNA_access.h"
38
39 #include "MEM_guardedalloc.h"
40
41 #include "BIF_gl.h"
42
43 #include "BLO_readfile.h"
44
45 #include "BLI_blenlib.h"
46 #include "BLI_math.h"
47 #include "BLI_rand.h"
48 #include "BLI_storage_types.h"
49
50 #include "BKE_colortools.h"
51 #include "BKE_context.h"
52 #include "BKE_screen.h"
53
54 #include "ED_space_api.h"
55 #include "ED_screen.h"
56 #include "ED_fileselect.h"
57
58 #include "IMB_imbuf_types.h"
59 #include "IMB_thumbs.h"
60
61 #include "WM_api.h"
62 #include "WM_types.h"
63
64 #include "UI_interface.h"
65 #include "UI_resources.h"
66 #include "UI_view2d.h"
67
68
69 #include "ED_markers.h"
70 #include "ED_fileselect.h"
71
72 #include "file_intern.h"        // own include
73 #include "fsmenu.h"
74 #include "filelist.h"
75
76 /* ******************** default callbacks for file space ***************** */
77
78 static SpaceLink *file_new(const bContext *C)
79 {
80         ARegion *ar;
81         SpaceFile *sfile;
82         
83         sfile= MEM_callocN(sizeof(SpaceFile), "initfile");
84         sfile->spacetype= SPACE_FILE;
85
86         /* header */
87         ar= MEM_callocN(sizeof(ARegion), "header for file");
88         BLI_addtail(&sfile->regionbase, ar);
89         ar->regiontype= RGN_TYPE_HEADER;
90         ar->alignment= RGN_ALIGN_TOP;
91
92         /* channel list region */
93         ar= MEM_callocN(sizeof(ARegion), "channel area for file");
94         BLI_addtail(&sfile->regionbase, ar);
95         ar->regiontype= RGN_TYPE_CHANNELS;
96         ar->alignment= RGN_ALIGN_LEFT;  
97
98         /* ui list region */
99         ar= MEM_callocN(sizeof(ARegion), "ui area for file");
100         BLI_addtail(&sfile->regionbase, ar);
101         ar->regiontype= RGN_TYPE_UI;
102         ar->alignment= RGN_ALIGN_TOP;
103
104         /* main area */
105         ar= MEM_callocN(sizeof(ARegion), "main area for file");
106         BLI_addtail(&sfile->regionbase, ar);
107         ar->regiontype= RGN_TYPE_WINDOW;
108         ar->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
109         ar->v2d.align = (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y);
110         ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_LIMITZOOM|V2D_KEEPASPECT);
111         ar->v2d.keeptot= V2D_KEEPTOT_STRICT;
112         ar->v2d.minzoom= ar->v2d.maxzoom= 1.0f;
113
114         return (SpaceLink *)sfile;
115 }
116
117 /* not spacelink itself */
118 static void file_free(SpaceLink *sl)
119 {       
120         SpaceFile *sfile= (SpaceFile *) sl;
121         
122         if(sfile->files) {
123                 // XXXXX would need to do thumbnails_stop here, but no context available
124                 filelist_freelib(sfile->files);
125                 filelist_free(sfile->files);
126                 MEM_freeN(sfile->files);
127                 sfile->files= NULL;
128         }
129
130         if(sfile->folders_prev) {
131                 folderlist_free(sfile->folders_prev);
132                 MEM_freeN(sfile->folders_prev);
133                 sfile->folders_prev= NULL;
134         }
135
136         if(sfile->folders_next) {
137                 folderlist_free(sfile->folders_next);
138                 MEM_freeN(sfile->folders_next);
139                 sfile->folders_next= NULL;
140         }
141
142         if (sfile->params) {
143                 MEM_freeN(sfile->params);
144                 sfile->params= NULL;
145         }
146
147         if (sfile->layout) {
148                 MEM_freeN(sfile->layout);
149                 sfile->layout = NULL;
150         }
151 }
152
153
154 /* spacetype; init callback, area size changes, screen set, etc */
155 static void file_init(struct wmWindowManager *wm, ScrArea *sa)
156 {
157         SpaceFile *sfile= (SpaceFile*)sa->spacedata.first;
158         //printf("file_init\n");
159
160         if(sfile->layout) sfile->layout->dirty= 1;
161 }
162
163
164 static SpaceLink *file_duplicate(SpaceLink *sl)
165 {
166         SpaceFile *sfileo= (SpaceFile*)sl;
167         SpaceFile *sfilen= MEM_dupallocN(sl);
168         
169         /* clear or remove stuff from old */
170         sfilen->op = NULL; /* file window doesn't own operators */
171
172         if (sfileo->params) {
173                 sfilen->files = filelist_new(sfileo->params->type);
174                 sfilen->params= MEM_dupallocN(sfileo->params);
175                 filelist_setdir(sfilen->files, sfilen->params->dir);
176         }
177
178         if(sfileo->folders_prev)
179                 sfilen->folders_prev = folderlist_duplicate(sfileo->folders_prev);
180
181         if(sfileo->folders_next)
182                 sfilen->folders_next = folderlist_duplicate(sfileo->folders_next);
183         
184         if (sfileo->layout) {
185                 sfilen->layout= MEM_dupallocN(sfileo->layout);
186         }
187         return (SpaceLink *)sfilen;
188 }
189
190 static void file_refresh(const bContext *C, ScrArea *sa)
191 {
192         SpaceFile *sfile= CTX_wm_space_file(C);
193         FileSelectParams *params = ED_fileselect_get_params(sfile);
194
195         if (!sfile->folders_prev)
196                 sfile->folders_prev = folderlist_new();
197         if (!sfile->files) {
198                 sfile->files = filelist_new(params->type);
199                 filelist_setdir(sfile->files, params->dir);
200                 params->active_file = -1; // added this so it opens nicer (ton)
201         }
202         filelist_hidedot(sfile->files, params->flag & FILE_HIDE_DOT);
203         filelist_setfilter(sfile->files, params->flag & FILE_FILTER ? params->filter : 0);      
204         if (filelist_empty(sfile->files))
205         {
206                 filelist_readdir(sfile->files);
207                 thumbnails_start(sfile->files, C);
208                 BLI_strncpy(params->dir, filelist_dir(sfile->files), FILE_MAX);
209         } else {
210                 filelist_filter(sfile->files);
211         }
212         if(params->sort!=FILE_SORT_NONE) filelist_sort(sfile->files, params->sort);             
213         
214         if (params->renamefile[0] != '\0') {
215                 int idx = filelist_find(sfile->files, params->renamefile);
216                 if (idx >= 0) {
217                         struct direntry *file= filelist_file(sfile->files, idx);
218                         if (file) {
219                                 file->flags |= EDITING;
220                         }
221                 }
222                 params->renamefile[0] = '\0';
223         }
224         if (sfile->layout) sfile->layout->dirty= 1;
225
226 }
227
228 static void file_listener(ScrArea *sa, wmNotifier *wmn)
229 {
230     /* SpaceFile* sfile = (SpaceFile*)sa->spacedata.first; */
231
232         /* context changes */
233         switch(wmn->category) {
234                 case NC_SPACE:
235                         switch (wmn->data) {
236                                 case ND_SPACE_FILE_LIST:
237                                         ED_area_tag_refresh(sa);
238                                         ED_area_tag_redraw(sa);
239                                         break;
240                                 case ND_SPACE_FILE_PARAMS:
241                                         ED_area_tag_refresh(sa);
242                                         ED_area_tag_redraw(sa);
243                                         break;
244                         }
245                         break;
246         }
247 }
248
249 /* add handlers, stuff you only do once or on area/region changes */
250 static void file_main_area_init(wmWindowManager *wm, ARegion *ar)
251 {
252         wmKeyMap *keymap;
253         
254         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
255         
256         /* own keymaps */
257         keymap= WM_keymap_find(wm->defaultconf, "File Browser", SPACE_FILE, 0);
258         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
259
260         keymap= WM_keymap_find(wm->defaultconf, "File Browser Main", SPACE_FILE, 0);
261         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
262                                                            
263
264 }
265
266 static void file_main_area_listener(ARegion *ar, wmNotifier *wmn)
267 {
268         /* context changes */
269         switch(wmn->category) {
270                 case NC_SPACE:
271                         switch (wmn->data) {
272                                 case ND_SPACE_FILE_LIST:
273                                         ED_region_tag_redraw(ar);
274                                         break;
275                                 case ND_SPACE_FILE_PARAMS:
276                                         ED_region_tag_redraw(ar);
277                                         break;
278                         }
279                         break;
280         }
281 }
282
283 static void file_main_area_draw(const bContext *C, ARegion *ar)
284 {
285         /* draw entirely, view changes should be handled here */
286         SpaceFile *sfile= CTX_wm_space_file(C);
287         FileSelectParams *params = ED_fileselect_get_params(sfile);
288         FileLayout *layout=NULL;
289
290         View2D *v2d= &ar->v2d;
291         View2DScrollers *scrollers;
292         float col[3];
293
294         /* Needed, because filelist is not initialized on loading */
295         if (!sfile->files || filelist_empty(sfile->files))
296                 file_refresh(C, NULL);
297
298         layout = ED_fileselect_get_layout(sfile, ar);
299
300         /* clear and setup matrix */
301         UI_GetThemeColor3fv(TH_BACK, col);
302         glClearColor(col[0], col[1], col[2], 0.0);
303         glClear(GL_COLOR_BUFFER_BIT);
304         
305         /* Allow dynamically sliders to be set, saves notifiers etc. */
306         if (layout && (layout->flag == FILE_LAYOUT_VER)) {
307                 v2d->scroll = V2D_SCROLL_RIGHT;
308                 v2d->keepofs &= ~V2D_LOCKOFS_Y;
309                 v2d->keepofs |= V2D_LOCKOFS_X;
310         }
311         else {
312                 v2d->scroll = V2D_SCROLL_BOTTOM;
313                 v2d->keepofs &= ~V2D_LOCKOFS_X;
314                 v2d->keepofs |= V2D_LOCKOFS_Y;
315         }
316         /* v2d has initialized flag, so this call will only set the mask correct */
317         UI_view2d_region_reinit(v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
318
319         /* sets tile/border settings in sfile */
320         file_calc_previews(C, ar);
321
322         /* set view */
323         UI_view2d_view_ortho(C, v2d);
324         
325         /* on first read, find active file */
326         if (params->active_file == -1) {
327                 wmEvent *event= CTX_wm_window(C)->eventstate;
328                 file_hilight_set(sfile, ar, event->x, event->y);
329         }
330         
331         file_draw_list(C, ar);
332         
333         /* reset view matrix */
334         UI_view2d_view_restore(C);
335         
336         /* scrollers */
337         scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
338         UI_view2d_scrollers_draw(C, v2d, scrollers);
339         UI_view2d_scrollers_free(scrollers);
340
341 }
342
343 void file_operatortypes(void)
344 {
345         WM_operatortype_append(FILE_OT_select);
346         WM_operatortype_append(FILE_OT_select_all_toggle);
347         WM_operatortype_append(FILE_OT_select_border);
348         WM_operatortype_append(FILE_OT_select_bookmark);
349         WM_operatortype_append(FILE_OT_highlight);
350         WM_operatortype_append(FILE_OT_execute);
351         WM_operatortype_append(FILE_OT_cancel);
352         WM_operatortype_append(FILE_OT_parent);
353         WM_operatortype_append(FILE_OT_previous);
354         WM_operatortype_append(FILE_OT_next);
355         WM_operatortype_append(FILE_OT_refresh);
356         WM_operatortype_append(FILE_OT_bookmark_toggle);
357         WM_operatortype_append(FILE_OT_bookmark_add);
358         WM_operatortype_append(FILE_OT_delete_bookmark);
359         WM_operatortype_append(FILE_OT_hidedot);
360         WM_operatortype_append(FILE_OT_filenum);
361         WM_operatortype_append(FILE_OT_directory_new);
362         WM_operatortype_append(FILE_OT_delete);
363         WM_operatortype_append(FILE_OT_rename);
364 }
365
366 /* NOTE: do not add .blend file reading on this level */
367 void file_keymap(struct wmKeyConfig *keyconf)
368 {
369         wmKeyMapItem *kmi;
370         /* keys for all areas */
371         wmKeyMap *keymap= WM_keymap_find(keyconf, "File Browser", SPACE_FILE, 0);
372         WM_keymap_add_item(keymap, "FILE_OT_bookmark_toggle", NKEY, KM_PRESS, 0, 0);
373         WM_keymap_add_item(keymap, "FILE_OT_parent", PKEY, KM_PRESS, 0, 0);
374         WM_keymap_add_item(keymap, "FILE_OT_bookmark_add", BKEY, KM_PRESS, KM_CTRL, 0);
375         WM_keymap_add_item(keymap, "FILE_OT_hidedot", HKEY, KM_PRESS, 0, 0);
376         WM_keymap_add_item(keymap, "FILE_OT_previous", BACKSPACEKEY, KM_PRESS, 0, 0);
377         WM_keymap_add_item(keymap, "FILE_OT_next", BACKSPACEKEY, KM_PRESS, KM_SHIFT, 0);
378         WM_keymap_add_item(keymap, "FILE_OT_directory_new", IKEY, KM_PRESS, 0, 0);  /* XXX needs button */
379         WM_keymap_add_item(keymap, "FILE_OT_delete", XKEY, KM_PRESS, 0, 0);
380         WM_keymap_add_item(keymap, "FILE_OT_delete", DELKEY, KM_PRESS, 0, 0);
381
382         /* keys for main area */
383         keymap= WM_keymap_find(keyconf, "File Browser Main", SPACE_FILE, 0);
384         WM_keymap_add_item(keymap, "FILE_OT_select_execute", LEFTMOUSE, KM_DBL_CLICK, 0, 0);
385         WM_keymap_add_item(keymap, "FILE_OT_select", LEFTMOUSE, KM_CLICK, 0, 0);
386         kmi = WM_keymap_add_item(keymap, "FILE_OT_select", LEFTMOUSE, KM_CLICK, KM_SHIFT, 0);
387         RNA_boolean_set(kmi->ptr, "extend", 1);
388         WM_keymap_add_item(keymap, "FILE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
389         WM_keymap_add_item(keymap, "FILE_OT_select_border", BKEY, KM_PRESS, 0, 0);
390         WM_keymap_add_item(keymap, "FILE_OT_select_border", EVT_TWEAK_L, KM_ANY, 0, 0);
391         WM_keymap_add_item(keymap, "FILE_OT_rename", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
392         WM_keymap_add_item(keymap, "FILE_OT_highlight", MOUSEMOVE, KM_ANY, KM_ANY, 0);
393         kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADPLUSKEY, KM_PRESS, 0, 0);
394         RNA_int_set(kmi->ptr, "increment", 1);
395         kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADPLUSKEY, KM_PRESS, KM_SHIFT, 0);
396         RNA_int_set(kmi->ptr, "increment", 10);
397         kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
398         RNA_int_set(kmi->ptr, "increment", 100);
399         kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADMINUS, KM_PRESS, 0,0);
400         RNA_int_set(kmi->ptr, "increment", -1);
401         kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADMINUS, KM_PRESS, KM_SHIFT, 0);
402         RNA_int_set(kmi->ptr, "increment", -10);
403         kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADMINUS, KM_PRESS, KM_CTRL, 0);
404         RNA_int_set(kmi->ptr, "increment",-100);
405         
406         /* keys for button area (top) */
407         keymap= WM_keymap_find(keyconf, "File Browser Buttons", SPACE_FILE, 0);
408         kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADPLUSKEY, KM_PRESS, 0, 0);
409         RNA_int_set(kmi->ptr, "increment", 1);
410         kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADPLUSKEY, KM_PRESS, KM_SHIFT, 0);
411         RNA_int_set(kmi->ptr, "increment", 10);
412         kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
413         RNA_int_set(kmi->ptr, "increment", 100);
414         kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADMINUS, KM_PRESS, 0, 0);
415         RNA_int_set(kmi->ptr, "increment", -1);
416         kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADMINUS, KM_PRESS, KM_SHIFT,0);
417         RNA_int_set(kmi->ptr, "increment", -10);
418         kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADMINUS, KM_PRESS, KM_CTRL,0);
419         RNA_int_set(kmi->ptr, "increment",-100);
420 }
421
422
423 static void file_channel_area_init(wmWindowManager *wm, ARegion *ar)
424 {
425         wmKeyMap *keymap;
426
427         ED_region_panels_init(wm, ar);
428
429         /* own keymaps */
430         keymap= WM_keymap_find(wm->defaultconf, "File Browser", SPACE_FILE, 0); 
431         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
432 }
433
434 static void file_channel_area_draw(const bContext *C, ARegion *ar)
435 {
436         ED_region_panels(C, ar, 1, NULL, -1);
437 }
438
439 static void file_channel_area_listener(ARegion *ar, wmNotifier *wmn)
440 {
441         /* context changes */
442         switch(wmn->category) {
443                 
444         }
445 }
446
447 /* add handlers, stuff you only do once or on area/region changes */
448 static void file_header_area_init(wmWindowManager *wm, ARegion *ar)
449 {
450         ED_region_header_init(ar);
451 }
452
453 static void file_header_area_draw(const bContext *C, ARegion *ar)
454 {
455         ED_region_header(C, ar);
456 }
457
458 /* add handlers, stuff you only do once or on area/region changes */
459 static void file_ui_area_init(wmWindowManager *wm, ARegion *ar)
460 {
461         wmKeyMap *keymap;
462
463         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
464
465         /* own keymap */
466         keymap= WM_keymap_find(wm->defaultconf, "File Browser", SPACE_FILE, 0);
467         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
468
469         keymap= WM_keymap_find(wm->defaultconf, "File Browser Buttons", SPACE_FILE, 0);
470         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
471 }
472
473 static void file_ui_area_draw(const bContext *C, ARegion *ar)
474 {
475         float col[3];
476         /* clear */
477         UI_GetThemeColor3fv(TH_PANEL, col);
478         glClearColor(col[0], col[1], col[2], 0.0);
479         glClear(GL_COLOR_BUFFER_BIT);
480
481         /* set view2d view matrix for scrolling (without scrollers) */
482         UI_view2d_view_ortho(C, &ar->v2d);
483
484         file_draw_buttons(C, ar);
485
486         UI_view2d_view_restore(C);
487 }
488
489 static void file_ui_area_listener(ARegion *ar, wmNotifier *wmn)
490 {
491         /* context changes */
492         switch(wmn->category) {
493                 case NC_SPACE:
494                         switch (wmn->data) {
495                                 case ND_SPACE_FILE_LIST:
496                                         ED_region_tag_redraw(ar);
497                                         break;
498                         }
499                         break;
500         }
501 }
502
503 /* only called once, from space/spacetypes.c */
504 void ED_spacetype_file(void)
505 {
506         SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype file");
507         ARegionType *art;
508         
509         st->spaceid= SPACE_FILE;
510         strncpy(st->name, "File", BKE_ST_MAXNAME);
511         
512         st->new= file_new;
513         st->free= file_free;
514         st->init= file_init;
515         st->duplicate= file_duplicate;
516         st->refresh= file_refresh;
517         st->listener= file_listener;
518         st->operatortypes= file_operatortypes;
519         st->keymap= file_keymap;
520         
521         /* regions: main window */
522         art= MEM_callocN(sizeof(ARegionType), "spacetype file region");
523         art->regionid = RGN_TYPE_WINDOW;
524         art->init= file_main_area_init;
525         art->draw= file_main_area_draw;
526         art->listener= file_main_area_listener;
527         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
528         BLI_addhead(&st->regiontypes, art);
529         
530         /* regions: header */
531         art= MEM_callocN(sizeof(ARegionType), "spacetype file region");
532         art->regionid = RGN_TYPE_HEADER;
533         art->prefsizey= HEADERY;
534         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_HEADER;
535         art->init= file_header_area_init;
536         art->draw= file_header_area_draw;
537         // art->listener= file_header_area_listener;
538         BLI_addhead(&st->regiontypes, art);
539         
540         /* regions: ui */
541         art= MEM_callocN(sizeof(ARegionType), "spacetype file region");
542         art->regionid = RGN_TYPE_UI;
543         art->prefsizey= 60;
544         art->keymapflag= ED_KEYMAP_UI;
545         art->listener= file_ui_area_listener;
546         art->init= file_ui_area_init;
547         art->draw= file_ui_area_draw;
548         BLI_addhead(&st->regiontypes, art);
549
550         /* regions: channels (directories) */
551         art= MEM_callocN(sizeof(ARegionType), "spacetype file region");
552         art->regionid = RGN_TYPE_CHANNELS;
553         art->prefsizex= 240;
554         art->keymapflag= ED_KEYMAP_UI;
555         art->listener= file_channel_area_listener;
556         art->init= file_channel_area_init;
557         art->draw= file_channel_area_draw;
558         BLI_addhead(&st->regiontypes, art);
559         file_panels_register(art);
560
561         BKE_spacetype_register(st);
562
563 }
564
565 void ED_file_init(void)
566 {
567         char name[FILE_MAX];
568         BLI_make_file_string("/", name, BLI_gethome(), ".Bfs");
569         fsmenu_read_file(fsmenu_get(), name);
570         filelist_init_icons();
571         IMB_thumb_makedirs();
572 }
573
574 void ED_file_exit(void)
575 {
576         fsmenu_free(fsmenu_get());
577         filelist_free_icons();
578 }