~ubuntu-branches/ubuntu/utopic/rhythmbox/utopic-proposed

« back to all changes in this revision

Viewing changes to lib/rb-util.c

Tags: upstream-0.9.2
ImportĀ upstreamĀ versionĀ 0.9.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 */
21
21
 
22
22
#include "rb-util.h"
 
23
#include <gtk/gtk.h>
23
24
#include <string.h>
 
25
#include <libgnomevfs/gnome-vfs.h>
 
26
#include "rb-debug.h"
 
27
 
 
28
static GPrivate * private_is_primary_thread;
24
29
 
25
30
gboolean
26
31
rb_true_function (gpointer dummy)
34
39
        return FALSE;
35
40
}
36
41
 
 
42
gpointer
 
43
rb_null_function (gpointer dummy)
 
44
{
 
45
        return NULL;
 
46
}
 
47
 
37
48
int
38
49
rb_gvalue_compare (GValue *a, GValue *b)
39
50
{
166
177
        return retval;
167
178
}
168
179
 
 
180
int
 
181
rb_compare_gtimeval (GTimeVal *a, GTimeVal *b)
 
182
{
 
183
        if (a->tv_sec == b->tv_sec)
 
184
                /* It's quite unlikely that microseconds are equal,
 
185
                 * so just ignore that case, we don't need a lot
 
186
                 * of precision.
 
187
                 */
 
188
                return a->tv_usec > b->tv_usec ? 1 : -1;
 
189
        else if (a->tv_sec > b->tv_sec)
 
190
                return 1;
 
191
        else
 
192
                return -1;
 
193
}
 
194
 
169
195
/* Taken from totem/video-utils.c CVS HEAD 2004-04-22 */
170
196
static void
171
197
totem_pixbuf_mirror (GdkPixbuf *pixbuf)
206
232
/* Same as gtk_image_new_from_stock except that it mirrors the icons for RTL 
207
233
 * languages
208
234
 */
209
 
GtkWidget *rb_image_new_from_stock (const gchar *stock_id, GtkIconSize size)
 
235
GtkWidget *
 
236
rb_image_new_from_stock (const gchar *stock_id, GtkIconSize size)
210
237
{
211
238
 
212
239
        if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_LTR) {
215
242
 
216
243
                GtkWidget *image;
217
244
                GdkPixbuf *pixbuf;
 
245
                GdkPixbuf *mirror;
218
246
                
219
247
                image = gtk_image_new ();
220
248
                
221
 
                pixbuf = rb_pixbuf_new_from_stock (stock_id, size);
222
 
 
223
 
                gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
 
249
                if (image == NULL) {
 
250
                        return NULL;
 
251
                }
 
252
                
 
253
                pixbuf = gtk_widget_render_icon (image, stock_id, size, NULL);
 
254
                g_assert (pixbuf != NULL);
 
255
                
 
256
                
 
257
                mirror = gdk_pixbuf_copy (pixbuf);
 
258
                gdk_pixbuf_unref (pixbuf);
 
259
 
 
260
                if (!mirror)
 
261
                        return NULL;
 
262
 
 
263
                totem_pixbuf_mirror (mirror);
 
264
                gtk_image_set_from_pixbuf (GTK_IMAGE (image), mirror);
 
265
                gdk_pixbuf_unref (mirror);
224
266
 
225
267
                return image;
226
268
        }
228
270
        return NULL;
229
271
}
230
272
 
231
 
GdkPixbuf *
232
 
rb_pixbuf_new_from_stock (const char *stock_id, GtkIconSize size)
233
 
{
234
 
        GtkWidget *dummy;
235
 
        GdkPixbuf *pixbuf;
236
 
        GdkPixbuf *mirror;
237
 
                
238
 
        dummy = gtk_image_new ();
239
 
                
240
 
        pixbuf = gtk_widget_render_icon (dummy, stock_id, size, NULL);
241
 
                
242
 
        if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_LTR)
243
 
                return pixbuf;
244
 
 
245
 
        mirror = gdk_pixbuf_copy (pixbuf);
246
 
        gdk_pixbuf_unref (pixbuf);
247
 
 
248
 
        if (!mirror)
249
 
                return NULL;
250
 
 
251
 
        totem_pixbuf_mirror (mirror);
252
 
 
253
 
        return mirror;
254
 
}
 
273
void
 
274
rb_gtk_action_popup_menu (GtkUIManager *uimanager, const char *path)
 
275
{
 
276
        GtkWidget *menu;
 
277
 
 
278
        menu = gtk_ui_manager_get_widget (uimanager, path);
 
279
        gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 3, 
 
280
                        gtk_get_current_event_time ());
 
281
}
 
282
 
 
283
static GList *
 
284
get_mount_points (void)
 
285
{
 
286
        GnomeVFSVolumeMonitor *monitor;
 
287
        GList *volumes;
 
288
        GList *it;
 
289
        GList *mount_points = NULL;
 
290
 
 
291
        monitor = gnome_vfs_get_volume_monitor ();
 
292
        /* FIXME: should also get the list of connected drivers (network
 
293
         * shares I assume)
 
294
         */
 
295
        volumes = gnome_vfs_volume_monitor_get_mounted_volumes (monitor);
 
296
 
 
297
        for (it = volumes; it != NULL; it = it->next) {
 
298
                gchar *uri;
 
299
                GnomeVFSVolume *volume;
 
300
 
 
301
                volume = GNOME_VFS_VOLUME (it->data);
 
302
                uri = gnome_vfs_volume_get_activation_uri (volume);
 
303
                g_assert (uri != NULL);
 
304
                mount_points = g_list_prepend (mount_points, uri);
 
305
        }
 
306
 
 
307
        g_list_foreach (volumes, (GFunc)gnome_vfs_volume_ref, NULL);
 
308
        g_list_free (volumes);
 
309
 
 
310
        return mount_points;
 
311
}
 
312
 
 
313
 
 
314
gchar *
 
315
rb_uri_get_mount_point (const char *uri)
 
316
{
 
317
        GList *mount_points = get_mount_points ();
 
318
        GList *it;
 
319
        gchar *mount_point = NULL;
 
320
 
 
321
        for (it = mount_points; it != NULL; it = it->next) {
 
322
                if (g_str_has_prefix (uri, it->data)) {
 
323
                        if ((mount_point == NULL) || (strlen (mount_point) < strlen (it->data))) {
 
324
                                g_free (mount_point);
 
325
                                mount_point = g_strdup (it->data);
 
326
                        }
 
327
                }
 
328
        }
 
329
        g_list_foreach (mount_points, (GFunc)g_free, NULL);
 
330
        g_list_free (mount_points);
 
331
 
 
332
        return mount_point;
 
333
}
 
334
 
 
335
gboolean
 
336
rb_uri_is_mounted (const char *uri)
 
337
{
 
338
        GList *mount_points = get_mount_points ();
 
339
        GList *it;
 
340
        gboolean found = FALSE;
 
341
 
 
342
        if ((uri == NULL) || (*uri == '\0')) {
 
343
                return TRUE;
 
344
        }
 
345
 
 
346
        for (it = mount_points; it != NULL; it = it->next) {
 
347
                if (strcmp (it->data, uri) == 0) {
 
348
                        found = TRUE;
 
349
                        break;
 
350
                }
 
351
        }
 
352
        g_list_foreach (mount_points, (GFunc)g_free, NULL);
 
353
        g_list_free (mount_points);
 
354
 
 
355
/*      if (found == FALSE) {
 
356
                g_print ("%s not mounted\n", uri);
 
357
                }*/
 
358
 
 
359
        return found;
 
360
}
 
361
 
 
362
gboolean
 
363
rb_is_main_thread (void)
 
364
{
 
365
        if (g_thread_supported()) {
 
366
                return GPOINTER_TO_UINT(g_private_get (private_is_primary_thread)) == 1;
 
367
        } else {
 
368
                return TRUE;
 
369
        }
 
370
}
 
371
 
 
372
 
 
373
void
 
374
rb_threads_init (void)
 
375
{
 
376
        private_is_primary_thread = g_private_new (NULL);
 
377
        g_private_set (private_is_primary_thread, GUINT_TO_POINTER (1));
 
378
 
 
379
        /* not really necessary, but in case it does something besides
 
380
         * set up lock functions some day..
 
381
         */
 
382
        gdk_threads_init ();
 
383
}
 
384
 
 
385
gchar **
 
386
rb_string_split_words (const gchar *string)
 
387
{
 
388
        /*return g_slist_prepend (NULL, g_strdup (string));*/
 
389
 
 
390
        GSList *words, *current;
 
391
        gunichar *unicode, *cur_write, *cur_read;
 
392
        gchar **ret;
 
393
        gint i, wordcount = 1;
 
394
        gboolean new_word = TRUE;
 
395
 
 
396
        g_return_val_if_fail (string != NULL, NULL);
 
397
 
 
398
        cur_write = cur_read = unicode = g_utf8_to_ucs4_fast (string, -1, NULL);
 
399
 
 
400
        /* we may fail here, we expect valid utf-8 */
 
401
        g_return_val_if_fail (unicode != NULL, NULL);
 
402
 
 
403
        words = g_slist_prepend (NULL, unicode);
 
404
 
 
405
        /* now normalize this text */
 
406
        while (*cur_read) {
 
407
                switch (g_unichar_type (*cur_read)) {
 
408
                case G_UNICODE_UNASSIGNED:
 
409
                        g_warning ("unassigned unicode character type found");
 
410
                        /* fall through */
 
411
                case G_UNICODE_CONTROL:
 
412
                case G_UNICODE_FORMAT:
 
413
                case G_UNICODE_PRIVATE_USE:
 
414
 
 
415
                case G_UNICODE_SURROGATE:
 
416
                case G_UNICODE_LINE_SEPARATOR:
 
417
                case G_UNICODE_PARAGRAPH_SEPARATOR:
 
418
                case G_UNICODE_SPACE_SEPARATOR:
 
419
                        /* remove these and start a new word */
 
420
                        if (!new_word) {
 
421
                                /* end current word if it isn't ended yet */
 
422
                                *cur_write++ = 0;
 
423
                                new_word = TRUE;
 
424
                        }
 
425
 
 
426
                        break;
 
427
                case G_UNICODE_COMBINING_MARK:
 
428
                case G_UNICODE_ENCLOSING_MARK:
 
429
                case G_UNICODE_NON_SPACING_MARK:
 
430
                case G_UNICODE_CONNECT_PUNCTUATION:
 
431
                case G_UNICODE_DASH_PUNCTUATION:
 
432
                case G_UNICODE_CLOSE_PUNCTUATION:
 
433
                case G_UNICODE_FINAL_PUNCTUATION:
 
434
                case G_UNICODE_INITIAL_PUNCTUATION:
 
435
                case G_UNICODE_OTHER_PUNCTUATION:
 
436
                case G_UNICODE_OPEN_PUNCTUATION:
 
437
                        /* remove these */
 
438
                        /*break;*/
 
439
                case G_UNICODE_LOWERCASE_LETTER:
 
440
                case G_UNICODE_MODIFIER_LETTER:
 
441
                case G_UNICODE_OTHER_LETTER:
 
442
                case G_UNICODE_TITLECASE_LETTER:
 
443
                case G_UNICODE_UPPERCASE_LETTER:
 
444
                case G_UNICODE_DECIMAL_NUMBER:
 
445
                case G_UNICODE_LETTER_NUMBER:
 
446
                case G_UNICODE_OTHER_NUMBER:
 
447
                case G_UNICODE_CURRENCY_SYMBOL:
 
448
                case G_UNICODE_MODIFIER_SYMBOL:
 
449
                case G_UNICODE_MATH_SYMBOL:
 
450
                case G_UNICODE_OTHER_SYMBOL:
 
451
                        /* keep these unchanged */
 
452
                        *cur_write = *cur_read;
 
453
                        if (new_word) {
 
454
                                if (cur_write != unicode) {/* first insert has been done above */
 
455
                                        words = g_slist_prepend (words, cur_write);
 
456
                                        wordcount++;
 
457
                                }
 
458
                                new_word = FALSE;
 
459
                        }
 
460
                        cur_write++;
 
461
                        break;    
 
462
                default:
 
463
                        g_warning ("unknown unicode character type found");
 
464
                        break;
 
465
                }
 
466
                cur_read++;
 
467
        }
 
468
 
 
469
        if (!new_word) {
 
470
                *cur_write++ = 0;
 
471
        }
 
472
 
 
473
        ret = g_new (gchar *, wordcount + 1); 
 
474
        current = words;
 
475
        for (i = wordcount - 1; i >= 0; i--) {
 
476
                ret[i] = g_ucs4_to_utf8 (current->data, -1, NULL, NULL, NULL);
 
477
                current = g_slist_next (current);
 
478
        }
 
479
        ret[wordcount] = NULL;
 
480
 
 
481
        g_slist_free (words);
 
482
        g_free (unicode);
 
483
 
 
484
        return ret;
 
485
}
 
486
 
 
487
gchar*
 
488
rb_search_fold (const char *original)
 
489
{
 
490
        GString *string;
 
491
        gunichar *unicode, *cur;
 
492
        
 
493
        g_return_val_if_fail (original != NULL, NULL);
 
494
 
 
495
        /* old behaviour is equivalent to: return g_utf8_casefold (original, -1); */
 
496
        
 
497
        string = g_string_new (NULL);
 
498
        unicode = g_utf8_to_ucs4_fast (original, -1, NULL);
 
499
 
 
500
        for (cur = unicode; *cur != 0; cur++) {
 
501
                switch (g_unichar_type (*cur)) {
 
502
                case G_UNICODE_COMBINING_MARK:
 
503
                case G_UNICODE_ENCLOSING_MARK:
 
504
                case G_UNICODE_NON_SPACING_MARK:
 
505
                case G_UNICODE_CONNECT_PUNCTUATION:
 
506
                case G_UNICODE_DASH_PUNCTUATION:
 
507
                case G_UNICODE_CLOSE_PUNCTUATION:
 
508
                case G_UNICODE_FINAL_PUNCTUATION:
 
509
                case G_UNICODE_INITIAL_PUNCTUATION:
 
510
                case G_UNICODE_OTHER_PUNCTUATION:
 
511
                case G_UNICODE_OPEN_PUNCTUATION:
 
512
                        /* remove these */
 
513
                        break;
 
514
 
 
515
                case G_UNICODE_LOWERCASE_LETTER:
 
516
                case G_UNICODE_MODIFIER_LETTER:
 
517
                case G_UNICODE_OTHER_LETTER:
 
518
                case G_UNICODE_TITLECASE_LETTER:
 
519
                case G_UNICODE_UPPERCASE_LETTER:
 
520
                        /* convert to lower case */
 
521
                        *cur = g_unichar_tolower (*cur);
 
522
                        /* ... and fall through */\
 
523
                case G_UNICODE_DECIMAL_NUMBER:
 
524
                case G_UNICODE_LETTER_NUMBER:
 
525
                case G_UNICODE_OTHER_NUMBER:
 
526
                /* should be keep symbols? */
 
527
                case G_UNICODE_CURRENCY_SYMBOL:
 
528
                case G_UNICODE_MODIFIER_SYMBOL:
 
529
                case G_UNICODE_MATH_SYMBOL:
 
530
                case G_UNICODE_OTHER_SYMBOL:
 
531
                        g_string_append_unichar (string, *cur);
 
532
                        break;
 
533
 
 
534
                case G_UNICODE_UNASSIGNED:
 
535
                        g_warning ("unassigned unicode character type found");
 
536
                        /* fall through */
 
537
 
 
538
                default:
 
539
                        /* leave these in */
 
540
                        g_string_append_unichar (string, *cur);
 
541
                }
 
542
        }
 
543
        
 
544
        g_free (unicode);
 
545
                        
 
546
        return g_string_free (string, FALSE);
 
547
}
 
548