ali@9: /* ali@9: * Copyright (C) 2010 J. Ali Harlow ali@9: * ali@9: * This program is free software; you can redistribute it and/or modify ali@9: * it under the terms of the GNU General Public License as published by ali@9: * the Free Software Foundation; either version 2 of the License, or ali@9: * (at your option) any later version. ali@9: * ali@9: * This program is distributed in the hope that it will be useful, ali@9: * but WITHOUT ANY WARRANTY; without even the implied warranty of ali@9: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ali@9: * GNU General Public License for more details. ali@9: * ali@9: * You should have received a copy of the GNU General Public License along ali@9: * with this program; if not, write to the Free Software Foundation, Inc., ali@9: * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ali@9: */ ali@9: ali@9: #include "config.h" ali@9: #include ali@9: #include ali@9: #include ali@9: #include ali@9: #include ali@9: #include ali@9: #include "localmedia.h" ali@9: ali@9: G_DEFINE_TYPE(PloverLocalMediaStore,plover_local_media_store, ali@9: PLOVER_TYPE_PACKAGE_STORE); ali@9: ali@9: static void plover_local_media_store_dispose(GObject *obj) ali@9: { ali@9: PloverLocalMediaStore *store=PLOVER_LOCAL_MEDIA_STORE(obj); ali@9: if (store->monitor) ali@9: { ali@9: g_object_unref(store->monitor); ali@9: store->monitor=NULL; ali@9: } ali@9: if (G_OBJECT_CLASS(plover_local_media_store_parent_class)->dispose) ali@9: G_OBJECT_CLASS(plover_local_media_store_parent_class)->dispose(obj); ali@9: } ali@9: ali@9: static void ali@9: plover_local_media_store_class_init(PloverLocalMediaStoreClass *klass) ali@9: { ali@9: GObjectClass *oclass=G_OBJECT_CLASS(klass); ali@9: oclass->dispose=plover_local_media_store_dispose; ali@9: } ali@9: ali@9: GtkTreeModel *plover_local_media_store_new(void) ali@9: { ali@9: return g_object_new(PLOVER_TYPE_LOCAL_MEDIA_STORE,NULL); ali@9: } ali@9: ali@9: static void local_media_scan_mount(PloverLocalMediaStore *store,GMount *mount) ali@9: { ali@9: GFile *root; ali@9: gchar *path; ali@9: PloverPackageSet *set; ali@9: root=g_mount_get_root(mount); ali@9: path=g_file_get_path(root); ali@9: if (path) ali@9: { ali@9: set=plover_package_set_new_from_repository(path,NULL); ali@9: if (set) ali@9: { ali@9: g_object_set_data(G_OBJECT(mount),"plover-local-media-set",set); ali@9: plover_package_store_add_set(PLOVER_PACKAGE_STORE(store),set); ali@9: g_object_ref(mount); ali@9: } ali@9: g_free(path); ali@9: } ali@9: g_object_unref(root); ali@9: } ali@9: ali@9: static void local_media_mounted(GObject *source,GAsyncResult *res,gpointer data) ali@9: { ali@9: GVolume *volume=G_VOLUME(source); ali@9: GMount *mount; ali@9: PloverLocalMediaStore *store=PLOVER_LOCAL_MEDIA_STORE(data); ali@9: if (g_volume_mount_finish(volume,res,NULL)) ali@9: { ali@9: mount=g_volume_get_mount(volume); ali@9: if (mount) ali@9: { ali@9: local_media_scan_mount(store,mount); ali@9: g_object_unref(mount); ali@9: } ali@9: } ali@9: g_object_unref(volume); ali@9: } ali@9: ali@9: static void local_media_scan_drive(PloverLocalMediaStore *store,GDrive *drive) ali@9: { ali@9: GVolume *volume; ali@9: GMount *mount; ali@9: GList *volumes,*link; ali@9: if (g_drive_has_media(drive)) ali@9: { ali@9: volumes=g_drive_get_volumes(drive); ali@9: for(link=volumes;link;link=link->next) ali@9: { ali@9: volume=G_VOLUME(link->data); ali@9: mount=g_volume_get_mount(volume); ali@9: if (mount) ali@9: { ali@9: local_media_scan_mount(store,mount); ali@9: g_object_unref(mount); ali@9: } ali@9: else if (!store->implicit_scan && g_volume_can_mount(volume)) ali@9: g_volume_mount(volume,G_MOUNT_MOUNT_NONE,NULL,NULL, ali@9: local_media_mounted,store); ali@9: g_object_unref(volume); ali@9: } ali@9: g_list_free(volumes); ali@9: } ali@9: } ali@9: ali@9: static void local_media_polled(GObject *source,GAsyncResult *res,gpointer data) ali@9: { ali@9: GDrive *drive=G_DRIVE(source); ali@9: PloverLocalMediaStore *store=PLOVER_LOCAL_MEDIA_STORE(data); ali@9: if (g_drive_poll_for_media_finish(drive,res,NULL)) ali@9: local_media_scan_drive(store,drive); ali@9: g_object_unref(drive); ali@9: } ali@9: ali@9: void plover_local_media_store_scan(PloverLocalMediaStore *store) ali@9: { ali@9: GList *drives,*link; ali@9: GDrive *drive; ali@9: g_return_if_fail(PLOVER_IS_LOCAL_MEDIA_STORE(store)); ali@9: drives=g_volume_monitor_get_connected_drives(store->monitor); ali@9: for(link=drives;link;link=link->next) ali@9: { ali@9: drive=G_DRIVE(link->data); ali@9: if (g_drive_is_media_removable(drive)) ali@9: { ali@9: if (!g_drive_is_media_check_automatic(drive) && ali@9: g_drive_can_poll_for_media(drive) || ali@9: !g_drive_has_media(drive) && !store->implicit_scan) ali@9: { ali@9: g_object_ref(drive); ali@9: g_drive_poll_for_media(drive,NULL,local_media_polled,store); ali@9: } ali@9: else ali@9: local_media_scan_drive(store,drive); ali@9: } ali@9: g_object_unref(drive); ali@9: } ali@9: g_list_free(drives); ali@9: } ali@9: ali@9: static void local_media_mount_added(GVolumeMonitor *volume_monitor, ali@9: GMount *mount,PloverLocalMediaStore *store) ali@9: { ali@9: local_media_scan_mount(store,mount); ali@9: } ali@9: ali@9: static void local_media_mount_removed(GVolumeMonitor *volume_monitor, ali@9: GMount *mount,PloverLocalMediaStore *store) ali@9: { ali@9: PloverPackageSet *set= ali@9: g_object_get_data(G_OBJECT(mount),"plover-local-media-set"); ali@9: if (set) ali@9: { ali@9: plover_package_store_remove_set(PLOVER_PACKAGE_STORE(store),set); ali@9: g_object_set_data(G_OBJECT(mount),"plover-local-media-set",NULL); ali@9: g_object_unref(set); ali@9: g_object_unref(mount); ali@9: } ali@9: } ali@9: ali@9: static void local_media_mount_changed(GVolumeMonitor *volume_monitor, ali@9: GMount *mount,PloverLocalMediaStore *store) ali@9: { ali@9: local_media_mount_removed(volume_monitor,mount,store); ali@9: local_media_mount_added(volume_monitor,mount,store); ali@9: } ali@9: ali@9: static void plover_local_media_store_init(PloverLocalMediaStore *store) ali@9: { ali@9: store->monitor=g_volume_monitor_get(); ali@9: store->implicit_scan=TRUE; ali@9: plover_local_media_store_scan(store); ali@9: store->implicit_scan=FALSE; ali@9: g_signal_connect(store->monitor,"mount-added", ali@9: G_CALLBACK(local_media_mount_added),store); ali@9: g_signal_connect(store->monitor,"mount-changed", ali@9: G_CALLBACK(local_media_mount_changed),store); ali@9: g_signal_connect(store->monitor,"mount-removed", ali@9: G_CALLBACK(local_media_mount_removed),store); ali@9: }