FileBrowser: Editable Bookmarks.
[blender-staging.git] / source / blender / editors / space_file / file_draw.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2008 Blender Foundation.
19  * All rights reserved.
20  *
21  * 
22  * Contributor(s): Blender Foundation
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/editors/space_file/file_draw.c
28  *  \ingroup spfile
29  */
30
31
32 #include <math.h>
33 #include <string.h>
34
35 #include "BLI_blenlib.h"
36 #include "BLI_utildefines.h"
37 #include "BLI_fileops_types.h"
38
39 #ifdef WIN32
40 #  include "BLI_winstuff.h"
41 #endif
42
43 #include "BIF_gl.h"
44 #include "BIF_glutil.h"
45
46 #include "BKE_context.h"
47 #include "BKE_global.h"
48 #include "BKE_main.h"
49
50 #include "BLF_translation.h"
51
52 #include "IMB_imbuf_types.h"
53
54 #include "DNA_userdef_types.h"
55 #include "DNA_windowmanager_types.h"
56
57 #include "RNA_access.h"
58
59 #include "ED_fileselect.h"
60 #include "ED_screen.h"
61
62 #include "UI_interface.h"
63 #include "UI_interface_icons.h"
64 #include "UI_resources.h"
65 #include "UI_view2d.h"
66
67 #include "WM_types.h"
68
69 #include "filelist.h"
70
71 #include "file_intern.h"    // own include
72
73 /* Note: This function uses pixelspace (0, 0, winx, winy), not view2d. 
74  * The controls are laid out as follows:
75  *
76  * -------------------------------------------
77  * | Directory input               | execute |
78  * -------------------------------------------
79  * | Filename input        | + | - | cancel  |
80  * -------------------------------------------
81  *
82  * The input widgets will stretch to fill any excess space.
83  * When there isn't enough space for all controls to be shown, they are
84  * hidden in this order: x/-, execute/cancel, input widgets.
85  */
86 void file_draw_buttons(const bContext *C, ARegion *ar)
87 {
88         /* Button layout. */
89         const int max_x      = ar->winx - 10;
90         const int line1_y    = ar->winy - (IMASEL_BUTTONS_HEIGHT / 2 + IMASEL_BUTTONS_MARGIN);
91         const int line2_y    = line1_y - (IMASEL_BUTTONS_HEIGHT / 2 + IMASEL_BUTTONS_MARGIN);
92         const int input_minw = 20;
93         const int btn_h      = UI_UNIT_Y;
94         const int btn_fn_w   = UI_UNIT_X;
95         const int btn_minw   = 80;
96         const int btn_margin = 20;
97         const int separator  = 4;
98
99         /* Additional locals. */
100         char uiblockstr[32];
101         int loadbutton;
102         int fnumbuttons;
103         int min_x       = 10;
104         int chan_offs   = 0;
105         int available_w = max_x - min_x;
106         int line1_w     = available_w;
107         int line2_w     = available_w;
108         
109         uiBut *but;
110         uiBlock *block;
111         SpaceFile *sfile  = CTX_wm_space_file(C);
112         FileSelectParams *params = ED_fileselect_get_params(sfile);
113         ARegion *artmp;
114         const bool is_browse_only = (sfile->op == NULL);
115         
116         /* Initialize UI block. */
117         BLI_snprintf(uiblockstr, sizeof(uiblockstr), "win %p", (void *)ar);
118         block = UI_block_begin(C, ar, uiblockstr, UI_EMBOSS);
119
120         /* exception to make space for collapsed region icon */
121         for (artmp = CTX_wm_area(C)->regionbase.first; artmp; artmp = artmp->next) {
122                 if (artmp->regiontype == RGN_TYPE_TOOLS && artmp->flag & RGN_FLAG_HIDDEN) {
123                         chan_offs = 16;
124                         min_x += chan_offs;
125                         available_w -= chan_offs;
126                 }
127         }
128
129         /* Is there enough space for the execute / cancel buttons? */
130
131
132         if (is_browse_only) {
133                 loadbutton = 0;
134         }
135         else {
136                 const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
137                 loadbutton = UI_fontstyle_string_width(fstyle, params->title) + btn_margin;
138                 CLAMP_MIN(loadbutton, btn_minw);
139                 if (available_w <= loadbutton + separator + input_minw) {
140                         loadbutton = 0;
141                 }
142         }
143
144         if (loadbutton) {
145                 line1_w -= (loadbutton + separator);
146                 line2_w  = line1_w;
147         }
148
149         /* Is there enough space for file number increment/decrement buttons? */
150         fnumbuttons = 2 * btn_fn_w;
151         if (!loadbutton || line2_w <= fnumbuttons + separator + input_minw) {
152                 fnumbuttons = 0;
153         }
154         else {
155                 line2_w -= (fnumbuttons + separator);
156         }
157
158         /* Text input fields for directory and file. */
159         if (available_w > 0) {
160                 int overwrite_alert = file_draw_check_exists(sfile);
161                 /* callbacks for operator check functions */
162                 UI_block_func_set(block, file_draw_check_cb, NULL, NULL);
163
164                 but = uiDefBut(block, UI_BTYPE_TEXT, -1, "",
165                                min_x, line1_y, line1_w - chan_offs, btn_h,
166                                params->dir, 0.0, (float)FILE_MAX, 0, 0,
167                                TIP_("File path"));
168                 UI_but_func_complete_set(but, autocomplete_directory, NULL);
169                 UI_but_flag_enable(but, UI_BUT_NO_UTF8);
170                 UI_but_flag_disable(but, UI_BUT_UNDO);
171                 UI_but_funcN_set(but, file_directory_enter_handle, NULL, but);
172
173                 /* TODO, directory editing is non-functional while a library is loaded
174                  * until this is properly supported just disable it. */
175                 if (sfile->files && filelist_lib(sfile->files))
176                         UI_but_flag_enable(but, UI_BUT_DISABLED);
177
178                 if ((params->flag & FILE_DIRSEL_ONLY) == 0) {
179                         but = uiDefBut(block, UI_BTYPE_TEXT, -1, "",
180                                        min_x, line2_y, line2_w - chan_offs, btn_h,
181                                        params->file, 0.0, (float)FILE_MAXFILE, 0, 0,
182                                        TIP_(overwrite_alert ? N_("File name, overwrite existing") : N_("File name")));
183                         UI_but_func_complete_set(but, autocomplete_file, NULL);
184                         UI_but_flag_enable(but, UI_BUT_NO_UTF8);
185                         UI_but_flag_disable(but, UI_BUT_UNDO);
186                         /* silly workaround calling NFunc to ensure this does not get called
187                          * immediate ui_apply_but_func but only after button deactivates */
188                         UI_but_funcN_set(but, file_filename_enter_handle, NULL, but);
189
190                         /* check if this overrides a file and if the operator option is used */
191                         if (overwrite_alert) {
192                                 UI_but_flag_enable(but, UI_BUT_REDALERT);
193                         }
194                 }
195                 
196                 /* clear func */
197                 UI_block_func_set(block, NULL, NULL, NULL);
198         }
199         
200         /* Filename number increment / decrement buttons. */
201         if (fnumbuttons && (params->flag & FILE_DIRSEL_ONLY) == 0) {
202                 UI_block_align_begin(block);
203                 but = uiDefIconButO(block, UI_BTYPE_BUT, "FILE_OT_filenum", 0, ICON_ZOOMOUT,
204                                     min_x + line2_w + separator - chan_offs, line2_y,
205                                     btn_fn_w, btn_h,
206                                     TIP_("Decrement the filename number"));
207                 RNA_int_set(UI_but_operator_ptr_get(but), "increment", -1);
208
209                 but = uiDefIconButO(block, UI_BTYPE_BUT, "FILE_OT_filenum", 0, ICON_ZOOMIN,
210                                     min_x + line2_w + separator + btn_fn_w - chan_offs, line2_y,
211                                     btn_fn_w, btn_h,
212                                     TIP_("Increment the filename number"));
213                 RNA_int_set(UI_but_operator_ptr_get(but), "increment", 1);
214                 UI_block_align_end(block);
215         }
216         
217         /* Execute / cancel buttons. */
218         if (loadbutton) {
219                 /* params->title is already translated! */
220                 uiDefButO(block, UI_BTYPE_BUT, "FILE_OT_execute", WM_OP_EXEC_REGION_WIN, params->title,
221                           max_x - loadbutton, line1_y, loadbutton, btn_h, "");
222                 uiDefButO(block, UI_BTYPE_BUT, "FILE_OT_cancel", WM_OP_EXEC_REGION_WIN, IFACE_("Cancel"),
223                           max_x - loadbutton, line2_y, loadbutton, btn_h, "");
224         }
225         
226         UI_block_end(C, block);
227         UI_block_draw(C, block);
228 }
229
230
231 static void draw_tile(int sx, int sy, int width, int height, int colorid, int shade)
232 {
233         UI_ThemeColorShade(colorid, shade);
234         UI_draw_roundbox_corner_set(UI_CNR_ALL);
235         UI_draw_roundbox((float)sx, (float)(sy - height), (float)(sx + width), (float)sy, 5.0f);
236 }
237
238
239 static int get_file_icon(struct direntry *file)
240 {
241         if (file->type & S_IFDIR) {
242                 if (FILENAME_IS_PARENT(file->relname)) {
243                         return ICON_FILE_PARENT;
244                 }
245                 if (file->flags & FILE_TYPE_APPLICATIONBUNDLE) {
246                         return ICON_UGLYPACKAGE;
247                 }
248                 if (file->flags & FILE_TYPE_BLENDER) {
249                         return ICON_FILE_BLEND;
250                 }
251                 return ICON_FILE_FOLDER;
252         }
253         else if (file->flags & FILE_TYPE_BLENDER)
254                 return ICON_FILE_BLEND;
255         else if (file->flags & FILE_TYPE_BLENDER_BACKUP)
256                 return ICON_FILE_BACKUP;
257         else if (file->flags & FILE_TYPE_IMAGE)
258                 return ICON_FILE_IMAGE;
259         else if (file->flags & FILE_TYPE_MOVIE)
260                 return ICON_FILE_MOVIE;
261         else if (file->flags & FILE_TYPE_PYSCRIPT)
262                 return ICON_FILE_SCRIPT;
263         else if (file->flags & FILE_TYPE_SOUND)
264                 return ICON_FILE_SOUND;
265         else if (file->flags & FILE_TYPE_FTFONT)
266                 return ICON_FILE_FONT;
267         else if (file->flags & FILE_TYPE_BTX)
268                 return ICON_FILE_BLANK;
269         else if (file->flags & FILE_TYPE_COLLADA)
270                 return ICON_FILE_BLANK;
271         else if (file->flags & FILE_TYPE_TEXT)
272                 return ICON_FILE_TEXT;
273         else
274                 return ICON_FILE_BLANK;
275 }
276
277 static void file_draw_icon(uiBlock *block, char *path, int sx, int sy, int icon, int width, int height, bool drag)
278 {
279         uiBut *but;
280         int x, y;
281         // float alpha = 1.0f;
282         
283         x = sx;
284         y = sy - height;
285         
286         /*if (icon == ICON_FILE_BLANK) alpha = 0.375f;*/
287
288         but = uiDefIconBut(block, UI_BTYPE_LABEL, 0, icon, x, y, width, height, NULL, 0.0f, 0.0f, 0.0f, 0.0f, "");
289
290         if (drag)
291                 UI_but_drag_set_path(but, path);
292 }
293
294
295 static void file_draw_string(int sx, int sy, const char *string, float width, int height, short align)
296 {
297         uiStyle *style = UI_style_get();
298         uiFontStyle fs = style->widgetlabel;
299         rcti rect;
300         char fname[FILE_MAXFILE];
301
302         fs.align = align;
303
304         BLI_strncpy(fname, string, FILE_MAXFILE);
305         file_shorten_string(fname, width + 1.0f, 0);
306
307         /* no text clipping needed, UI_fontstyle_draw does it but is a bit too strict (for buttons it works) */
308         rect.xmin = sx;
309         rect.xmax = (int)(sx + ceil(width + 4.0f));
310         rect.ymin = sy - height;
311         rect.ymax = sy;
312         
313         UI_fontstyle_draw(&fs, &rect, fname);
314 }
315
316 void file_calc_previews(const bContext *C, ARegion *ar)
317 {
318         SpaceFile *sfile = CTX_wm_space_file(C);
319         View2D *v2d = &ar->v2d;
320         
321         ED_fileselect_init_layout(sfile, ar);
322         UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height);
323 }
324
325 static void file_draw_preview(uiBlock *block, struct direntry *file, int sx, int sy, ImBuf *imb, FileLayout *layout, bool dropshadow, bool drag)
326 {
327         if (imb) {
328                 uiBut *but;
329                 float fx, fy;
330                 float dx, dy;
331                 int xco, yco;
332                 float scaledx, scaledy;
333                 float scale;
334                 int ex, ey;
335                 
336                 if ((imb->x * UI_DPI_FAC > layout->prv_w) ||
337                     (imb->y * UI_DPI_FAC > layout->prv_h))
338                 {
339                         if (imb->x > imb->y) {
340                                 scaledx = (float)layout->prv_w;
341                                 scaledy =  ( (float)imb->y / (float)imb->x) * layout->prv_w;
342                                 scale = scaledx / imb->x;
343                         }
344                         else {
345                                 scaledy = (float)layout->prv_h;
346                                 scaledx =  ( (float)imb->x / (float)imb->y) * layout->prv_h;
347                                 scale = scaledy / imb->y;
348                         }
349                 }
350                 else {
351                         scaledx = (float)imb->x * UI_DPI_FAC;
352                         scaledy = (float)imb->y * UI_DPI_FAC;
353                         scale = UI_DPI_FAC;
354                 }
355
356                 ex = (int)scaledx;
357                 ey = (int)scaledy;
358                 fx = ((float)layout->prv_w - (float)ex) / 2.0f;
359                 fy = ((float)layout->prv_h - (float)ey) / 2.0f;
360                 dx = (fx + 0.5f + layout->prv_border_x);
361                 dy = (fy + 0.5f - layout->prv_border_y);
362                 xco = sx + (int)dx;
363                 yco = sy - layout->prv_h + (int)dy;
364                 
365                 glBlendFunc(GL_SRC_ALPHA,  GL_ONE_MINUS_SRC_ALPHA);
366                 
367                 /* shadow */
368                 if (dropshadow)
369                         UI_draw_box_shadow(220, (float)xco, (float)yco, (float)(xco + ex), (float)(yco + ey));
370
371                 glEnable(GL_BLEND);
372                 
373                 /* the image */
374                 glColor4f(1.0, 1.0, 1.0, 1.0);
375                 glaDrawPixelsTexScaled((float)xco, (float)yco, imb->x, imb->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, imb->rect, scale, scale);
376                 
377                 /* border */
378                 if (dropshadow) {
379                         glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
380                         fdrawbox((float)xco, (float)yco, (float)(xco + ex), (float)(yco + ey));
381                 }
382                 
383                 /* dragregion */
384                 if (drag) {
385                         but = uiDefBut(block, UI_BTYPE_LABEL, 0, "", xco, yco, ex, ey, NULL, 0.0, 0.0, 0, 0, "");
386                         UI_but_drag_set_image(but, file->path, get_file_icon(file), imb, scale);
387                 }
388                 
389                 glDisable(GL_BLEND);
390         }
391 }
392
393 static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
394 {
395         char newname[FILE_MAX + 12];
396         char orgname[FILE_MAX + 12];
397         char filename[FILE_MAX + 12];
398         wmWindowManager *wm = CTX_wm_manager(C);
399         SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C);
400         ARegion *ar = CTX_wm_region(C);
401
402         BLI_make_file_string(G.main->name, orgname, sfile->params->dir, oldname);
403         BLI_strncpy(filename, sfile->params->renameedit, sizeof(filename));
404         BLI_make_file_string(G.main->name, newname, sfile->params->dir, filename);
405
406         if (!STREQ(orgname, newname)) {
407                 if (!BLI_exists(newname)) {
408                         BLI_rename(orgname, newname);
409                         /* to make sure we show what is on disk */
410                         ED_fileselect_clear(wm, sfile);
411                 }
412
413                 ED_region_tag_redraw(ar);
414         }
415 }
416
417
418 static void draw_background(FileLayout *layout, View2D *v2d)
419 {
420         int i;
421         int sy;
422
423         UI_ThemeColorShade(TH_BACK, -7);
424
425         /* alternating flat shade background */
426         for (i = 0; (i <= layout->rows); i += 2) {
427                 sy = (int)v2d->cur.ymax - i * (layout->tile_h + 2 * layout->tile_border_y) - layout->tile_border_y;
428
429                 glRectf(v2d->cur.xmin, (float)sy, v2d->cur.xmax, (float)(sy + layout->tile_h + 2 * layout->tile_border_y));
430                 
431         }
432 }
433
434 static void draw_dividers(FileLayout *layout, View2D *v2d)
435 {
436         const int step = (layout->tile_w + 2 * layout->tile_border_x);
437         int v1[2], v2[2];
438         int sx;
439         unsigned char col_hi[3], col_lo[3];
440
441         UI_GetThemeColorShade3ubv(TH_BACK,  30, col_hi);
442         UI_GetThemeColorShade3ubv(TH_BACK, -30, col_lo);
443
444         v1[1] = v2d->cur.ymax - layout->tile_border_y;
445         v2[1] = v2d->cur.ymin;
446
447         glBegin(GL_LINES);
448
449         /* vertical column dividers */
450         sx = (int)v2d->tot.xmin;
451         while (sx < v2d->cur.xmax) {
452                 sx += step;
453
454                 glColor3ubv(col_lo);
455                 v1[0] = v2[0] = sx;
456                 glVertex2iv(v1);
457                 glVertex2iv(v2);
458
459                 glColor3ubv(col_hi);
460                 v1[0] = v2[0] = sx + 1;
461                 glVertex2iv(v1);
462                 glVertex2iv(v2);
463         }
464
465         glEnd();
466 }
467
468 void file_draw_list(const bContext *C, ARegion *ar)
469 {
470         SpaceFile *sfile = CTX_wm_space_file(C);
471         FileSelectParams *params = ED_fileselect_get_params(sfile);
472         FileLayout *layout = ED_fileselect_get_layout(sfile, ar);
473         View2D *v2d = &ar->v2d;
474         struct FileList *files = sfile->files;
475         struct direntry *file;
476         ImBuf *imb;
477         uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
478         int numfiles;
479         int numfiles_layout;
480         int sx, sy;
481         int offset;
482         int textwidth, textheight;
483         int i;
484         bool is_icon;
485         short align;
486         bool do_drag;
487         int column_space = 0.6f * UI_UNIT_X;
488
489         numfiles = filelist_numfiles(files);
490         
491         if (params->display != FILE_IMGDISPLAY) {
492
493                 draw_background(layout, v2d);
494         
495                 draw_dividers(layout, v2d);
496         }
497
498         offset = ED_fileselect_layout_offset(layout, (int)ar->v2d.cur.xmin, (int)-ar->v2d.cur.ymax);
499         if (offset < 0) offset = 0;
500
501         numfiles_layout = ED_fileselect_layout_numfiles(layout, ar);
502
503         /* adjust, so the next row is already drawn when scrolling */
504         if (layout->flag & FILE_LAYOUT_HOR) {
505                 numfiles_layout += layout->rows;
506         }
507         else {
508                 numfiles_layout += layout->columns;
509         }
510
511         textwidth = (FILE_IMGDISPLAY == params->display) ? layout->tile_w : (int)layout->column_widths[COLUMN_NAME];
512         textheight = (int)(layout->textheight * 3.0 / 2.0 + 0.5);
513
514         align = (FILE_IMGDISPLAY == params->display) ? UI_STYLE_TEXT_CENTER : UI_STYLE_TEXT_LEFT;
515
516         for (i = offset; (i < numfiles) && (i < offset + numfiles_layout); i++) {
517                 ED_fileselect_layout_tilepos(layout, i, &sx, &sy);
518                 sx += (int)(v2d->tot.xmin + 0.1f * UI_UNIT_X);
519                 sy = (int)(v2d->tot.ymax - sy);
520
521                 file = filelist_file(files, i);
522                 
523                 UI_ThemeColor4(TH_TEXT);
524
525
526                 if (!(file->selflag & FILE_SEL_EDITING)) {
527                         if ((params->active_file == i) || (file->selflag & FILE_SEL_HIGHLIGHTED) || (file->selflag & FILE_SEL_SELECTED)) {
528                                 int colorid = (file->selflag & FILE_SEL_SELECTED) ? TH_HILITE : TH_BACK;
529                                 int shade = (params->active_file == i) || (file->selflag & FILE_SEL_HIGHLIGHTED) ? 20 : 0;
530
531                                 /* readonly files (".." and ".") must not be drawn as selected - set color back to normal */
532                                 if (FILENAME_IS_CURRPAR(file->relname)) {
533                                         colorid = TH_BACK;
534                                 }
535                                 draw_tile(sx, sy - 1, layout->tile_w + 4, sfile->layout->tile_h + layout->tile_border_y, colorid, shade);
536                         }
537                 }
538                 UI_draw_roundbox_corner_set(UI_CNR_NONE);
539
540                 /* don't drag parent or refresh items */
541                 do_drag = !(FILENAME_IS_CURRPAR(file->relname));
542
543                 if (FILE_IMGDISPLAY == params->display) {
544                         is_icon = 0;
545                         imb = filelist_getimage(files, i);
546                         if (!imb) {
547                                 imb = filelist_geticon(files, i);
548                                 is_icon = 1;
549                         }
550                         
551                         file_draw_preview(block, file, sx, sy, imb, layout, !is_icon && (file->flags & FILE_TYPE_IMAGE), do_drag);
552                 }
553                 else {
554                         file_draw_icon(block, file->path, sx, sy - (UI_UNIT_Y / 6), get_file_icon(file), ICON_DEFAULT_WIDTH_SCALE, ICON_DEFAULT_HEIGHT_SCALE, do_drag);
555                         sx += ICON_DEFAULT_WIDTH_SCALE + 0.2f * UI_UNIT_X;
556                 }
557
558                 UI_ThemeColor4(TH_TEXT);
559
560                 if (file->selflag & FILE_SEL_EDITING) {
561                         uiBut *but;
562                         short width;
563
564                         if (params->display == FILE_SHORTDISPLAY) {
565                                 width = layout->tile_w - (ICON_DEFAULT_WIDTH_SCALE + 0.2f * UI_UNIT_X);
566                         }
567                         else if (params->display == FILE_LONGDISPLAY) {
568                                 width = layout->column_widths[COLUMN_NAME]  + layout->column_widths[COLUMN_MODE1] +
569                                         layout->column_widths[COLUMN_MODE2] + layout->column_widths[COLUMN_MODE3] +
570                                         (column_space * 3.5f);
571                         }
572                         else {
573                                 BLI_assert(params->display == FILE_IMGDISPLAY);
574                                 width = textwidth;
575                         }
576
577                         but = uiDefBut(block, UI_BTYPE_TEXT, 1, "", sx, sy - layout->tile_h - 0.15f * UI_UNIT_X,
578                                        width, textheight, sfile->params->renameedit, 1.0f, (float)sizeof(sfile->params->renameedit), 0, 0, "");
579                         UI_but_func_rename_set(but, renamebutton_cb, file);
580                         UI_but_flag_enable(but, UI_BUT_NO_UTF8); /* allow non utf8 names */
581                         UI_but_flag_disable(but, UI_BUT_UNDO);
582                         if (false == UI_but_active_only(C, ar, block, but)) {
583                                 file->selflag &= ~FILE_SEL_EDITING;
584                         }
585                 }
586
587                 if (!(file->selflag & FILE_SEL_EDITING)) {
588                         int tpos = (FILE_IMGDISPLAY == params->display) ? sy - layout->tile_h + layout->textheight : sy;
589                         file_draw_string(sx + 1, tpos, file->relname, (float)textwidth, textheight, align);
590                 }
591
592                 if (params->display == FILE_SHORTDISPLAY) {
593                         sx += (int)layout->column_widths[COLUMN_NAME] + column_space;
594                         if ((BLI_is_dir(file->path) == false) && file->size[0]) {
595                                 file_draw_string(sx, sy, file->size, layout->column_widths[COLUMN_SIZE], layout->tile_h, align);
596                                 sx += (int)layout->column_widths[COLUMN_SIZE] + column_space;
597                         }
598                 }
599                 else if (params->display == FILE_LONGDISPLAY) {
600                         sx += (int)layout->column_widths[COLUMN_NAME] + column_space;
601
602 #ifndef WIN32
603                         /* rwx rwx rwx */
604                         file_draw_string(sx, sy, file->mode1, layout->column_widths[COLUMN_MODE1], layout->tile_h, align); 
605                         sx += layout->column_widths[COLUMN_MODE1] + column_space;
606
607                         file_draw_string(sx, sy, file->mode2, layout->column_widths[COLUMN_MODE2], layout->tile_h, align);
608                         sx += layout->column_widths[COLUMN_MODE2] + column_space;
609
610                         file_draw_string(sx, sy, file->mode3, layout->column_widths[COLUMN_MODE3], layout->tile_h, align);
611                         sx += layout->column_widths[COLUMN_MODE3] + column_space;
612
613                         file_draw_string(sx, sy, file->owner, layout->column_widths[COLUMN_OWNER], layout->tile_h, align);
614                         sx += layout->column_widths[COLUMN_OWNER] + column_space;
615 #endif
616
617                         file_draw_string(sx, sy, file->date, layout->column_widths[COLUMN_DATE], layout->tile_h, align);
618                         sx += (int)layout->column_widths[COLUMN_DATE] + column_space;
619
620                         file_draw_string(sx, sy, file->time, layout->column_widths[COLUMN_TIME], layout->tile_h, align);
621                         sx += (int)layout->column_widths[COLUMN_TIME] + column_space;
622
623                         if ((BLI_is_dir(file->path) == false) && file->size[0]) {
624                                 file_draw_string(sx, sy, file->size, layout->column_widths[COLUMN_SIZE], layout->tile_h, align);
625                                 sx += (int)layout->column_widths[COLUMN_SIZE] + column_space;
626                         }
627                 }
628         }
629
630         UI_block_end(C, block);
631         UI_block_draw(C, block);
632
633 }