~ubuntu-branches/ubuntu/gutsy/avscan/gutsy

« back to all changes in this revision

Viewing changes to avscan/fb.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Berg
  • Date: 2007-08-12 14:22:25 UTC
  • mfrom: (1.9.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070812142225-2whp6690lilo2wg8
Tags: 3.2.1-openssl-2
Correctly handle DEB_BUILD_OPTIONS=nostrip (Closes: #436496).

Show diffs side-by-side

added added

removed removed

Lines of Context:
115
115
        const gchar *buf, const gint len
116
116
);
117
117
static gchar *FileBrowserDNDBufFormat(
118
 
        FileBrowserObject **object, const gint total, GList *selection,
119
 
        gint *len
 
118
        GList *objects_list, GList *selection, gint *len_rtn
120
119
);
121
120
static gboolean FileBrowserObjectNameFilter(
122
121
        const gchar *name, const gchar *full_path,
154
153
 
155
154
 
156
155
/* Icons */
 
156
static FileBrowserIcon *FileBrowserIconNew(void);
 
157
static void FileBrowserIconDelete(FileBrowserIcon *icon);
157
158
static FileBrowserIcon *FileBrowserGetIcon(FileBrowser *fb, const gint i);
158
159
static FileBrowserIcon *FileBrowserIconAppend(
159
160
        FileBrowser *fb, guint8 **data, const gchar *desc
164
165
 
165
166
 
166
167
/* Objects */
167
 
static FileBrowserObject *FileBrowserGetObject(FileBrowser *fb, gint i);
 
168
static FileBrowserObject *FileBrowserObjectNew(void);
 
169
static void FileBrowserObjectDelete(FileBrowserObject *o);
 
170
static FileBrowserObject *FileBrowserGetObject(FileBrowser *fb, const gint i);
168
171
static void FileBrowserObjectUpdateValues(
169
172
        FileBrowser *fb, FileBrowserObject *o
170
173
);
192
195
 
193
196
 
194
197
/* List Columns */
195
 
static FileBrowserColumn *FileBrowserListGetColumn(FileBrowser *fb, gint i);
 
198
static FileBrowserColumn *FileBrowserColumnNew(void);
 
199
static void FileBrowserColumnDelete(FileBrowserColumn *column);
 
200
static FileBrowserColumn *FileBrowserListGetColumn(FileBrowser *fb, const gint i);
196
201
static FileBrowserColumn *FileBrowserListColumnAppend(
197
202
        FileBrowser *fb, const gchar *label, const gint width
198
203
);
211
216
/* Callbacks */
212
217
static void FileBrowserLocationsPUListItemDestroyCB(gpointer data);
213
218
static void FileBrowserTypesPUListItemDestroyCB(gpointer data);
214
 
static void FileBrowserIconDestroyCB(gpointer data);
215
 
static void FileBrowserObjectDestroyCB(gpointer data);
216
 
static void FileBrowserColumnDestroyCB(gpointer data);
217
219
 
218
220
static gboolean FileBrowserDragMotionCB(
219
221
        GtkWidget *widget, GdkDragContext *dc, gint x, gint y, guint t,
289
291
gint FileBrowserInit(void);
290
292
void FileBrowserSetStyle(GtkRcStyle *rc_style);
291
293
void FileBrowserSetTransientFor(GtkWidget *w);
 
294
void FileBrowserSetObjectCreatedCB(
 
295
        void (*cb)(
 
296
                const gchar *path,
 
297
                gpointer data
 
298
        ),
 
299
        gpointer data
 
300
);
 
301
void FileBrowserSetObjectModifiedCB(
 
302
        void (*cb)(
 
303
                const gchar *old_path,
 
304
                const gchar *new_path,
 
305
                gpointer data
 
306
        ),
 
307
        gpointer data
 
308
);
 
309
void FileBrowserSetObjectDeletedCB(
 
310
        void (*cb)(
 
311
                const gchar *path,
 
312
                gpointer data
 
313
        ),
 
314
        gpointer data
 
315
);
292
316
gboolean FileBrowserIsQuery(void);
293
317
void FileBrowserBreakQuery(void);
294
318
GtkWidget *FileBrowserGetToplevel(void);
508
532
struct _FileBrowser {
509
533
 
510
534
        GtkWidget       *toplevel;
 
535
        GtkAccelGroup   *accelgrp;
511
536
        gint            busy_count,
512
 
                        freeze_count;
513
 
        GtkAccelGroup   *accelgrp;
514
 
 
 
537
                        freeze_count,
 
538
                        block_loop_level;
 
539
        gboolean        user_response;          /* TRUE if user clicked on OK */
515
540
        GdkCursor       *cur_busy,
516
541
                        *cur_column_hresize,
517
542
                        *cur_translate;
544
569
        pulistbox_struct        *loc_pulistbox,
545
570
                                *types_pulistbox;
546
571
 
 
572
        /* Current Location */
547
573
        gchar           *cur_location;
548
574
 
549
 
        gint            block_loop_level;
550
 
        gboolean        user_response;  /* TRUE if user clicked on OK */
551
 
 
 
575
        /* List Format */
552
576
        FileBrowserListFormat   list_format;
553
577
 
554
 
        FileBrowserColumn       **column;
555
 
        gint                    total_columns;
556
 
 
557
 
        fb_type_struct  cur_type;       /* Current file type */
558
 
        gchar           **selected_path;
559
 
        gint            total_selected_paths;
560
 
 
561
 
        FileBrowserIcon **icon;
562
 
        gint            total_icons;
 
578
        /* Columns */
 
579
        GList           *columns_list;          /* GList of FileBrowserColumn * columns */
 
580
 
 
581
        /* Icons */
 
582
        GList           *icons_list;            /* GList of FileBrowserIcon * icons */
563
583
 
564
584
        gint            uid, euid;
565
585
        gint            gid, egid;
566
586
        gchar           *home_path;
 
587
 
 
588
        /* Devices */
567
589
        GList           *device_paths_list;     /* List of gchar * device paths */
568
590
 
569
 
        gint            focus_object;
 
591
        /* Objects */
 
592
        GList           *objects_list;          /* GList of FileBrowserObject * objects */
 
593
        gint            objects_per_row;        /* For use with
 
594
                                                 * FB_LIST_FORMAT_STANDARD */
570
595
        GList           *selection,
571
596
                        *selection_end;
572
 
        FileBrowserObject       **object;
573
 
        gint            total_objects;
574
 
        gint            objects_per_row;        /* For use with
575
 
                                                 * FB_LIST_FORMAT_STANDARD */
576
 
        gint            last_single_select_object;
 
597
        gint            focus_object,
 
598
                        last_single_select_object;
577
599
        gboolean        show_hidden_objects;
578
600
 
 
601
        /* Current File Type Return */
 
602
        fb_type_struct  cur_type;
 
603
 
 
604
        /* Selected Paths Return */
 
605
        gchar           **selected_path;
 
606
        gint            total_selected_paths;
 
607
 
 
608
        /* Callbacks */
 
609
        void            (*object_created_cb)(
 
610
                const gchar *path,
 
611
                gpointer data
 
612
        );
 
613
        gpointer        object_created_data;
 
614
 
 
615
        void            (*object_modified_cb)(
 
616
                const gchar *old_path,
 
617
                const gchar *new_path,
 
618
                gpointer data
 
619
        );
 
620
        gpointer        object_modified_data;
 
621
 
 
622
        void            (*object_deleted_cb)(
 
623
                const gchar *path,
 
624
                gpointer data
 
625
        );
 
626
        gpointer        object_deleted_data;
 
627
 
579
628
        /* Last button pressed and pointer position */
580
629
        gint            button,
581
630
                        drag_last_x,
647
696
 
648
697
/*
649
698
 *      Generates a DND buffer based on the list of objects that are
650
 
 *      selected based on the given selection.
 
699
 *      selected.
 
700
 *
 
701
 *      The objects_list specifies the GList of FileBrowserObject *
 
702
 *      objects.
 
703
 *
 
704
 *      The selection specifies the GList of gint selections.
 
705
 *
 
706
 *      The len_rtn specifies the return value for the length of the
 
707
 *      buffer.
 
708
 *
 
709
 *      Returns a null deliminator string describing the objects in
 
710
 *      URL format or NULL on error.
651
711
 */
652
712
static gchar *FileBrowserDNDBufFormat(
653
 
        FileBrowserObject **object, const gint total, GList *selection,
654
 
        gint *len
 
713
        GList *objects_list, GList *selection, gint *len_rtn
655
714
)
656
715
{
657
716
        gchar *buf = NULL;
658
 
        gint i, buf_len = 0;
 
717
        gint buf_len = 0;
659
718
        GList *glist;
660
719
        FileBrowserObject *o;
661
720
 
662
 
 
663
721
        /* Iterate through the selection list */
664
722
        for(glist = selection;
665
723
            glist != NULL;
666
724
            glist = g_list_next(glist)
667
725
        )
668
726
        {
669
 
            i = (gint)glist->data;
670
 
            if((i >= 0) && (i < total))
671
 
                o = object[i];
672
 
            else
673
 
                o = NULL;
674
 
            if((o != NULL) ? (o->full_path != NULL) : FALSE)
 
727
            o = FILE_BROWSER_OBJECT(g_list_nth_data(
 
728
                objects_list, (guint)glist->data
 
729
            ));
 
730
            if(o == NULL)
 
731
                continue;
 
732
 
 
733
            if(o->full_path != NULL)
675
734
            {
676
 
                gchar *url = g_strdup_printf(
677
 
                    "file://%s",
678
 
                    o->full_path
 
735
                gchar *url = g_strconcat(
 
736
                    "file://",
 
737
                    o->full_path,
 
738
                    NULL
679
739
                );
680
 
                gint url_len = STRLEN(url);
681
 
                gint last_buf_len = buf_len;
 
740
                const gint      url_len = STRLEN(url),
 
741
                                last_buf_len = buf_len;
682
742
 
683
 
                /* Increase allocation of buffer for this url string
 
743
                /* Increase the buffer allocation for this url string
684
744
                 * which we will append to the buffer (include the
685
745
                 * '\0' character counted in buf_len)
686
746
                 */
701
761
            }
702
762
        }
703
763
 
704
 
        /* Update return value */
705
 
        if(len != NULL)
706
 
            *len = buf_len;
 
764
        if(len_rtn != NULL)
 
765
            *len_rtn = buf_len;
707
766
 
708
767
        return(buf);
709
768
}
1221
1280
                /* No change in location, but check if we still need
1222
1281
                 * to update the lists if the lists were reset/cleared
1223
1282
                 */
1224
 
                if(fb->total_objects > 0)
 
1283
                if(fb->objects_list != NULL)
1225
1284
                {
1226
1285
                    /* Lists were not cleared, so no need to update */
1227
1286
                    g_free(new_location);
1450
1509
            {
1451
1510
                gint buf_len;
1452
1511
                gchar *buf = FileBrowserDNDBufFormat(
1453
 
                    fb->object, fb->total_objects, fb->selection,
1454
 
                    &buf_len
 
1512
                    fb->objects_list, fb->selection, &buf_len
1455
1513
                );
1456
1514
                if(buf != NULL)
1457
1515
                {
1673
1731
            gboolean created = FALSE;
1674
1732
 
1675
1733
            /* Failed to create, try creating it under a different
1676
 
             * name.
 
1734
             * name
1677
1735
             */
1678
1736
            for(i = 2; i < 100; i++)
1679
1737
            {
1731
1789
        if(name != NULL)
1732
1790
        {
1733
1791
            gint i;
1734
 
            const FileBrowserObject *o;
1735
 
            for(i = 0; i < fb->total_objects; i++)
 
1792
            GList *glist;
 
1793
            FileBrowserObject *o;
 
1794
 
 
1795
            for(glist = fb->objects_list, i = 0;
 
1796
                glist != NULL;
 
1797
                glist = g_list_next(glist), i++
 
1798
            )
1736
1799
            {
1737
 
                o = fb->object[i];
1738
 
                if((o != NULL) ? (o->name == NULL) : TRUE)
1739
 
                    continue;
1740
 
 
1741
 
                if(!strcmp(o->name, name))
 
1800
                o = FILE_BROWSER_OBJECT(glist->data);
 
1801
                if(o == NULL)
 
1802
                    continue;
 
1803
 
 
1804
                if(o->name == NULL)
 
1805
                    continue;
 
1806
 
 
1807
                if(!strcmp((const char *)o->name, (const char *)name))
1742
1808
                {
1743
1809
                    /* Select this object */
1744
1810
                    fb->focus_object = i;
1759
1825
        /* Update selected objects on entry */
1760
1826
        FileBrowserEntrySetSelectedObjects(fb);
1761
1827
 
 
1828
        /* Notify about the created directory */
 
1829
        if(fb->object_created_cb != NULL)
 
1830
            fb->object_created_cb(
 
1831
                full_path,
 
1832
                fb->object_created_data
 
1833
            );
 
1834
 
1762
1835
        FileBrowserSetBusy(fb, FALSE);
1763
1836
 
1764
1837
        g_free(name);
1864
1937
        PUListClear(pulist);
1865
1938
 
1866
1939
#define GET_ICON(p)     {               \
1867
 
 if(stat((p), &stat_buf))               \
 
1940
 if(stat((const char *)(p), &stat_buf)) \
1868
1941
  icon = NULL;                          \
1869
1942
 else                                   \
1870
1943
  icon = FileBrowserGetIcon(            \
2074
2147
 
2075
2148
 
2076
2149
/*
 
2150
 *      Creates a new icon.
 
2151
 */
 
2152
static FileBrowserIcon *FileBrowserIconNew(void)
 
2153
{
 
2154
        return(FILE_BROWSER_ICON(g_malloc0(
 
2155
            sizeof(FileBrowserIcon)
 
2156
        )));
 
2157
}
 
2158
 
 
2159
/*
 
2160
 *      Deletes the icon.
 
2161
 */
 
2162
static void FileBrowserIconDelete(FileBrowserIcon *icon)
 
2163
{
 
2164
        if(icon == NULL)
 
2165
            return;
 
2166
 
 
2167
        GDK_PIXMAP_UNREF(icon->pixmap);
 
2168
        GDK_BITMAP_UNREF(icon->mask);
 
2169
        g_free(icon->desc);
 
2170
        g_free(icon);
 
2171
}
 
2172
 
 
2173
/*
2077
2174
 *      Returns the icon at index i or NULL on error.
2078
2175
 */
2079
2176
static FileBrowserIcon *FileBrowserGetIcon(FileBrowser *fb, const gint i)
2081
2178
        if(fb == NULL)
2082
2179
            return(NULL);
2083
2180
 
2084
 
        if((i < 0) || (i >= fb->total_icons))
 
2181
        if(i < 0)
2085
2182
            return(NULL);
2086
 
        else
2087
 
            return(fb->icon[i]);
 
2183
 
 
2184
        return(FILE_BROWSER_ICON(
 
2185
            g_list_nth_data(fb->icons_list, (guint)i)
 
2186
        ));
2088
2187
}
2089
2188
 
2090
2189
/*
2094
2193
        FileBrowser *fb, guint8 **data, const gchar *desc
2095
2194
)
2096
2195
{
2097
 
        gint i;
2098
2196
        FileBrowserIcon *icon;
2099
2197
 
2100
2198
        if((fb == NULL) || (data == NULL))
2101
2199
            return(NULL);
2102
2200
 
2103
 
        i = MAX(fb->total_icons, 0);
2104
 
        fb->total_icons = i + 1;
2105
 
        fb->icon = (FileBrowserIcon **)g_realloc(
2106
 
            fb->icon, fb->total_icons * sizeof(FileBrowserIcon *)
2107
 
        );
2108
 
        if(fb->icon == NULL)
2109
 
        {
2110
 
            fb->total_icons = 0;
 
2201
        /* Create a new icon */
 
2202
        icon = FileBrowserIconNew();
 
2203
        if(icon == NULL)
2111
2204
            return(NULL);
2112
 
        }
2113
 
 
2114
 
        fb->icon[i] = icon = FILE_BROWSER_ICON(g_malloc0(
2115
 
            sizeof(FileBrowserIcon)
2116
 
        ));
2117
 
        if(icon != NULL)
2118
 
        {
2119
 
            icon->pixmap = GDK_PIXMAP_NEW_FROM_XPM_DATA(&icon->mask, data);
2120
 
            gdk_window_get_size(icon->pixmap, &icon->width, &icon->height);
2121
 
            icon->desc = STRDUP(desc);
2122
 
        }
 
2205
 
 
2206
        /* Append it to the list */
 
2207
        fb->icons_list = g_list_append(fb->icons_list, icon);
 
2208
 
 
2209
        /* Set the new icon's values */
 
2210
        icon->pixmap = GDK_PIXMAP_NEW_FROM_XPM_DATA(&icon->mask, data);
 
2211
        gdk_window_get_size(icon->pixmap, &icon->width, &icon->height);
 
2212
        icon->desc = STRDUP(desc);
 
2213
 
2123
2214
        return(icon);
2124
2215
}
2125
2216
 
2311
2402
 
2312
2403
 
2313
2404
/*
 
2405
 *      Creates a new object.
 
2406
 */
 
2407
static FileBrowserObject *FileBrowserObjectNew(void)
 
2408
{
 
2409
        return(FILE_BROWSER_OBJECT(g_malloc0(
 
2410
            sizeof(FileBrowserObject)
 
2411
        )));
 
2412
}
 
2413
 
 
2414
/*
 
2415
 *      Deletes the object.
 
2416
 */
 
2417
static void FileBrowserObjectDelete(FileBrowserObject *o)
 
2418
{
 
2419
        if(o == NULL)
 
2420
            return;
 
2421
 
 
2422
        g_free(o->displayed_name);
 
2423
        g_free(o->full_path);
 
2424
        g_free(o->name);
 
2425
        g_free(o);
 
2426
}
 
2427
 
 
2428
/*
2314
2429
 *      Returns the object at index i or NULL on error.
2315
2430
 */
2316
 
static FileBrowserObject *FileBrowserGetObject(FileBrowser *fb, gint i)
 
2431
static FileBrowserObject *FileBrowserGetObject(FileBrowser *fb, const gint i)
2317
2432
{
2318
2433
        if(fb == NULL)
2319
2434
            return(NULL);
2320
2435
 
2321
 
        if((i < 0) || (i >= fb->total_objects))
 
2436
        if(i < 0)
2322
2437
            return(NULL);
2323
 
        else
2324
 
            return(fb->object[i]);
 
2438
 
 
2439
        return(FILE_BROWSER_OBJECT(
 
2440
            g_list_nth_data(fb->objects_list, (guint)i)
 
2441
        ));
2325
2442
}
2326
2443
 
2327
2444
/*
2363
2480
        /* Set displayed_name from name, abbreviate it as needed */
2364
2481
        if(o->name != NULL)
2365
2482
        {
 
2483
#if 0
 
2484
/* Do not shorten the displayed name anymore */
2366
2485
            const gchar *name = o->name;
2367
2486
            const gint  len = STRLEN(name),
2368
2487
                        max_chars = FB_LIST_ITEM_MAX_CHARS;
2375
2494
                );
2376
2495
            else
2377
2496
                o->displayed_name = STRDUP(name);
 
2497
#endif
 
2498
            g_free(o->displayed_name);
 
2499
            o->displayed_name = STRDUP(o->name);
2378
2500
        }
2379
2501
        else
2380
2502
        {
2439
2561
        struct stat *lstat_buf
2440
2562
)
2441
2563
{
2442
 
        gint i;
2443
2564
        FileBrowserObject *o;
2444
2565
 
2445
2566
        if((fb == NULL) || (full_path == NULL))
2446
2567
            return(NULL);
2447
2568
 
2448
 
        /* Allocate one more pointer for the array */
2449
 
        i = MAX(fb->total_objects, 0);
2450
 
        fb->total_objects = i + 1;
2451
 
        fb->object = (FileBrowserObject **)g_realloc(
2452
 
            fb->object, fb->total_objects * sizeof(FileBrowserObject *)
2453
 
        );
2454
 
        if(fb->object == NULL)
2455
 
        {
2456
 
            fb->total_objects = 0;
 
2569
        /* Create a new object */
 
2570
        o = FileBrowserObjectNew();
 
2571
        if(o == NULL)
2457
2572
            return(NULL);
2458
 
        }
2459
 
 
2460
 
        /* Create a new Object */
2461
 
        fb->object[i] = o = FILE_BROWSER_OBJECT(g_malloc0(
2462
 
            sizeof(FileBrowserObject)
2463
 
        ));
2464
 
        if(o != NULL)
2465
 
        {
2466
 
            o->name = STRDUP(name);
2467
 
            o->full_path = STRDUP(full_path);
2468
 
            if(lstat_buf != NULL)
2469
 
                memcpy(&o->lstat_buf, lstat_buf, sizeof(struct stat));
2470
 
            else
2471
 
                memset(&o->lstat_buf, 0x00, sizeof(struct stat));
2472
 
 
2473
 
            /* Update values */
2474
 
            FileBrowserObjectUpdateValues(fb, o);
2475
 
        }
 
2573
 
 
2574
        /* Append this object to the list */
 
2575
        fb->objects_list = g_list_append(fb->objects_list, o);
 
2576
 
 
2577
        o->name = STRDUP(name);
 
2578
        o->full_path = STRDUP(full_path);
 
2579
        if(lstat_buf != NULL)
 
2580
            memcpy(&o->lstat_buf, lstat_buf, sizeof(struct stat));
 
2581
        else
 
2582
            memset(&o->lstat_buf, 0x00, sizeof(struct stat));
 
2583
 
 
2584
        /* Update values */
 
2585
        FileBrowserObjectUpdateValues(fb, o);
2476
2586
 
2477
2587
        return(o);
2478
2588
}
2515
2625
        g_list_free(fb->selection);
2516
2626
        fb->selection = fb->selection_end = NULL;
2517
2627
 
2518
 
        /* Delete all objects */
2519
 
        for(i = 0; i < fb->total_objects; i++)
2520
 
            FileBrowserObjectDestroyCB(fb->object[i]);
2521
 
        g_free(fb->object);
2522
 
        fb->object = NULL;
2523
 
        fb->total_objects = 0;  
 
2628
        /* Delete all the objects */
 
2629
        if(fb->objects_list != NULL)
 
2630
        {
 
2631
            g_list_foreach(
 
2632
                fb->objects_list, (GFunc)FileBrowserObjectDelete, NULL
 
2633
            );
 
2634
            g_list_free(fb->objects_list);
 
2635
            fb->objects_list = NULL;
 
2636
        }
2524
2637
 
2525
 
        /* Reset objects per row */
 
2638
        /* Reset the number of objects per row */
2526
2639
        fb->objects_per_row = 0;
2527
2640
 
2528
2641
 
2695
2808
                        border_x = border_minor,
2696
2809
                        border_y = border_minor;
2697
2810
        gboolean        need_resize = FALSE;
2698
 
        gint    i, width, height,
2699
 
                total_objects, objects_per_row,
 
2811
        gint    width, height,
 
2812
                objects_per_row,
2700
2813
                cur_x = border_x,
2701
2814
                cur_y = border_y,
2702
2815
                longest_width = 0,
2704
2817
                list_x_max = 0, list_y_max = 0,
2705
2818
                list_x_inc = 0, list_x_page_inc = 0,
2706
2819
                list_y_inc = 0, list_y_page_inc = 0;
 
2820
        GList *glist;
2707
2821
        GdkWindow *window;
2708
2822
        GtkWidget *w;
2709
2823
        FileBrowserListFormat list_format;
2731
2845
        {
2732
2846
          case FB_LIST_FORMAT_VERTICAL_DETAILS:
2733
2847
          case FB_LIST_FORMAT_VERTICAL:
2734
 
            total_objects = fb->total_objects;
2735
 
            for(i = 0; i < total_objects; i++)
 
2848
            for(glist = fb->objects_list;
 
2849
                glist != NULL;
 
2850
                glist = g_list_next(glist)
 
2851
            )
2736
2852
            {
2737
 
                o = fb->object[i];
 
2853
                o = FILE_BROWSER_OBJECT(glist->data);
2738
2854
                if(o == NULL)
2739
2855
                    continue;
2740
2856
 
2747
2863
            }
2748
2864
            break;
2749
2865
          case FB_LIST_FORMAT_STANDARD:
2750
 
            total_objects = fb->total_objects;
2751
2866
            objects_per_row = 0;
2752
 
            for(i = 0; i < total_objects; i++)
 
2867
            for(glist = fb->objects_list;
 
2868
                glist != NULL;
 
2869
                glist = g_list_next(glist)
 
2870
            )
2753
2871
            {
2754
 
                o = fb->object[i];
 
2872
                o = FILE_BROWSER_OBJECT(glist->data);
2755
2873
                if(o == NULL)
2756
2874
                    continue;
2757
2875
 
3108
3226
        FileBrowser *fb, const gint x, const gint y
3109
3227
)
3110
3228
{
3111
 
        gint scroll_x = 0, scroll_y = 0;
 
3229
        gint i, cx, cy, scroll_x = 0, scroll_y = 0;
 
3230
        GList *glist;
 
3231
        FileBrowserObject *o;
3112
3232
 
3113
3233
        if(fb == NULL)
3114
3234
            return(-1);
3130
3250
        /* Find object by list display format */
3131
3251
        switch(fb->list_format)
3132
3252
        {
3133
 
            gint i, cx, cy;
3134
 
            FileBrowserObject *o;
3135
 
 
3136
3253
          case FB_LIST_FORMAT_VERTICAL_DETAILS:
3137
3254
          case FB_LIST_FORMAT_VERTICAL:
3138
 
            for(i = 0; i < fb->total_objects; i++)
 
3255
            for(glist = fb->objects_list, i = 0;
 
3256
                glist != NULL;
 
3257
                glist = g_list_next(glist), i++
 
3258
            )
3139
3259
            {
3140
 
                o = fb->object[i];
 
3260
                o = FILE_BROWSER_OBJECT(glist->data);
3141
3261
                if(o == NULL)
3142
3262
                    continue;
3143
3263
 
3157
3277
            break;
3158
3278
 
3159
3279
          case FB_LIST_FORMAT_STANDARD:
3160
 
            for(i = 0; i < fb->total_objects; i++)
 
3280
            for(glist = fb->objects_list, i = 0;
 
3281
                glist != NULL;
 
3282
                glist = g_list_next(glist), i++
 
3283
            )
3161
3284
            {
3162
 
                o = fb->object[i];
 
3285
                o = FILE_BROWSER_OBJECT(glist->data);
3163
3286
                if(o == NULL)
3164
3287
                    continue;
3165
3288
 
3248
3371
#endif
3249
3372
 
3250
3373
 
3251
 
        /* Draw frame around entire header */
 
3374
        /* Draw the frame around entire header */
3252
3375
        gtk_draw_box(
3253
3376
            style, drawable, state,
3254
3377
            GTK_SHADOW_OUT,
3256
3379
        );
3257
3380
 
3258
3381
        /* Any column headings to draw? */
3259
 
        if(fb->total_columns > 0)
 
3382
        if(fb->columns_list != NULL)
3260
3383
        {
3261
 
            gint i, last_column_position = 0;
 
3384
            gint last_column_position = 0;
 
3385
            GList *glist;
3262
3386
            GdkRectangle rect;
 
3387
            GdkGC *gc_text;
3263
3388
            FileBrowserColumn *column;
3264
 
            GdkGC *gc_text;
3265
3389
 
3266
3390
            /* Draw each column heading */
3267
 
            for(i = 0; i < fb->total_columns; i++)
 
3391
            for(glist = fb->columns_list;
 
3392
                glist != NULL;
 
3393
                glist = g_list_next(glist)
 
3394
            )
3268
3395
            {
3269
 
                column = fb->column[i];
 
3396
                column = FILE_BROWSER_COLUMN(glist->data);
3270
3397
                if(column == NULL)
3271
3398
                    continue;
3272
3399
 
3275
3402
                rect.width = MAX(column->position - last_column_position, 0);
3276
3403
                rect.height = height;
3277
3404
 
 
3405
                if(rect.width == 0)
 
3406
                    continue;
 
3407
 
3278
3408
                gtk_draw_box(
3279
 
                    style, drawable, state,
3280
 
                    GTK_SHADOW_OUT,
 
3409
                    style, drawable,
 
3410
                    (column->flags & GTK_HAS_FOCUS) ?
 
3411
                        GTK_STATE_ACTIVE : state,
 
3412
                    (column->flags & GTK_HAS_FOCUS) ?
 
3413
                        GTK_SHADOW_IN : GTK_SHADOW_OUT,
3281
3414
                    rect.x, rect.y, rect.width, rect.height
3282
3415
                );
3283
3416
 
3327
3460
                    gdk_gc_set_clip_rectangle(gc_text, NULL);
3328
3461
                }
3329
3462
 
3330
 
                if((column->flags & GTK_SENSITIVE) &&
3331
 
                   (column->flags & GTK_HAS_FOCUS) &&
3332
 
                   GTK_WIDGET_HAS_FOCUS(w) &&
3333
 
                   GTK_WIDGET_SENSITIVE(w)
3334
 
                )
3335
 
                    gdk_draw_rectangle(
3336
 
                        drawable, style->fg_gc[state], FALSE,
3337
 
                        rect.x, rect.y, rect.width - 1, rect.height - 1
3338
 
                    );
3339
 
 
3340
3463
                last_column_position = column->position;
3341
3464
            }
3342
3465
        }
3434
3557
        switch(fb->list_format)
3435
3558
        {
3436
3559
            gboolean o_is_selected;
3437
 
            GdkTextBounds b;
3438
3560
            gint i, x, y, icon_width;
 
3561
            GList *glist;
 
3562
            GdkTextBounds b;
3439
3563
            GdkGC *gc_text;
3440
 
            const FileBrowserObject *o;
3441
 
            const FileBrowserIcon *icon;
 
3564
            FileBrowserObject *o;
 
3565
            FileBrowserIcon *icon;
3442
3566
 
3443
3567
          case FB_LIST_FORMAT_VERTICAL_DETAILS:
3444
3568
            /* Make sure we have enough columns to draw for this
3445
3569
             * list display format
3446
3570
             */
3447
 
            if(fb->total_columns >= 4)
 
3571
            if(g_list_length(fb->columns_list) >= 4)
3448
3572
            {
3449
3573
                mode_t m;
3450
3574
                const struct stat *lstat_buf;
3451
3575
                GdkRectangle rect;
3452
 
                const FileBrowserColumn *column[4];
 
3576
                FileBrowserColumn *column[4];
3453
3577
 
3454
3578
                /* Get the pointers to each column */
3455
 
                for(i = 0; i < 4; i++)
3456
 
                    column[i] = fb->column[i];
 
3579
                for(glist = fb->columns_list, i = 0;
 
3580
                    (glist != NULL) && (i < 4);
 
3581
                    glist = g_list_next(glist), i++
 
3582
                )
 
3583
                    column[i] = FILE_BROWSER_COLUMN(glist->data);
3457
3584
 
3458
3585
                /* Draw each object */
3459
 
                for(i = 0; i < fb->total_objects; i++)
 
3586
                for(glist = fb->objects_list, i = 0;
 
3587
                    glist != NULL;
 
3588
                    glist = g_list_next(glist), i++
 
3589
                )
3460
3590
                {
3461
 
                    o = fb->object[i];
 
3591
                    o = FILE_BROWSER_OBJECT(glist->data);
3462
3592
                    if(o == NULL)
3463
3593
                        continue;
3464
3594
 
3493
3623
                         */
3494
3624
                        gc = style->fg_gc[GTK_STATE_SELECTED];
3495
3625
                        gc_text = style->text_gc[GTK_STATE_SELECTED];
3496
 
                        gdk_draw_rectangle(
3497
 
                            drawable, style->bg_gc[GTK_STATE_SELECTED], TRUE,
3498
 
                            rect.x, rect.y, rect.width, rect.height
3499
 
                        );
 
3626
                        if(rect.width > 0)
 
3627
                            gdk_draw_rectangle(
 
3628
                                drawable, style->bg_gc[GTK_STATE_SELECTED], TRUE,
 
3629
                                rect.x, rect.y, rect.width, rect.height
 
3630
                            );
3500
3631
                    }
3501
3632
                    else
3502
3633
                    {
3507
3638
                        gc_text = style->text_gc[state];
3508
3639
                    }
3509
3640
 
 
3641
                    /* Set up the clip rectangle for drawing of the
 
3642
                     * object's name cell
 
3643
                     */
 
3644
                    gdk_gc_set_clip_origin(gc, 0, 0);
 
3645
                    gdk_gc_set_clip_rectangle(gc, &rect);
 
3646
 
3510
3647
                    /* Draw the icon */
3511
3648
                    icon = FileBrowserGetIcon(fb, o->icon_num);
3512
3649
                    if((icon != NULL) ? (icon->pixmap != NULL) : FALSE)
3527
3664
                        icon_width = 0;
3528
3665
                    }
3529
3666
 
3530
 
                    /* Set up the clip rectangle for drawing of the
3531
 
                     * object's name cell
3532
 
                     */
3533
 
                    gdk_gc_set_clip_origin(gc, 0, 0);
3534
 
                    gdk_gc_set_clip_rectangle(gc, &rect);
3535
3667
                    gdk_gc_set_clip_origin(gc_text, 0, 0);
3536
3668
                    gdk_gc_set_clip_rectangle(gc_text, &rect);
3537
3669
 
3577
3709
                        g_snprintf(
3578
3710
                            s, sizeof(s),
3579
3711
                            "%ld",
3580
 
                            lstat_buf->st_size
 
3712
                            (gulong)lstat_buf->st_size
3581
3713
                        );
3582
3714
                        gdk_string_bounds(font, s, &b);
3583
3715
                        rect.x = column[0]->position;
3584
3716
                        rect.width = column[1]->position - column[0]->position;
3585
3717
                        if(rect.width > 0)
 
3718
                        {
3586
3719
                            gdk_gc_set_clip_rectangle(gc_text, &rect);
3587
 
                        gdk_draw_string(
3588
 
                            drawable, font, gc_text,
3589
 
                            (rect.x + rect.width - b.width - 2) -
3590
 
                                b.lbearing,
3591
 
                            (y + (o->height / 2) -
3592
 
                                ((font->ascent + font->descent) / 2)) +
3593
 
                                font->ascent,
3594
 
                            s
3595
 
                        );
 
3720
                            gdk_draw_string(
 
3721
                                drawable, font, gc_text,
 
3722
                                (rect.x + rect.width - b.width - 2) -
 
3723
                                    b.lbearing,
 
3724
                                (y + (o->height / 2) -
 
3725
                                    ((font->ascent + font->descent) / 2)) +
 
3726
                                    font->ascent,
 
3727
                                s
 
3728
                            );
 
3729
                        }
3596
3730
                    }
3597
3731
 
3598
3732
                    /* Draw the permissions */
3627
3761
                        rect.x = column[1]->position;
3628
3762
                        rect.width = column[2]->position - column[1]->position;
3629
3763
                        if(rect.width > 0)
 
3764
                        {
3630
3765
                            gdk_gc_set_clip_rectangle(gc_text, &rect);
3631
 
                        gdk_draw_string(
3632
 
                            drawable, font, gc_text,
3633
 
                            (rect.x + 2) - b.lbearing,
3634
 
                            (y + (o->height / 2) -
3635
 
                                ((font->ascent + font->descent) / 2)) +
3636
 
                                font->ascent,
3637
 
                            s
3638
 
                        );
 
3766
                            gdk_draw_string(
 
3767
                                drawable, font, gc_text,
 
3768
                                (rect.x + 2) - b.lbearing,
 
3769
                                (y + (o->height / 2) -
 
3770
                                    ((font->ascent + font->descent) / 2)) +
 
3771
                                    font->ascent,
 
3772
                                s
 
3773
                            );
 
3774
                        }
3639
3775
                    }
3640
3776
 
3641
3777
                    /* Draw the modified time */
3652
3788
                        rect.x = column[2]->position;
3653
3789
                        rect.width = column[3]->position - column[2]->position;
3654
3790
                        if(rect.width > 0)
 
3791
                        {
3655
3792
                            gdk_gc_set_clip_rectangle(gc_text, &rect);
3656
 
                        gdk_draw_string(
3657
 
                            drawable, font, gc_text,
3658
 
                            (rect.x + 2) - b.lbearing,
3659
 
                            (y + (o->height / 2) -
3660
 
                                ((font->ascent + font->descent) / 2)) +
3661
 
                                font->ascent,
3662
 
                            s
3663
 
                        );
 
3793
                            gdk_draw_string(
 
3794
                                drawable, font, gc_text,
 
3795
                                (rect.x + 2) - b.lbearing,
 
3796
                                (y + (o->height / 2) -
 
3797
                                    ((font->ascent + font->descent) / 2)) +
 
3798
                                    font->ascent,
 
3799
                                s
 
3800
                            );
 
3801
                        }
3664
3802
                        g_free(s);
3665
3803
                    }
3666
3804
 
3688
3826
            break;
3689
3827
 
3690
3828
          case FB_LIST_FORMAT_VERTICAL:
3691
 
            for(i = 0; i < fb->total_objects; i++)
 
3829
            for(glist = fb->objects_list, i = 0;
 
3830
                glist != NULL;
 
3831
                glist = g_list_next(glist), i++
 
3832
            )
3692
3833
            {
3693
 
                o = fb->object[i];
 
3834
                o = FILE_BROWSER_OBJECT(glist->data);
3694
3835
                if(o == NULL)
3695
3836
                    continue;
3696
3837
 
3776
3917
 
3777
3918
          case FB_LIST_FORMAT_STANDARD:
3778
3919
            /* Draw each object */
3779
 
            for(i = 0; i < fb->total_objects; i++)
 
3920
            for(glist = fb->objects_list, i = 0;
 
3921
                glist != NULL;
 
3922
                glist = g_list_next(glist), i++
 
3923
            )
3780
3924
            {
3781
 
                o = fb->object[i];
 
3925
                o = FILE_BROWSER_OBJECT(glist->data);
3782
3926
                if(o == NULL)
3783
3927
                    continue;
3784
3928
 
3899
4043
 
3900
4044
 
3901
4045
/*
 
4046
 *      Creates a new list column.
 
4047
 */
 
4048
static FileBrowserColumn *FileBrowserColumnNew(void)
 
4049
{
 
4050
        return(FILE_BROWSER_COLUMN(g_malloc0(
 
4051
            sizeof(FileBrowserColumn)
 
4052
        )));
 
4053
}
 
4054
 
 
4055
/*
 
4056
 *      Deletes the list column.
 
4057
 */
 
4058
static void FileBrowserColumnDelete(FileBrowserColumn *column)
 
4059
{
 
4060
        if(column == NULL)
 
4061
            return;
 
4062
 
 
4063
        g_free(column->label);
 
4064
        g_free(column);
 
4065
}
 
4066
 
 
4067
/*
3902
4068
 *      Returns the list column at index i.
3903
4069
 */
3904
 
static FileBrowserColumn *FileBrowserListGetColumn(FileBrowser *fb, gint i)
 
4070
static FileBrowserColumn *FileBrowserListGetColumn(FileBrowser *fb, const gint i)
3905
4071
{
3906
4072
        if(fb == NULL)
3907
4073
            return(NULL);
3908
 
        if((i < 0) || (i >= fb->total_columns))
 
4074
 
 
4075
        if(i < 0)
3909
4076
            return(NULL);
3910
 
        else
3911
 
            return(fb->column[i]);
 
4077
 
 
4078
        return(FILE_BROWSER_COLUMN(
 
4079
            g_list_nth_data(fb->columns_list, (guint)i)
 
4080
        ));
3912
4081
}
3913
4082
 
3914
4083
/*
3918
4087
        FileBrowser *fb, const gchar *label, const gint width
3919
4088
)
3920
4089
{
3921
 
        gint i;
 
4090
        gint ncolumns;
3922
4091
        FileBrowserColumn *column, *column_prev;
3923
4092
 
3924
4093
        if(fb == NULL)
3925
4094
            return(NULL);
3926
4095
 
3927
 
        i = fb->total_columns;
3928
 
        fb->total_columns = i + 1;
3929
 
        fb->column = (FileBrowserColumn **)g_realloc(
3930
 
            fb->column, fb->total_columns * sizeof(FileBrowserColumn *)
3931
 
        );
3932
 
        if(fb->column == NULL)
3933
 
        {
3934
 
            fb->total_columns = 0;
3935
 
            return(NULL);
3936
 
        }
3937
 
 
3938
 
        fb->column[i] = column = FILE_BROWSER_COLUMN(g_malloc0(
3939
 
            sizeof(FileBrowserColumn)
3940
 
        ));
 
4096
        /* Create a new list column */
 
4097
        column = FileBrowserColumnNew();
3941
4098
        if(column == NULL)
3942
4099
            return(NULL);
3943
4100
 
 
4101
        fb->columns_list = g_list_append(fb->columns_list, column);
 
4102
        ncolumns = g_list_length(fb->columns_list);
 
4103
 
3944
4104
        column->label = STRDUP(label);
3945
 
        column_prev = FileBrowserListGetColumn(fb, i - 1);
3946
 
        column->position = ((column_prev != NULL) ?
3947
 
            column_prev->position : 0) + width;
 
4105
        column_prev = FileBrowserListGetColumn(fb, ncolumns - 2);
 
4106
        if(column_prev != NULL)
 
4107
            column->position = column_prev->position + width;
 
4108
        else
 
4109
            column->position = width;
3948
4110
        column->label_justify = GTK_JUSTIFY_LEFT;
3949
4111
        column->flags = GTK_SENSITIVE | GTK_CAN_FOCUS |
3950
4112
                        GTK_CAN_DEFAULT;
3957
4119
}
3958
4120
 
3959
4121
/*
3960
 
 *      Deletes all list columns.
 
4122
 *      Deletes all the list columns.
3961
4123
 */
3962
4124
static void FileBrowserListColumnsClear(FileBrowser *fb)
3963
4125
{
3964
 
        gint i;
3965
 
 
3966
4126
        if(fb == NULL)
3967
4127
            return;
3968
4128
 
3969
 
        for(i = 0; i < fb->total_columns; i++)
3970
 
            FileBrowserColumnDestroyCB(fb->column[i]);
3971
 
        g_free(fb->column);
3972
 
        fb->column = NULL;
3973
 
        fb->total_columns = 0;
 
4129
        if(fb->columns_list != NULL)
 
4130
        {
 
4131
            g_list_foreach(
 
4132
                fb->columns_list, (GFunc)FileBrowserColumnDelete, NULL
 
4133
            );
 
4134
            g_list_free(fb->columns_list);
 
4135
            fb->columns_list = NULL;
 
4136
        }
3974
4137
}
3975
4138
 
3976
4139
 
4125
4288
}
4126
4289
 
4127
4290
/*
4128
 
 *      File browser icon destroy callback.
4129
 
 */
4130
 
static void FileBrowserIconDestroyCB(gpointer data)
4131
 
{
4132
 
        FileBrowserIcon *icon = FILE_BROWSER_ICON(data);
4133
 
        if(icon == NULL)
4134
 
            return;
4135
 
 
4136
 
        GDK_PIXMAP_UNREF(icon->pixmap);
4137
 
        GDK_BITMAP_UNREF(icon->mask);
4138
 
        g_free(icon->desc);
4139
 
        g_free(icon);
4140
 
}
4141
 
 
4142
 
/*
4143
 
 *      File browser object destroy callback.
4144
 
 */
4145
 
static void FileBrowserObjectDestroyCB(gpointer data)
4146
 
{
4147
 
        FileBrowserObject *o = FILE_BROWSER_OBJECT(data);
4148
 
        if(o == NULL)
4149
 
            return;
4150
 
 
4151
 
        g_free(o->displayed_name);
4152
 
        g_free(o->full_path);
4153
 
        g_free(o->name);
4154
 
        g_free(o);
4155
 
}
4156
 
 
4157
 
/*
4158
 
 *      File browser list column destroy callback.
4159
 
 */
4160
 
static void FileBrowserColumnDestroyCB(gpointer data)
4161
 
{
4162
 
        FileBrowserColumn *column = FILE_BROWSER_COLUMN(data);
4163
 
        if(column == NULL)
4164
 
            return;
4165
 
 
4166
 
        g_free(column->label);
4167
 
        g_free(column);
4168
 
}
4169
 
 
4170
 
/*
4171
4291
 *      File browser ok button signal callback.
4172
4292
 */
4173
4293
static void FileBrowserOKCB(GtkWidget *widget, gpointer data)
4478
4598
            button = (GdkEventButton *)event;
4479
4599
            if(!GTK_WIDGET_HAS_FOCUS(w))
4480
4600
                gtk_widget_grab_focus(w);
4481
 
            if(fb->total_columns > 0)
 
4601
            if(fb->columns_list != NULL)
4482
4602
            {
4483
 
                gint i, cp, tolor = 3;
 
4603
                gint cp, tolor = 3;
4484
4604
                gint p = (gint)button->x;
4485
 
                FileBrowserColumn *column;
4486
 
 
4487
 
#define COLUMN_POSITION(p)      (((p) != NULL) ? (p)->position : 0)
4488
 
 
4489
 
                /* Iterate through all columns to update focus and
4490
 
                 * reset drag state.
4491
 
                 */
4492
 
                for(i = 0; i < fb->total_columns; i++)
4493
 
                {
4494
 
                    column = fb->column[i];
4495
 
                    if(column == NULL)
4496
 
                        continue;
4497
 
 
4498
 
                    /* Get left edge column position */
4499
 
                    cp = ((i - 1) >= 0) ?
4500
 
                        COLUMN_POSITION(fb->column[i - 1]) : 0;
4501
 
 
4502
 
                    if((p >= (cp + tolor)) && (p < (column->position - tolor)))
4503
 
                        column->flags |= GTK_HAS_FOCUS;
4504
 
                    else
4505
 
                        column->flags &= ~GTK_HAS_FOCUS;
4506
 
 
4507
 
                    column->drag = FALSE;
4508
 
                }
4509
 
                FileBrowserListHeaderQueueDraw(fb);
4510
 
 
4511
 
                /* Iterate through all columns, checking for one
4512
 
                 * where the pointer is over its resizing area.
4513
 
                 */
4514
 
                for(i = fb->total_columns - 1; i >= 0; i--)
4515
 
                {
4516
 
                    column = fb->column[i];
 
4605
                GList *glist;
 
4606
                FileBrowserColumn *column, *prev_column;
 
4607
 
 
4608
                /* Iterate through the list of columns, checking a
 
4609
                 * column that the pointer is over its resizing
 
4610
                 * area
 
4611
                 */
 
4612
                for(glist = g_list_last(fb->columns_list);
 
4613
                    glist != NULL;
 
4614
                    glist = g_list_previous(glist)
 
4615
                )
 
4616
                {
 
4617
                    column = FILE_BROWSER_COLUMN(glist->data);
4517
4618
                    if(column == NULL)
4518
4619
                        continue;
4519
4620
 
4532
4633
                        break;
4533
4634
                    }
4534
4635
                }
4535
 
#undef COLUMN_POSITION
 
4636
                /* No column was clicked on its resizing area? */
 
4637
                if(glist == NULL)
 
4638
                {
 
4639
                    /* Iterate through all columns to update the focus
 
4640
                     * and reset the drag state
 
4641
                     */
 
4642
                    prev_column = NULL;
 
4643
                    for(glist = fb->columns_list;
 
4644
                        glist != NULL;
 
4645
                        glist = g_list_next(glist)
 
4646
                    )
 
4647
                    {
 
4648
                        column = FILE_BROWSER_COLUMN(glist->data);
 
4649
                        if(column == NULL)
 
4650
                            continue;
 
4651
 
 
4652
                        /* Get the left edge column position */
 
4653
                        cp = (prev_column != NULL) ? prev_column->position : 0;
 
4654
 
 
4655
                        /* Clicked on this column? */
 
4656
                        if((p >= (cp + tolor)) && (p < (column->position - tolor)))
 
4657
                        {
 
4658
                            /* Invert the focus */
 
4659
                            if(column->flags & GTK_HAS_FOCUS)
 
4660
                                column->flags &= ~GTK_HAS_FOCUS;
 
4661
                            else
 
4662
                                column->flags |= GTK_HAS_FOCUS;
 
4663
                        }
 
4664
                        else
 
4665
                        {
 
4666
                            column->flags &= ~GTK_HAS_FOCUS;
 
4667
                        }
 
4668
 
 
4669
                        column->drag = FALSE;
 
4670
 
 
4671
                        prev_column = column;
 
4672
                    }
 
4673
                }
 
4674
                FileBrowserListHeaderQueueDraw(fb);
4536
4675
            }
4537
4676
            status = TRUE;
4538
4677
            break;
4539
4678
 
4540
4679
          case GDK_BUTTON_RELEASE:
4541
4680
            button = (GdkEventButton *)event;
4542
 
            if(fb->total_columns > 0)
 
4681
            if(fb->columns_list != NULL)
4543
4682
            {
4544
 
                gint i, pos_shift_delta = 0;
 
4683
                gint pos_shift_delta = 0;
 
4684
                GList *glist;
4545
4685
                FileBrowserColumn *column;
4546
4686
 
4547
 
                /* Iterate through all columns, checking for one that
4548
 
                 * is being dragged and set that new column's
 
4687
                /* Iterate through the columns list, checking for one
 
4688
                 * that is being dragged and set that column's new
4549
4689
                 * position
4550
4690
                 */
4551
 
                for(i = 0; i < fb->total_columns; i++)
 
4691
                for(glist = fb->columns_list;
 
4692
                    glist != NULL;
 
4693
                    glist = g_list_next(glist)
 
4694
                )
4552
4695
                {
4553
 
                    column = fb->column[i];
 
4696
                    column = FILE_BROWSER_COLUMN(glist->data);
4554
4697
                    if(column == NULL)
4555
4698
                        continue;
4556
4699
 
4577
4720
 
4578
4721
          case GDK_MOTION_NOTIFY:
4579
4722
            motion = (GdkEventMotion *)event;
4580
 
            if(fb->total_columns > 0)
 
4723
            if(fb->columns_list != NULL)
4581
4724
            {
4582
 
                gint i, tolor = 3, left_column_pos = 0;
 
4725
                gint tolor = 3, left_column_pos = 0;
 
4726
                gint p = (gint)motion->x;
 
4727
                GList *glist;
4583
4728
                GdkCursor *cursor = NULL;
4584
 
                gint p = (gint)motion->x;
4585
4729
                FileBrowserColumn *column;
4586
4730
 
4587
4731
 
4591
4735
                 * moved into the dragging area of a column then
4592
4736
                 * the new cursor will be specified.
4593
4737
                 */
4594
 
                for(i = 0; i < fb->total_columns; i++)
 
4738
                for(glist = fb->columns_list;
 
4739
                    glist != NULL;
 
4740
                    glist = g_list_next(glist)
 
4741
                )
4595
4742
                {
4596
 
                    column = fb->column[i];
 
4743
                    column = FILE_BROWSER_COLUMN(glist->data);
4597
4744
                    if(column == NULL)
4598
4745
                        continue;
4599
4746
 
4625
4772
                         * pointer has moved into the dragging
4626
4773
                         * area of this column.
4627
4774
                         */
4628
 
                        gint cp = column->position;
 
4775
                        const gint cp = column->position;
4629
4776
                        if((p >= (cp - tolor)) && (p < (cp + (2 * tolor))))
4630
 
                        {
4631
4777
                            cursor = fb->cur_column_hresize;
4632
 
                        }
4633
4778
 
4634
4779
                        left_column_pos = column->position;
4635
4780
                    }
4766
4911
 
4767
4912
                            /* Select? */
4768
4913
                            if((key->state & GDK_SHIFT_MASK) &&
4769
 
                               (fb->total_objects > 0)
 
4914
                               (fb->objects_list != NULL)
4770
4915
                            )
4771
4916
                            {
4772
4917
                                if(!OBJISSEL(fb, n))
4801
4946
                    if(key_press)
4802
4947
                    {
4803
4948
                        /* Scroll only? */
 
4949
                        const gint nobjs = g_list_length(fb->objects_list);
4804
4950
                        if(key->state & GDK_CONTROL_MASK)
4805
4951
                        {
4806
4952
                            GtkRange *range = (GtkRange *)fb->list_vsb;
4815
4961
                                    )
4816
4962
                                );
4817
4963
                        }
4818
 
                        else if(fb->focus_object < (fb->total_objects - 1))
 
4964
                        else if(fb->focus_object < (nobjs - 1))
4819
4965
                        {
4820
4966
                            gint        n = fb->focus_object,
4821
4967
                                        i = n + 1;
4824
4970
 
4825
4971
                            /* Select? */
4826
4972
                            if((key->state & GDK_SHIFT_MASK) &&
4827
 
                               (fb->total_objects > 0)
 
4973
                               (nobjs > 0)
4828
4974
                            )
4829
4975
                            {
4830
4976
                                if(!OBJISSEL(fb, n))
4857
5003
                    if(key_press)
4858
5004
                    {
4859
5005
                        /* Scroll only? */
 
5006
                        const gint nobjs = g_list_length(fb->objects_list);
4860
5007
                        if(key->state & GDK_CONTROL_MASK)
4861
5008
                        {
4862
5009
                            GtkRange *range = (GtkRange *)fb->list_vsb;
4873
5020
                        }
4874
5021
                        else
4875
5022
                        {
4876
 
                            const FileBrowserObject *o = (fb->total_objects > 0) ?
4877
 
                                fb->object[0] : NULL;
 
5023
                            FileBrowserObject *o = FILE_BROWSER_OBJECT(
 
5024
                                g_list_nth_data(fb->objects_list, 0)
 
5025
                            );
4878
5026
                            gint i, n = fb->focus_object,
4879
5027
                                row_height = (o != NULL) ?
4880
5028
                                    (o->height + 1) : 0;
4892
5040
 
4893
5041
                                /* Select? */
4894
5042
                                if((key->state & GDK_SHIFT_MASK) &&
4895
 
                                   (fb->total_objects > 0)
 
5043
                                   (nobjs > 0)
4896
5044
                                )
4897
5045
                                {
4898
5046
                                    gint j;
4899
 
                                    for(j = MIN(n, fb->total_objects - 1); j >= i; j--)
 
5047
                                    for(j = MIN(n, nobjs - 1); j >= i; j--)
4900
5048
                                    {
4901
5049
                                        if(!OBJISSEL(fb, j))
4902
5050
                                            fb->selection = g_list_append(
4925
5073
                    if(key_press)
4926
5074
                    {
4927
5075
                        /* Scroll only? */
 
5076
                        const gint nobjs = g_list_length(fb->objects_list);
4928
5077
                        if(key->state & GDK_CONTROL_MASK)
4929
5078
                        {
4930
5079
                            GtkRange *range = (GtkRange *)fb->list_vsb;
4941
5090
                        }
4942
5091
                        else
4943
5092
                        {
4944
 
                            const FileBrowserObject *o = (fb->total_objects > 0) ?
4945
 
                                fb->object[0] : NULL;
 
5093
                            FileBrowserObject *o = FILE_BROWSER_OBJECT(
 
5094
                                g_list_nth_data(fb->objects_list, 0)
 
5095
                            );
4946
5096
                            gint i, n = fb->focus_object,
4947
5097
                                row_height = (o != NULL) ?
4948
5098
                                    (o->height + 1) : 0;
4954
5104
                            {
4955
5105
                                fb->focus_object = i = MIN(
4956
5106
                                    fb->focus_object +
4957
 
                                    (gint)(adj->page_increment / row_height),
4958
 
                                    fb->total_objects - 1
 
5107
                                        (gint)(adj->page_increment / row_height),
 
5108
                                    (nobjs - 1)
4959
5109
                                );
4960
5110
 
4961
5111
                                /* Select? */
4962
5112
                                if((key->state & GDK_SHIFT_MASK) &&
4963
 
                                   (fb->total_objects > 0)
 
5113
                                   (nobjs > 0)
4964
5114
                                )
4965
5115
                                {
4966
5116
                                    gint j;
5006
5156
                        }
5007
5157
                        else if(fb->focus_object > 0)
5008
5158
                        {
 
5159
                            const gint nobjs = g_list_length(fb->objects_list);
5009
5160
                            gint        i = 0,
5010
5161
                                        n = fb->focus_object;
5011
5162
 
5013
5164
 
5014
5165
                            /* Select? */
5015
5166
                            if((key->state & GDK_SHIFT_MASK) &&
5016
 
                               (fb->total_objects > 0)
 
5167
                               (nobjs > 0)
5017
5168
                            )
5018
5169
                            {
5019
5170
                                gint j;
5020
 
                                for(j = MIN(n, fb->total_objects - 1); j >= i; j--)
 
5171
                                for(j = MIN(n, (nobjs - 1)); j >= i; j--)
5021
5172
                                {
5022
5173
                                    if(!OBJISSEL(fb, j))
5023
5174
                                        fb->selection = g_list_append(
5045
5196
                    if(key_press)
5046
5197
                    {
5047
5198
                        /* Scroll only? */
 
5199
                        const gint nobjs = g_list_length(fb->objects_list);
5048
5200
                        if(key->state & GDK_CONTROL_MASK)
5049
5201
                        {
5050
5202
                            GtkRange *range = (GtkRange *)fb->list_vsb;
5059
5211
                                    )
5060
5212
                                );
5061
5213
                        }
5062
 
                        else if(fb->focus_object < (fb->total_objects - 1))
 
5214
                        else if(fb->focus_object < (nobjs - 1))
5063
5215
                        {
5064
 
                            gint        i = MAX(fb->total_objects - 1, 0),
 
5216
                            gint        i = MAX((nobjs - 1), 0),
5065
5217
                                        n = fb->focus_object;
5066
5218
 
5067
5219
                            fb->focus_object = i;
5068
5220
 
5069
5221
                            /* Select? */
5070
5222
                            if((key->state & GDK_SHIFT_MASK) &&
5071
 
                               (fb->total_objects > 0)
 
5223
                               (nobjs > 0)
5072
5224
                            )
5073
5225
                            {
5074
5226
                                gint j;
5112
5264
                        }
5113
5265
                        else if(fb->focus_object > 0)
5114
5266
                        {
5115
 
                            const gint  n = fb->focus_object,
 
5267
                            const gint  nobjs = g_list_length(fb->objects_list),
 
5268
                                        n = fb->focus_object,
5116
5269
                                        i = n - 1;
5117
5270
 
5118
5271
                            fb->focus_object = i;
5119
5272
 
5120
5273
                            /* Select? */
5121
5274
                            if((key->state & GDK_SHIFT_MASK) &&
5122
 
                               (fb->total_objects > 0)
 
5275
                               (nobjs > 0)
5123
5276
                            )
5124
5277
                            {
5125
5278
                                if(!OBJISSEL(fb, n))
5152
5305
                    if(key_press)
5153
5306
                    {
5154
5307
                        /* Scroll only? */
 
5308
                        const gint nobjs = g_list_length(fb->objects_list);
5155
5309
                        if(key->state & GDK_CONTROL_MASK)
5156
5310
                        {
5157
5311
                            /* No vertical scrolling */
5158
5312
                        }
5159
 
                        else if(fb->focus_object < (fb->total_objects - 1))
 
5313
                        else if(fb->focus_object < (nobjs - 1))
5160
5314
                        {
5161
5315
                            const gint  n = MAX(fb->focus_object, 0),
5162
5316
                                        i = n + 1;
5165
5319
 
5166
5320
                            /* Select? */
5167
5321
                            if((key->state & GDK_SHIFT_MASK) &&
5168
 
                               (fb->total_objects > 0)
 
5322
                               (nobjs > 0)
5169
5323
                            )
5170
5324
                            {
5171
5325
                                if(!OBJISSEL(fb, n))
5214
5368
                        }
5215
5369
                        else if(fb->focus_object > 0)
5216
5370
                        {
5217
 
                            const gint  n = fb->focus_object,
 
5371
                            const gint  nobjs = g_list_length(fb->objects_list),
 
5372
                                        n = fb->focus_object,
5218
5373
                                        i = MAX(
5219
 
                        fb->focus_object - fb->objects_per_row, 0
 
5374
                        (fb->focus_object - fb->objects_per_row), 0
5220
5375
                                        );
5221
5376
 
5222
5377
                            fb->focus_object = i;
5223
5378
 
5224
5379
                            /* Select? */
5225
5380
                            if((key->state & GDK_SHIFT_MASK) &&
5226
 
                               (fb->total_objects > 0)
 
5381
                               (nobjs > 0)
5227
5382
                            )
5228
5383
                            {
5229
5384
                                gint j;
5230
 
                                for(j = MIN(n, fb->total_objects - 1); j >= i; j--)
 
5385
                                for(j = MIN(n, (nobjs - 1)); j >= i; j--)
5231
5386
                                {
5232
5387
                                    if(!OBJISSEL(fb, j))
5233
5388
                                        fb->selection = g_list_append(
5256
5411
                    if(key_press)
5257
5412
                    {
5258
5413
                        /* Scroll only? */
 
5414
                        const gint nobjs = g_list_length(fb->objects_list);
5259
5415
                        if(key->state & GDK_CONTROL_MASK)
5260
5416
                        {
5261
5417
                            GtkRange *range = (GtkRange *)fb->list_hsb;
5270
5426
                                    )
5271
5427
                                );
5272
5428
                        }
5273
 
                        else if(fb->focus_object < (fb->total_objects - 1))
 
5429
                        else if(fb->focus_object < (nobjs - 1))
5274
5430
                        {
5275
5431
                            const gint  n = MAX(fb->focus_object, 0),
5276
5432
                                        i = MIN(
5277
 
                                            n + fb->objects_per_row,
5278
 
                                            fb->total_objects - 1
 
5433
                                            (n + fb->objects_per_row),
 
5434
                                            (nobjs - 1)
5279
5435
                                        );
5280
5436
 
5281
5437
                            fb->focus_object = i;
5282
5438
 
5283
5439
                            /* Select? */
5284
5440
                            if((key->state & GDK_SHIFT_MASK) &&
5285
 
                               (fb->total_objects > 0)
 
5441
                               (nobjs > 0)
5286
5442
                            )
5287
5443
                            {
5288
5444
                                gint j;
5331
5487
                        }
5332
5488
                        else if(fb->focus_object > 0)
5333
5489
                        {
5334
 
                            gint        n = fb->focus_object,
 
5490
                            const gint  nobjs = g_list_length(fb->objects_list),
 
5491
                                        n = fb->focus_object,
5335
5492
                                        i = MAX(
5336
 
                        fb->focus_object - fb->objects_per_row, 0
 
5493
                        (fb->focus_object - fb->objects_per_row), 0
5337
5494
                                        );
5338
5495
 
5339
5496
                            fb->focus_object = i;
5340
5497
 
5341
5498
                            /* Select? */
5342
5499
                            if((key->state & GDK_SHIFT_MASK) &&
5343
 
                               (fb->total_objects > 0)
 
5500
                               (nobjs > 0)
5344
5501
                            )
5345
5502
                            {
5346
5503
                                gint j;
5347
 
                                for(j = MIN(n, fb->total_objects - 1); j >= i; j--)
 
5504
                                for(j = MIN(n, (nobjs - 1)); j >= i; j--)
5348
5505
                                {
5349
5506
                                    if(!OBJISSEL(fb, j))
5350
5507
                                        fb->selection = g_list_append(
5372
5529
                    if(key_press)
5373
5530
                    {
5374
5531
                        /* Scroll only? */
 
5532
                        const gint nobjs = g_list_length(fb->objects_list);
5375
5533
                        if(key->state & GDK_CONTROL_MASK)
5376
5534
                        {
5377
5535
                            GtkRange *range = (GtkRange *)fb->list_hsb;
5386
5544
                                    )
5387
5545
                                );
5388
5546
                        }
5389
 
                        else if(fb->focus_object < (fb->total_objects - 1))
 
5547
                        else if(fb->focus_object < (nobjs - 1))
5390
5548
                        {
5391
 
                            gint        n = fb->focus_object,
 
5549
                            const gint  n = fb->focus_object,
5392
5550
                                        i = MIN(
5393
 
                            fb->focus_object + fb->objects_per_row,
5394
 
                            fb->total_objects - 1
 
5551
                            (fb->focus_object + fb->objects_per_row),
 
5552
                                            (nobjs - 1)
5395
5553
                                        );
5396
5554
 
5397
5555
                            fb->focus_object = i;
5398
5556
 
5399
5557
                            /* Select? */
5400
5558
                            if((key->state & GDK_SHIFT_MASK) &&
5401
 
                               (fb->total_objects > 0)
 
5559
                               (nobjs > 0)
5402
5560
                            )
5403
5561
                            {
5404
5562
                                gint j;
5443
5601
                        }
5444
5602
                        else if(fb->focus_object > 0)
5445
5603
                        {
5446
 
                            gint        i = 0,
 
5604
                            const gint  nobjs = g_list_length(fb->objects_list),
 
5605
                                        i = 0,
5447
5606
                                        n = fb->focus_object;
5448
5607
 
5449
5608
                            fb->focus_object = i;
5450
5609
 
5451
5610
                            /* Select? */
5452
5611
                            if((key->state & GDK_SHIFT_MASK) &&
5453
 
                               (fb->total_objects > 0)
 
5612
                               (nobjs > 0)
5454
5613
                            )
5455
5614
                            {
5456
5615
                                gint j;
5457
 
                                for(j = MIN(n, fb->total_objects - 1); j >= i; j--)
 
5616
                                for(j = MIN(n, (nobjs - 1)); j >= i; j--)
5458
5617
                                {
5459
5618
                                    if(!OBJISSEL(fb, j))
5460
5619
                                        fb->selection = g_list_append(
5482
5641
                    if(key_press)
5483
5642
                    {
5484
5643
                        /* Scroll only? */
 
5644
                        const gint nobjs = g_list_length(fb->objects_list);
5485
5645
                        if(key->state & GDK_CONTROL_MASK)
5486
5646
                        {
5487
5647
                            GtkRange *range = (GtkRange *)fb->list_hsb;
5496
5656
                                    )
5497
5657
                                );
5498
5658
                        }
5499
 
                        else if(fb->focus_object < (fb->total_objects - 1))
 
5659
                        else if(fb->focus_object < (nobjs - 1))
5500
5660
                        {
5501
 
                            gint        i = MAX(fb->total_objects - 1, 0),
 
5661
                            const gint  i = MAX(nobjs - 1, 0),
5502
5662
                                        n = fb->focus_object;
5503
5663
 
5504
5664
                            fb->focus_object = i;
5505
5665
 
5506
5666
                            /* Select? */
5507
5667
                            if((key->state & GDK_SHIFT_MASK) &&
5508
 
                               (fb->total_objects > 0)
 
5668
                               (nobjs > 0)
5509
5669
                            )
5510
5670
                            {
5511
5671
                                gint j;
5636
5796
            /* Unmap the floating prompt as needed */
5637
5797
            if(FPromptIsQuery())
5638
5798
                FPromptBreakQuery();
5639
 
            /* Grab focus as needed */
 
5799
            /* Grab the focus as needed */
5640
5800
            if(!GTK_WIDGET_HAS_FOCUS(w))
5641
5801
                gtk_widget_grab_focus(w);
5642
 
            /* Handle by button number */
 
5802
            /* Handle by the button number */
5643
5803
            switch(button->button)
5644
5804
            {
5645
5805
              case GDK_BUTTON1:         /* Select */
5808
5968
                        fb->selection = fb->selection_end = NULL;
5809
5969
                    }
5810
5970
                }
5811
 
                /* Update entry with the new list of selected
 
5971
                /* Update the entry with the new list of selected
5812
5972
                 * objects
5813
5973
                 */
5814
5974
                FileBrowserEntrySetSelectedObjects(fb);
5834
5994
                if(fb->list_menu != NULL)
5835
5995
                {
5836
5996
                    GtkMenu *menu = GTK_MENU(fb->list_menu);
5837
 
                    gint i = FileBrowserListSelectCoordinates(
 
5997
                    const gint i = FileBrowserListSelectCoordinates(
5838
5998
                        fb, (gint)button->x, (gint)button->y
5839
5999
                    );
5840
6000
                    /* If ctrl or shift modifier keys are held then do
5851
6011
                    }
5852
6012
                    else if(i > -1)
5853
6013
                    {
5854
 
                        /* Unselect all objects */
 
6014
                        /* Unselect all the objects */
5855
6015
                        fb->focus_object = -1;
5856
6016
                        if(fb->selection != NULL)
5857
6017
                            g_list_free(fb->selection);
5868
6028
                         * object
5869
6029
                         */
5870
6030
                        FileBrowserListObjectSetDNDIcon(fb, i);
 
6031
 
 
6032
                        /* Update the entry with the new list of
 
6033
                         * selected objects
 
6034
                         */
 
6035
                        FileBrowserEntrySetSelectedObjects(fb);
5871
6036
                    }
5872
6037
 
5873
 
                    /* Map menu */
 
6038
                    /* Map the right-click menu */
5874
6039
                    gtk_menu_popup(
5875
6040
                        menu, NULL, NULL,
5876
6041
                        NULL, NULL,
5880
6045
                break;
5881
6046
 
5882
6047
              case GDK_BUTTON4:
5883
 
                /* Scroll left? */
 
6048
                /* Scroll left */
5884
6049
                if(fb->list_format == FB_LIST_FORMAT_STANDARD)
5885
6050
                {
5886
6051
                    GtkRange *range = (GtkRange *)fb->list_hsb;
5925
6090
                break;
5926
6091
 
5927
6092
              case GDK_BUTTON5:
5928
 
                /* Scroll Right? */
 
6093
                /* Scroll right */
5929
6094
                if(fb->list_format == FB_LIST_FORMAT_STANDARD)
5930
6095
                {
5931
6096
                    GtkRange *range = (GtkRange *)fb->list_hsb;
6139
6304
 */
6140
6305
static void FileBrowserSelectAllCB(GtkWidget *widget, gpointer data)
6141
6306
{
6142
 
        gint i;
 
6307
        gint i, nobjs;
6143
6308
        FileBrowser *fb = FILE_BROWSER(data);
6144
6309
        if(fb == NULL)
6145
6310
            return;
6147
6312
        if(fb->selection != NULL)
6148
6313
            g_list_free(fb->selection);
6149
6314
        fb->selection = NULL;
6150
 
        for(i = 0; i < fb->total_objects; i++)
 
6315
        nobjs = g_list_length(fb->objects_list);
 
6316
        for(i = 0; i < nobjs; i++)
6151
6317
            fb->selection = g_list_append(
6152
6318
                fb->selection, (gpointer)i
6153
6319
            );
6177
6343
 */
6178
6344
static void FileBrowserInvertSelectionCB(GtkWidget *widget, gpointer data)
6179
6345
{
6180
 
        gint i;
6181
 
        GList *glist = NULL;
 
6346
        gint i, nobjs;
 
6347
        GList *glist;
6182
6348
        FileBrowser *fb = FILE_BROWSER(data);
6183
6349
        if(fb == NULL)
6184
6350
            return;
6185
6351
 
6186
 
        for(i = 0; i < fb->total_objects; i++)
 
6352
        nobjs = g_list_length(fb->objects_list);
 
6353
        glist = NULL;
 
6354
        for(i = 0; i < nobjs; i++)
6187
6355
        {
6188
6356
            if(!OBJISSEL(fb, i))
6189
6357
                glist = g_list_append(glist, (gpointer)i);
6241
6409
 CDialogSetTransientFor(NULL);                  \
6242
6410
}
6243
6411
 
 
6412
        FileBrowserSetBusy(fb, TRUE);
 
6413
 
6244
6414
        /* No directory deliminators may exist in the new value */
6245
 
        if(strchr(value, G_DIR_SEPARATOR) != NULL)
 
6415
        if(strchr((const char *)value, G_DIR_SEPARATOR) != NULL)
6246
6416
        {
6247
 
            gchar *s = g_strdup_printf(
 
6417
            gchar *msg = g_strdup_printf(
6248
6418
#if defined(PROG_LANGUAGE_SPANISH)
6249
6419
"El nombre nuevo \"%s\" contiene deliminators de\n\
6250
6420
gu�a de '%c' que no se permiten en un nombre de objeto."
6273
6443
                ,
6274
6444
                value, G_DIR_SEPARATOR
6275
6445
            );
6276
 
            MESSAGE_RENAME_FAILED(s);
6277
 
            g_free(s);
 
6446
            MESSAGE_RENAME_FAILED(msg);
 
6447
            g_free(msg);
 
6448
            FileBrowserSetBusy(fb, FALSE);
6278
6449
            return;
6279
6450
        }
6280
6451
 
6281
 
        /* Get last selected object */
 
6452
        /* Get the last selected object */
6282
6453
        glist = fb->selection_end;
6283
6454
        i = (glist != NULL) ? (gint)glist->data : -1;
6284
6455
        o = FileBrowserGetObject(fb, i);
6285
 
        if((o != NULL) ? (o->full_path != NULL) : FALSE)
 
6456
        if((o != NULL) ?
 
6457
            (o->name != NULL) && (o->full_path != NULL) : FALSE
 
6458
        )
6286
6459
        {
 
6460
            struct stat lstat_buf;
6287
6461
            const gchar *cur_location = FileBrowserGetLocation(fb);
6288
6462
            gchar       *old_full_path = STRDUP(o->full_path),
6289
6463
                        *new_full_path = STRDUP(
6290
6464
                            PrefixPaths(cur_location, value)
6291
6465
                        );
6292
 
            struct stat lstat_buf;
6293
6466
 
6294
6467
            /* New name and old name the same? */
6295
 
            if(!strcmp(o->name, value))
 
6468
            if(!strcmp((const char *)o->name, (const char *)value))
6296
6469
            {
6297
6470
 
6298
6471
            }
6300
6473
             * already exists
6301
6474
             */
6302
6475
#ifdef _WIN32
6303
 
            else if(stat(new_full_path, &lstat_buf) == 0)
 
6476
            else if(stat((const char *)new_full_path, &lstat_buf) == 0)
6304
6477
#else
6305
 
            else if(lstat(new_full_path, &lstat_buf) == 0)
 
6478
            else if(lstat((const char *)new_full_path, &lstat_buf) == 0)
6306
6479
#endif
6307
6480
            {
6308
 
                gchar *s = g_strdup_printf(
 
6481
                gchar *msg = g_strdup_printf(
6309
6482
"An object by the name of \"%s\" already exists.",
6310
6483
                    value
6311
6484
                );
6312
 
                MESSAGE_RENAME_FAILED(s);
6313
 
                g_free(s);
 
6485
                MESSAGE_RENAME_FAILED(msg);
 
6486
                g_free(msg);
6314
6487
            }
6315
6488
            /* Rename */
6316
 
            else if(rename(old_full_path, new_full_path))
 
6489
            else if(rename((const char *)old_full_path, (const char *)new_full_path))
6317
6490
            {
6318
6491
                const gint error_code = (gint)errno;
6319
 
                gchar *s = g_strdup_printf(
 
6492
                gchar *msg = g_strdup_printf(
6320
6493
                    "%s.",
6321
6494
                    g_strerror(error_code)
6322
6495
                );
6323
 
                MESSAGE_RENAME_FAILED(s);
6324
 
                g_free(s);
 
6496
                MESSAGE_RENAME_FAILED(msg);
 
6497
                g_free(msg);
6325
6498
            }
6326
6499
            else
6327
6500
            {
6330
6503
                /* Update the list */
6331
6504
                FileBrowserListUpdate(fb, NULL);
6332
6505
 
6333
 
                /* Reselect object */
6334
 
                for(i = 0; i < fb->total_objects; i++)
 
6506
                /* Reselect the object */
 
6507
                for(glist = fb->objects_list, i = 0;
 
6508
                    glist != NULL;
 
6509
                    glist = g_list_next(glist), i++
 
6510
                )
6335
6511
                {
6336
 
                    o = fb->object[i];
6337
 
                    if((o != NULL) ? (o->full_path == NULL) : TRUE)
6338
 
                        continue;
6339
 
 
6340
 
                    if(!strcmp(o->full_path, new_full_path))
 
6512
                    o = FILE_BROWSER_OBJECT(glist->data);
 
6513
                    if(o == NULL)
 
6514
                        continue;
 
6515
 
 
6516
                    if(o->full_path == NULL)
 
6517
                        continue;
 
6518
 
 
6519
                    if(!strcmp((const char *)o->full_path, (const char *)new_full_path))
6341
6520
                    {
6342
6521
                        /* Select this object */
6343
6522
                        fb->focus_object = i;
6356
6535
 
6357
6536
                /* Update selected objects on entry */
6358
6537
                FileBrowserEntrySetSelectedObjects(fb);
 
6538
 
 
6539
                /* Notify about the rename */
 
6540
                if(fb->object_modified_cb != NULL)
 
6541
                    fb->object_modified_cb(
 
6542
                        old_full_path,
 
6543
                        new_full_path,
 
6544
                        fb->object_modified_data
 
6545
                    );
6359
6546
            }
6360
6547
 
6361
6548
            g_free(old_full_path);
6362
6549
            g_free(new_full_path);
6363
6550
        }
6364
6551
 
 
6552
        FileBrowserSetBusy(fb, FALSE);
 
6553
 
6365
6554
#undef MESSAGE_RENAME_FAILED
6366
6555
#undef TITLE_RENAME_FAILED
6367
6556
}
6763
6952
}
6764
6953
 
6765
6954
/*
6766
 
 *      List object delete callback.
 
6955
 *      Delete callback.
6767
6956
 */
6768
6957
static void FileBrowserDeleteCB(GtkWidget *widget, gpointer data)
6769
6958
{
6918
7107
                if(ISLPATHDIR(full_path))
6919
7108
                {
6920
7109
                    /* Delete directory */
6921
 
                    if(rmdir(full_path))
 
7110
                    if(rmdir((const char *)full_path))
6922
7111
                    {
6923
7112
                        const gint error_code = (gint)errno;
6924
 
                        gchar *s = g_strdup_printf(
 
7113
                        gchar *msg = g_strdup_printf(
6925
7114
                            "%s.",
6926
7115
                            g_strerror(error_code)
6927
7116
                        );
6928
 
                        MESSAGE_DELETE_FAILED(s);
6929
 
                        g_free(s);
 
7117
                        MESSAGE_DELETE_FAILED(msg);
 
7118
                        g_free(msg);
6930
7119
                    }
6931
7120
                    else
6932
7121
                    {
6939
7128
                    if(unlink((const char *)full_path))
6940
7129
                    {
6941
7130
                        const gint error_code = (gint)errno;
6942
 
                        gchar *s = g_strdup_printf(
 
7131
                        gchar *msg = g_strdup_printf(
6943
7132
                            "%s.",
6944
7133
                            g_strerror(error_code)
6945
7134
                        );
6946
 
                        MESSAGE_DELETE_FAILED(s);
6947
 
                        g_free(s);
 
7135
                        MESSAGE_DELETE_FAILED(msg);
 
7136
                        g_free(msg);
6948
7137
                    }
6949
7138
                    else
6950
7139
                    {
6951
7140
                        objects_deleted++;
6952
7141
                    }
6953
7142
                }
 
7143
 
 
7144
                /* Notify about the deleted object */
 
7145
                if(fb->object_deleted_cb != NULL)
 
7146
                    fb->object_deleted_cb(
 
7147
                        full_path,
 
7148
                        fb->object_deleted_data
 
7149
                    );
6954
7150
            }
6955
7151
 
6956
7152
            glist = g_list_next(glist);
7038
7234
                    gtk_entry_set_text(entry, (path != NULL) ? path : "");
7039
7235
                    gtk_entry_set_position(entry, -1);
7040
7236
 
7041
 
                    /* If there was no change in the path then beep */
7042
 
                    if((prev_path != NULL) && (path != NULL))
7043
 
                    {
7044
 
                        if(!strcmp((const char *)prev_path, (const char *)path))
7045
 
                            gdk_beep();
7046
 
                    }
 
7237
                    /* If there was no change in the path then beep */
 
7238
                    if((prev_path != NULL) && (path != NULL))
 
7239
                    {
 
7240
                        if(!strcmp((const char *)prev_path, (const char *)path))
 
7241
                            gdk_beep();
 
7242
                    }
7047
7243
 
7048
7244
                    g_free(prev_path);
7049
7245
                    g_free(path);
7232
7428
        GdkWindow *window;
7233
7429
        GtkAdjustment *adj;
7234
7430
        GtkAccelGroup *accelgrp;
7235
 
        GtkWidget *w, *parent, *parent2, *parent3, *parent4;
 
7431
        GtkWidget       *w,
 
7432
                        *parent, *parent2, *parent3, *parent4,
 
7433
                        *toplevel;
7236
7434
        pulist_struct *pulist;
7237
7435
        pulistbox_struct *pulistbox;
7238
7436
        FileBrowser *fb = &file_browser;
7239
7437
 
7240
 
        /* Reset values */
 
7438
        fb->toplevel = toplevel = gtk_window_new(GTK_WINDOW_DIALOG);
 
7439
        fb->accelgrp = accelgrp = gtk_accel_group_new();
7241
7440
        fb->busy_count = 0;
7242
7441
        fb->freeze_count = 0;
7243
 
        fb->accelgrp = accelgrp = gtk_accel_group_new();
 
7442
        fb->block_loop_level = 0;
 
7443
        fb->user_response = FALSE;
7244
7444
        fb->cur_busy = gdk_cursor_new(GDK_WATCH);
7245
7445
        fb->cur_column_hresize = gdk_cursor_new(GDK_SB_H_DOUBLE_ARROW);
7246
7446
        fb->cur_translate = gdk_cursor_new(GDK_FLEUR);
7248
7448
        fb->vsb_map_state = FALSE;
7249
7449
        fb->hsb_map_state = FALSE;
7250
7450
        fb->cur_location = NULL;
7251
 
        fb->block_loop_level = 0;
7252
 
        fb->user_response = FALSE;
7253
7451
        fb->list_format = FB_LIST_FORMAT_STANDARD;
7254
 
        fb->column = NULL;
7255
 
        fb->total_columns = 0;
7256
 
        memset(&fb->cur_type, 0x00, sizeof(fb_type_struct));
7257
 
        fb->selected_path = NULL;
7258
 
        fb->total_selected_paths = 0;
7259
 
        fb->icon = NULL;
7260
 
        fb->total_icons = 0;
 
7452
        fb->columns_list = NULL;
 
7453
        fb->icons_list = NULL;
7261
7454
#ifdef _WIN32
7262
7455
        fb->uid = 0;
7263
7456
        fb->euid = 0;
7275
7468
        fb->home_path = STRDUP(g_getenv("HOME"));
7276
7469
#endif
7277
7470
        fb->device_paths_list = NULL;
 
7471
        fb->objects_list = NULL;
 
7472
        fb->objects_per_row = 0;
7278
7473
        fb->focus_object = -1;
7279
 
        fb->selection = fb->selection_end = NULL;
7280
 
        fb->object = NULL;
7281
 
        fb->total_objects = 0;
7282
 
        fb->objects_per_row = 0;
7283
7474
        fb->last_single_select_object = -1;
 
7475
        fb->selection = fb->selection_end = NULL;
7284
7476
        fb->show_hidden_objects = TRUE;
 
7477
        memset(&fb->cur_type, 0x00, sizeof(fb_type_struct));
 
7478
        fb->selected_path = NULL;
 
7479
        fb->total_selected_paths = 0;
 
7480
        fb->object_created_cb = NULL;
 
7481
        fb->object_created_data = NULL;
 
7482
        fb->object_modified_cb = NULL;
 
7483
        fb->object_modified_data = NULL;
 
7484
        fb->object_deleted_cb = NULL;
 
7485
        fb->object_deleted_data = NULL;
7285
7486
        fb->button = 0;
7286
7487
        fb->drag_last_x = 0;
7287
7488
        fb->drag_last_y = 0;
7288
7489
        fb->last_button1_release_time = 0l;
7289
7490
 
7290
 
        /* Toplevel */
7291
 
        fb->toplevel = w = gtk_window_new(GTK_WINDOW_DIALOG);
 
7491
        /* Toplevel GtkWindow */
 
7492
        w = toplevel;
7292
7493
        gtk_window_set_policy(GTK_WINDOW(w), TRUE, TRUE, TRUE);
7293
7494
        gtk_widget_set_usize(w, FB_WIDTH, FB_HEIGHT);
7294
7495
        gtk_window_set_title(GTK_WINDOW(w), "Select File");
8229
8430
            GTK_OBJECT(w), "activate",
8230
8431
            GTK_SIGNAL_FUNC(FileBrowserEntryEnterCB), fb
8231
8432
        );
 
8433
        GUIEditableEndowPopupMenu(w, 0);
8232
8434
        gtk_widget_show(w);
8233
 
        GUISetWidgetTip(w,
 
8435
        GUISetWidgetTip(
 
8436
            w,
8234
8437
#if defined(PROG_LANGUAGE_SPANISH)
8235
8438
"Entre el nombre del objeto, usted puede especificar m�s\
8236
8439
 que un objeto (separa cada nombre con un ',' el car�cter)"
8497
8700
}
8498
8701
 
8499
8702
/*
 
8703
 *      Sets the object created callback.
 
8704
 */
 
8705
void FileBrowserSetObjectCreatedCB(
 
8706
        void (*cb)(
 
8707
                const gchar *path,
 
8708
                gpointer data
 
8709
        ),
 
8710
        gpointer data
 
8711
)
 
8712
{
 
8713
        FileBrowser *fb = &file_browser;
 
8714
        fb->object_created_cb = cb;
 
8715
        fb->object_created_data = data;
 
8716
}
 
8717
 
 
8718
/*
 
8719
 *      Sets the object modified callback.
 
8720
 */
 
8721
void FileBrowserSetObjectModifiedCB(
 
8722
        void (*cb)(
 
8723
                const gchar *old_path,
 
8724
                const gchar *new_path,
 
8725
                gpointer data
 
8726
        ),
 
8727
        gpointer data
 
8728
)
 
8729
{
 
8730
        FileBrowser *fb = &file_browser;
 
8731
        fb->object_modified_cb = cb;
 
8732
        fb->object_modified_data = data;
 
8733
}
 
8734
 
 
8735
/*
 
8736
 *      Sets the object deleted callback.
 
8737
 */
 
8738
void FileBrowserSetObjectDeletedCB(
 
8739
        void (*cb)(
 
8740
                const gchar *path,
 
8741
                gpointer data
 
8742
        ),
 
8743
        gpointer data
 
8744
)
 
8745
{
 
8746
        FileBrowser *fb = &file_browser;
 
8747
        fb->object_deleted_cb = cb;
 
8748
        fb->object_deleted_data = data;
 
8749
}
 
8750
 
 
8751
/*
8500
8752
 *      Returns TRUE if currently blocking for query.
8501
8753
 */
8502
8754
gboolean FileBrowserIsQuery(void) 
8542
8794
void FileBrowserReset(void)
8543
8795
{
8544
8796
        FileBrowser *fb = &file_browser;
8545
 
        gint i;
8546
8797
        GtkEntry *entry;
8547
8798
 
8548
8799
        fb->freeze_count++;
8575
8826
        fb->selection = fb->selection_end = NULL;
8576
8827
 
8577
8828
        /* Delete all the objects */
8578
 
        for(i = 0; i < fb->total_objects; i++)
8579
 
            FileBrowserObjectDestroyCB(fb->object[i]);
8580
 
        g_free(fb->object);
8581
 
        fb->object = NULL;
8582
 
        fb->total_objects = 0;
 
8829
        if(fb->objects_list != NULL)
 
8830
        {
 
8831
            g_list_foreach(
 
8832
                fb->objects_list, (GFunc)FileBrowserObjectDelete, NULL
 
8833
            );
 
8834
            g_list_free(fb->objects_list);
 
8835
            fb->objects_list = NULL;
 
8836
        }
8583
8837
 
8584
 
        /* Reset the objects per row */
 
8838
        /* Reset the number of objects per row */
8585
8839
        fb->objects_per_row = 0;
8586
8840
 
8587
8841
        fb->freeze_count--;
8680
8934
 
8681
8935
        FileBrowserSetBusy(fb, TRUE);
8682
8936
 
8683
 
        /* Map File Browser
 
8937
        /* Map the File Browser
8684
8938
         *
8685
8939
         * This needs to be done now in order to allow the proper
8686
8940
         * realizing of sizes before other things can be updated
 
8941
         *
 
8942
         * A configure_event signal will be emitted at which the
 
8943
         * correct sizes will be known when adding the objects to
 
8944
         * the objects list
8687
8945
         */
8688
8946
        FileBrowserMap();
8689
 
#if 0
8690
 
/* This is not needed any more since object positions are updated when
8691
 
 * a "configure_event" signal is received
8692
 
 */
8693
 
        while(gtk_events_pending() > 0)
8694
 
            gtk_main_iteration();
8695
 
#endif
8696
8947
 
8697
8948
        /* No initial path specified? */
8698
8949
        if(STRISEMPTY(path))
8701
8952
             * check if the list was previous cleared (reset), in
8702
8953
             * which case we need to reget the listing
8703
8954
             */
8704
 
            if(fb->total_objects <= 0)
 
8955
            if(fb->objects_list == NULL)
8705
8956
            {
8706
8957
                FileBrowserListUpdate(fb, NULL);
8707
8958
                FileBrowserLocationsPUListUpdate(fb);
8720
8971
            FileBrowserSetLocation(fb, "~");
8721
8972
 
8722
8973
        /* If there is a first object in the list then set it in focus */
8723
 
        if(fb->total_objects > 0)
 
8974
        if(fb->objects_list != NULL)
8724
8975
        {
8725
8976
            if(fb->focus_object < 0)
8726
8977
            {
8814
9065
        g_list_free(fb->selection);
8815
9066
        fb->selection = fb->selection_end = NULL;
8816
9067
 
8817
 
        /* Delete the objects */
8818
 
        for(i = 0; i < fb->total_objects; i++)
8819
 
            FileBrowserObjectDestroyCB(fb->object[i]);
8820
 
        g_free(fb->object);
8821
 
        fb->object = NULL;
8822
 
        fb->total_objects = 0;
 
9068
        /* Delete all the objects */
 
9069
        if(fb->objects_list != NULL)
 
9070
        {
 
9071
            g_list_foreach(
 
9072
                fb->objects_list, (GFunc)FileBrowserObjectDelete, NULL
 
9073
            );
 
9074
            g_list_free(fb->objects_list);
 
9075
            fb->objects_list = NULL;
 
9076
        }
8823
9077
        fb->objects_per_row = 0;
8824
9078
 
8825
9079
        /* Delete the icons */
8826
 
        for(i = 0; i < fb->total_icons; i++)
8827
 
            FileBrowserIconDestroyCB(fb->icon[i]);
8828
 
        g_free(fb->icon);
8829
 
        fb->icon = NULL;
8830
 
        fb->total_icons = 0;
 
9080
        if(fb->icons_list != NULL)
 
9081
        {
 
9082
            g_list_foreach(
 
9083
                fb->icons_list, (GFunc)FileBrowserIconDelete, NULL
 
9084
            );
 
9085
            g_list_free(fb->icons_list);
 
9086
            fb->icons_list = NULL;
 
9087
        }
8831
9088
 
8832
9089
        /* Delete the list columns */
8833
9090
        FileBrowserListColumnsClear(fb);