Properly refreshing the volume list

This commit is contained in:
Pierre Pronchery 2013-11-30 01:31:08 +01:00
parent 2dba9c00ae
commit 91bd571f40

View File

@ -40,9 +40,10 @@ enum _VolumesColumn
DC_NAME,
DC_MOUNTPOINT,
DC_FREE,
DC_FREE_DISPLAY
DC_FREE_DISPLAY,
DC_UPDATED
};
#define DC_LAST DC_FREE_DISPLAY
#define DC_LAST DC_UPDATED
#define DC_COUNT (DC_LAST + 1)
typedef enum _VolumesPixbuf
@ -116,7 +117,7 @@ static Volumes * _volumes_init(BrowserPluginHelper * helper)
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
volumes->store = gtk_list_store_new(DC_COUNT, GDK_TYPE_PIXBUF,
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT,
G_TYPE_STRING);
G_TYPE_STRING, G_TYPE_BOOLEAN);
volumes->view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(
volumes->store));
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(volumes->view), FALSE);
@ -171,6 +172,10 @@ static GtkWidget * _volumes_get_widget(Volumes * volumes)
static void _refresh_add(Volumes * volumes, char const * name,
char const * device, char const * mountpoint,
char const * filesystem, fsblkcnt_t free, fsblkcnt_t total);
static void _refresh_get_iter(Volumes * volumes, GtkTreeIter * iter,
char const * mountpoint);
static void _refresh_purge(Volumes * volumes);
static void _refresh_reset(Volumes * volumes);
static void _volumes_refresh(Volumes * volumes, GList * selection)
{
@ -195,11 +200,10 @@ static void _volumes_refresh(Volumes * volumes, GList * selection)
volumes->source = 0;
return;
}
/* FIXME no longer clear the list every time */
gtk_list_store_clear(volumes->store);
#if defined(ST_NOWAIT)
if((res = getmntinfo(&mnt, ST_NOWAIT)) <= 0)
return;
_refresh_reset(volumes);
for(i = 0; i < res; i++)
_refresh_add(volumes, NULL, mnt[i].f_mntfromname,
mnt[i].f_mntonname, mnt[i].f_fstypename,
@ -207,13 +211,16 @@ static void _volumes_refresh(Volumes * volumes, GList * selection)
#elif defined(MNT_NOWAIT)
if((res = getmntinfo(&mnt, MNT_NOWAIT)) <= 0)
return;
_refresh_reset(volumes);
for(i = 0; i < res; i++)
_refresh_add(volumes, NULL, mnt[i].f_mntfromname,
mnt[i].f_mntonname, mnt[i].f_fstypename,
mnt[i].f_bavail, mnt[i].f_blocks);
#else
_refresh_reset(volumes);
_refresh_add(volumes, NULL, NULL, "/", NULL, 0, 0);
#endif
_refresh_purge(volumes);
if(volumes->source == 0)
volumes->source = g_timeout_add(1000, _volumes_on_timeout,
volumes);
@ -230,6 +237,7 @@ static void _refresh_add(Volumes * volumes, char const * name,
char const * removable[] = { "/dev/sd" };
size_t i;
double fraction = 0.0;
int f;
char buf[16] = "";
#ifdef DEBUG
@ -262,18 +270,61 @@ static void _refresh_add(Volumes * volumes, char const * name,
{
fraction = total - free;
fraction = fraction / total;
f = fraction * 100;
snprintf(buf, sizeof(buf), "%.1lf%%", fraction * 100.0);
}
#if GTK_CHECK_VERSION(2, 6, 0)
gtk_list_store_insert_with_values(volumes->store, &iter, -1,
#else
gtk_list_store_append(volumes->store, &iter);
_refresh_get_iter(volumes, &iter, mountpoint);
gtk_list_store_set(volumes->store, &iter,
#endif
DC_PIXBUF, volumes->icons[dp], DC_NAME, name,
DC_MOUNTPOINT, mountpoint,
DC_FREE, (int)(fraction * 100), DC_FREE_DISPLAY, buf,
-1);
DC_MOUNTPOINT, mountpoint, DC_FREE, f,
DC_FREE_DISPLAY, buf, DC_UPDATED, TRUE, -1);
}
static void _refresh_get_iter(Volumes * volumes, GtkTreeIter * iter,
char const * mountpoint)
{
GtkTreeModel * model = GTK_TREE_MODEL(volumes->store);
gboolean valid;
gchar * p;
int res;
for(valid = gtk_tree_model_get_iter_first(model, iter); valid == TRUE;
valid = gtk_tree_model_iter_next(model, iter))
{
gtk_tree_model_get(model, iter, DC_MOUNTPOINT, &p, -1);
res = strcmp(mountpoint, p);
g_free(p);
if(res == 0)
return;
}
gtk_list_store_append(volumes->store, iter);
}
static void _refresh_purge(Volumes * volumes)
{
GtkTreeModel * model = GTK_TREE_MODEL(volumes->store);
GtkTreeIter iter;
gboolean valid;
gboolean updated;
for(valid = gtk_tree_model_get_iter_first(model, &iter); valid == TRUE;)
{
gtk_tree_model_get(model, &iter, DC_UPDATED, &updated, -1);
valid = updated ? gtk_tree_model_iter_next(model, &iter)
: gtk_list_store_remove(volumes->store, &iter);
}
}
static void _refresh_reset(Volumes * volumes)
{
GtkTreeModel * model = GTK_TREE_MODEL(volumes->store);
GtkTreeIter iter;
gboolean valid;
for(valid = gtk_tree_model_get_iter_first(model, &iter); valid == TRUE;
valid = gtk_tree_model_iter_next(model, &iter))
gtk_list_store_set(volumes->store, &iter, DC_UPDATED, FALSE,
-1);
}