app-manager/localmedia.c
author J. Ali Harlow <ali@juiblex.co.uk>
Sat Feb 20 12:11:02 2010 +0000 (2010-02-20)
changeset 9 8d3b1ddf789c
child 10 8b50be3e2998
permissions -rw-r--r--
First cut at an applications manager
     1 /*
     2  * Copyright (C) 2010  J. Ali Harlow <ali@juiblex.co.uk>
     3  *
     4  * This program is free software; you can redistribute it and/or modify
     5  * it under the terms of the GNU General Public License as published by
     6  * the Free Software Foundation; either version 2 of the License, or
     7  * (at your option) any later version.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License along
    15  * with this program; if not, write to the Free Software Foundation, Inc.,
    16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    17  */
    18 
    19 #include "config.h"
    20 #include <stdlib.h>
    21 #include <string.h>
    22 #include <glib.h>
    23 #include <gio/gio.h>
    24 #include <gtk/gtk.h>
    25 #include <plover-gtk/packagestore.h>
    26 #include "localmedia.h"
    27 
    28 G_DEFINE_TYPE(PloverLocalMediaStore,plover_local_media_store,
    29   PLOVER_TYPE_PACKAGE_STORE);
    30 
    31 static void plover_local_media_store_dispose(GObject *obj)
    32 {
    33     PloverLocalMediaStore *store=PLOVER_LOCAL_MEDIA_STORE(obj);
    34     if (store->monitor)
    35     {
    36 	g_object_unref(store->monitor);
    37 	store->monitor=NULL;
    38     }
    39     if (G_OBJECT_CLASS(plover_local_media_store_parent_class)->dispose)
    40 	G_OBJECT_CLASS(plover_local_media_store_parent_class)->dispose(obj);
    41 }
    42 
    43 static void
    44   plover_local_media_store_class_init(PloverLocalMediaStoreClass *klass)
    45 {
    46     GObjectClass *oclass=G_OBJECT_CLASS(klass);
    47     oclass->dispose=plover_local_media_store_dispose;
    48 }
    49 
    50 GtkTreeModel *plover_local_media_store_new(void)
    51 {
    52     return g_object_new(PLOVER_TYPE_LOCAL_MEDIA_STORE,NULL);
    53 }
    54 
    55 static void local_media_scan_mount(PloverLocalMediaStore *store,GMount *mount)
    56 {
    57     GFile *root;
    58     gchar *path;
    59     PloverPackageSet *set;
    60     root=g_mount_get_root(mount);
    61     path=g_file_get_path(root);
    62     if (path)
    63     {
    64 	set=plover_package_set_new_from_repository(path,NULL);
    65 	if (set)
    66 	{
    67 	    g_object_set_data(G_OBJECT(mount),"plover-local-media-set",set);
    68 	    plover_package_store_add_set(PLOVER_PACKAGE_STORE(store),set);
    69 	    g_object_ref(mount);
    70 	}
    71 	g_free(path);
    72     }
    73     g_object_unref(root);
    74 }
    75 
    76 static void local_media_mounted(GObject *source,GAsyncResult *res,gpointer data)
    77 {
    78     GVolume *volume=G_VOLUME(source);
    79     GMount *mount;
    80     PloverLocalMediaStore *store=PLOVER_LOCAL_MEDIA_STORE(data);
    81     if (g_volume_mount_finish(volume,res,NULL))
    82     {
    83 	mount=g_volume_get_mount(volume);
    84 	if (mount)
    85 	{
    86 	    local_media_scan_mount(store,mount);
    87 	    g_object_unref(mount);
    88 	}
    89     }
    90     g_object_unref(volume);
    91 }
    92 
    93 static void local_media_scan_drive(PloverLocalMediaStore *store,GDrive *drive)
    94 {
    95     GVolume *volume;
    96     GMount *mount;
    97     GList *volumes,*link;
    98     if (g_drive_has_media(drive))
    99     {
   100 	volumes=g_drive_get_volumes(drive);
   101 	for(link=volumes;link;link=link->next)
   102 	{
   103 	    volume=G_VOLUME(link->data);
   104 	    mount=g_volume_get_mount(volume);
   105 	    if (mount)
   106 	    {
   107 		local_media_scan_mount(store,mount);
   108 		g_object_unref(mount);
   109 	    }
   110 	    else if (!store->implicit_scan && g_volume_can_mount(volume))
   111 		g_volume_mount(volume,G_MOUNT_MOUNT_NONE,NULL,NULL,
   112 		  local_media_mounted,store);
   113 	    g_object_unref(volume);
   114 	}
   115 	g_list_free(volumes);
   116     }
   117 }
   118 
   119 static void local_media_polled(GObject *source,GAsyncResult *res,gpointer data)
   120 {
   121     GDrive *drive=G_DRIVE(source);
   122     PloverLocalMediaStore *store=PLOVER_LOCAL_MEDIA_STORE(data);
   123     if (g_drive_poll_for_media_finish(drive,res,NULL))
   124 	local_media_scan_drive(store,drive);
   125     g_object_unref(drive);
   126 }
   127 
   128 void plover_local_media_store_scan(PloverLocalMediaStore *store)
   129 {
   130     GList *drives,*link;
   131     GDrive *drive;
   132     g_return_if_fail(PLOVER_IS_LOCAL_MEDIA_STORE(store));
   133     drives=g_volume_monitor_get_connected_drives(store->monitor);
   134     for(link=drives;link;link=link->next)
   135     {
   136 	drive=G_DRIVE(link->data);
   137 	if (g_drive_is_media_removable(drive))
   138 	{
   139 	    if (!g_drive_is_media_check_automatic(drive) &&
   140 	      g_drive_can_poll_for_media(drive) ||
   141 	      !g_drive_has_media(drive) && !store->implicit_scan)
   142 	    {
   143 		g_object_ref(drive);
   144 		g_drive_poll_for_media(drive,NULL,local_media_polled,store);
   145 	    }
   146 	    else
   147 		local_media_scan_drive(store,drive);
   148 	}
   149 	g_object_unref(drive);
   150     }
   151     g_list_free(drives);
   152 }
   153 
   154 static void local_media_mount_added(GVolumeMonitor *volume_monitor,
   155   GMount *mount,PloverLocalMediaStore *store)
   156 {
   157     local_media_scan_mount(store,mount);
   158 }
   159 
   160 static void local_media_mount_removed(GVolumeMonitor *volume_monitor,
   161   GMount *mount,PloverLocalMediaStore *store)
   162 {
   163     PloverPackageSet *set=
   164       g_object_get_data(G_OBJECT(mount),"plover-local-media-set");
   165     if (set)
   166     {
   167 	plover_package_store_remove_set(PLOVER_PACKAGE_STORE(store),set);
   168 	g_object_set_data(G_OBJECT(mount),"plover-local-media-set",NULL);
   169 	g_object_unref(set);
   170 	g_object_unref(mount);
   171     }
   172 }
   173 
   174 static void local_media_mount_changed(GVolumeMonitor *volume_monitor,
   175   GMount *mount,PloverLocalMediaStore *store)
   176 {
   177     local_media_mount_removed(volume_monitor,mount,store);
   178     local_media_mount_added(volume_monitor,mount,store);
   179 }
   180 
   181 static void plover_local_media_store_init(PloverLocalMediaStore *store)
   182 {
   183     store->monitor=g_volume_monitor_get();
   184     store->implicit_scan=TRUE;
   185     plover_local_media_store_scan(store);
   186     store->implicit_scan=FALSE;
   187     g_signal_connect(store->monitor,"mount-added",
   188       G_CALLBACK(local_media_mount_added),store);
   189     g_signal_connect(store->monitor,"mount-changed",
   190       G_CALLBACK(local_media_mount_changed),store);
   191     g_signal_connect(store->monitor,"mount-removed",
   192       G_CALLBACK(local_media_mount_removed),store);
   193 }