new plugin : xfce4-mount-plugin

Mario Streiber <[email protected]>
Newsgroups gmane.comp.desktop.xfce.goodies.devel
Message-ID <[email protected]>
Hi Jean-Baptiste,


this is really a useful plugin. What I missed right from the start is
that the list of devices is static, so e.g. a hotplugged USB stick
will not show up in the menu. The only thing that gets updated is the
disk statistics.

I just changed mount-plugin.c so that each time you click on the
panel button the complete menu is rebuilt from fstab, and I'd like to
share that feature, so I attached the changed file.

I hope someone else will find that useful as well.


Regards
Mario
mount-plugin.c (text/plain, 10.4 KB)
/* mount-plugin.c */

/*
Copyright (C) 2005 Jean-Baptiste [email protected]

This program is free software; you can redistribute it and/or 
modify it under the terms of the GNU General Public License 
as published by the Free Software Foundation; either 
version 2 of the License, or (at your option) any later 
version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "devices.h"
#include <gtk/gtk.h>


/* for debugging */
#include <libxfce4util/debug.h>

#include <panel/xfce.h>
#include <panel/plugins.h>
#include <libxfcegui4/libxfcegui4.h>
#include "icons.h"

/*--------- graphical interface ----------*/
typedef struct 
{
	GtkWidget * button ;
	GtkWidget * menu ;
	GPtrArray * pdisks ; /* contains pointers to struct t_disk */
	GPtrArray * pdisk_display ; /*contains pointers to buttons containing t_disk_display */
} t_mounter ;
/*---------------------------------*/

typedef struct
{
	GtkWidget * menu_item ;
	GtkWidget * hbox ;
	GtkWidget * label_disk ;
	GtkWidget * label_mount_info ;
	GtkWidget * progress_bar ;
} t_disk_display ;
/*------------------------------------------------*/


/*---------------- on_release_disk_display ---------------*/
static void on_activate_disk_display(GtkWidget * widget,t_disk * disk)
{
	if (disk != NULL)
	{
		if (disk->mount_info != NULL)
		{/*disk is mounted*/
			disk_umount(disk);
			/* disk->mount_info is freed by disk_mount */
		}
		else
		{/*disk is not mounted*/
			disk_mount(disk);
			/* needs a refresh, a global refresh is done whe the window becomes visible*/
		}
	}
}

/*---------------------------------------------------------*/

/*-------------------- disk_display_new -----------------*/
/*create a new t_disk_display from t_disk infos */
static t_disk_display * disk_display_new(t_disk * disk)
{
	if (disk != NULL) 
	{
		t_disk_display * dd ;
		dd = g_new0(t_disk_display,1) ;
		dd->menu_item = gtk_menu_item_new();
		g_signal_connect(G_OBJECT(dd->menu_item),"activate",G_CALLBACK(on_activate_disk_display),disk);
		
		dd->hbox = gtk_hbox_new(FALSE,15);
		gtk_container_add(GTK_CONTAINER(dd->menu_item), dd->hbox);
		
		dd->label_disk = gtk_label_new(g_strconcat(disk->device," -> ",disk->mount_point,NULL));
		gtk_label_set_justify(GTK_LABEL(dd->label_disk),GTK_JUSTIFY_LEFT);
		gtk_box_pack_start(GTK_BOX(dd->hbox),dd->label_disk,FALSE,TRUE,0);
		
		dd->label_mount_info = gtk_label_new("");
		gtk_label_set_use_markup(GTK_LABEL(dd->label_mount_info),TRUE);
		gtk_label_set_justify(GTK_LABEL(dd->label_mount_info),GTK_JUSTIFY_RIGHT);
		gtk_box_pack_start(GTK_BOX(dd->hbox),dd->label_mount_info,TRUE,TRUE,0);
		
		dd->progress_bar = gtk_progress_bar_new();
		gtk_box_pack_start(GTK_BOX(dd->hbox),dd->progress_bar,TRUE,TRUE,0);
		return dd ;
	}
	return NULL ;
}




static void disk_display_refresh(t_disk_display * disk_display, t_mount_info * mount_info)
{
	TRACE("enters disk_display_refresh");
	if (disk_display != NULL)
	{
		if (mount_info != NULL)
		{	/* device is mounted */
			char * text ;
			char * used = get_size_human_readable(mount_info->used);
			DBG("used is now : %s",used);
			char * size = get_size_human_readable(mount_info->size);
			DBG("size is now : %s",size);
			char * avail = get_size_human_readable(mount_info->avail);
			DBG("avail is now : %s",size);
			text = g_strdup_printf("mounted on : %s \t[%s/%s] %s free", mount_info->mounted_on, used ,size,avail );
			DBG("text is now : %s",text);
			
			g_free(used);
			g_free(size);
			g_free(avail);
			//text = g_strdup_printf("mounted on : %s\t[%g Mb/%g Mb] %g Mb free",mount_info->mounted_on, mount_info->used, mount_info->size, mount_info->avail);
			gtk_label_set_text(GTK_LABEL(disk_display->label_mount_info),text);
			
			gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(disk_display->progress_bar),((gdouble)mount_info->percent / 100) );
			gtk_widget_show(GTK_WIDGET(disk_display->progress_bar));
		}
		else /* mount_info == NULL */
		{
			/*remove mount info */
			gtk_label_set_markup(GTK_LABEL(disk_display->label_mount_info),"<span foreground=\"#FF0000\">not mounted</span>");
			gtk_widget_hide(GTK_WIDGET(disk_display->progress_bar));

		}
	}
	TRACE("leaves disk_display_refresh");
}

/*---------------------- mounter_refresh ---------------*/
static void mounter_refresh(t_mounter * mounter)
{
	TRACE ("enters mounter_refresh");
	int i ;
	t_disk * disk ;
	t_disk_display * disk_display ;
	
	/* refresh pdisks structure */
	disks_refresh(mounter->pdisks);
	
	for(i=0;i < mounter->pdisks->len ;i++)
	{
		disk = g_ptr_array_index(mounter->pdisks,i); //get the disk
		disk_display = g_ptr_array_index(mounter->pdisk_display,i);
		disk_display_refresh(disk_display,disk->mount_info) ;
	}
	TRACE ("leaves mounter_refresh");
	
}
/*---------------------------------------------------------*/

/*---------------- mounter_new --------------------------*/
/* creator for t_mount_plugin */
static t_mounter * mounter_new(GtkWidget * button)
{
	TRACE ("enters mounter_new");
	t_mounter * mt ;
	int i ;
	t_disk * disk ;
	t_disk_display * disk_display ;
	
	mt = g_new0(t_mounter,1);
	
	/*get static infos from /etc/fstab */
	mt->pdisks = disks_new();
	
	/* get dynamic infos on mounts */
	disks_refresh(mt->pdisks);
	
	/* assign plugin button */
	mt->button = button;
	
	/* menu with menu_item */
	mt->menu = gtk_menu_new();
	gtk_menu_shell_append(GTK_MENU_SHELL(mt->menu),gtk_menu_item_new_with_label("Devices"));
	gtk_menu_shell_append(GTK_MENU_SHELL(mt->menu),gtk_separator_menu_item_new());
	
	mt->pdisk_display = g_ptr_array_sized_new(mt->pdisks->len) ;
	for(i=0;i < mt->pdisks->len;i++)
	{
		disk = g_ptr_array_index(mt->pdisks,i); //get the disk 
		disk_display = disk_display_new(disk) ;// creates a disk_display
		disk_display_refresh(disk_display,disk->mount_info) ;//fill in mount infos
		gtk_menu_shell_append(GTK_MENU_SHELL(mt->menu),disk_display->menu_item);//add the mnu_item to the menu
		g_ptr_array_add(mt->pdisk_display,disk_display); //add to the array
	}
	gtk_widget_show_all(mt->menu);
	
	TRACE ("leaves mounter_new");
	return mt ;
}
/*-------------------------------------------------------------*/

/*--------------- mounter_free -----------------*/
static GtkWidget * mounter_free(t_mounter * mt)
{
        TRACE ("enters mounter_free");
        GtkWidget * button = mt->button;

        disks_free(&(mt->pdisks));
        g_ptr_array_free(mt->pdisk_display,TRUE);
        mt->pdisk_display = NULL;
        gtk_widget_destroy (mt->menu);
        g_free(mt);
        TRACE ("leaves mounter_free");
        return button;
}
/*------------------------------------------------------*/

/* --------------plugin event --------------------------*/
static gboolean on_button_press(GtkWidget * widget , GdkEventButton * event,t_mounter * mounter)
{
        TRACE("enters on_button_pressed");
        if (mounter != NULL && event->button == 1)
        {
          mounter_new(mounter_free(mounter));
	  mounter_refresh(mounter); // refreshs infos regarding mounts data
          gtk_menu_popup(GTK_MENU(mounter->menu),NULL,NULL,NULL,NULL,0,event->time);
          return TRUE;
        }
        TRACE("leaves on_button_pressed");
        return FALSE ;
}
/*------------------------------------------------------*/

/*------------------- create_mounter -------------------*/
static gboolean create_mounter_control (Control * control)
{
	TRACE ("enters create_mounter_control");
	GtkWidget * button;
	GdkPixbuf * pb ;
	t_mounter * mt;

	/* create plugin button */
	pb = gdk_pixbuf_new_from_inline (sizeof(icon_plugin), icon_plugin, FALSE, NULL);
	button = xfce_iconbutton_new_from_pixbuf (pb);

	/* create data structures */
	mt = mounter_new(button);

	/* add button to the panel */
        g_signal_connect(G_OBJECT(button),"button_press_event",G_CALLBACK(on_button_press),mt);
        gtk_widget_show(button);
	gtk_container_add(GTK_CONTAINER(control->base), button);
	control->data = mt;
	TRACE ("leaves create_mounter_control");
	return TRUE;
}
/*--------------------------------------------------------*/

/*--------------- free_mounter_control ---------*/
static void free_mounter_control(Control * control)
{
        TRACE ("enters free_mounter_control");
        t_mounter * mt = (t_mounter*) control->data ;
        gtk_widget_destroy(mounter_free(mt));
        TRACE ("leaves free_mounter_control");
}
/*----------------------------------------------*/

/*--------------- mounter_attach_callback -----*/
void mounter_attach_callback(Control * control, const char *signal, GCallback callback, gpointer data)
{
        TRACE ("enters mounter_attach_callback");
        t_mounter * mounter = (t_mounter*)control->data ;

        g_signal_connect(G_OBJECT(mounter->button),signal,callback,data);
        TRACE ("leaves mounter_attach_callback");

}
/*--------------------------------------------*/

G_MODULE_EXPORT void
xfce_control_class_init (ControlClass * cc)
{
    TRACE ("enters xfce_control_class_init");
    xfce_textdomain (GETTEXT_PACKAGE, LOCALEDIR, "UTF-8");
    cc->name = "Mount-Plugin";
    cc->caption = "Mount and Display Devices";
    cc->create_control = (CreateControlFunc) create_mounter_control;
    cc->attach_callback = mounter_attach_callback;
    cc->free = free_mounter_control;

    cc->read_config = NULL;
    cc->write_config = NULL;
    cc->create_options = NULL;
    cc->set_theme = NULL;

    /* cc->set_size = NULL;
     * cc->set_orientation = NULL;
     * cc->about = NULL;
     */

    /* Additional API calls */

    /* use if there should be only one instance per screen */
    control_class_set_unique (cc, TRUE);

    /* use if the gmodule should not be unloaded *
     * (usually because of library issues)       */
    /*control_class_set_unloadable (cc, FALSE);*/

    /* use to set an icon to represent the module        *
     * (you could even update it when the theme changes) */
     /*
    if (1)
    {
	GdkPixbuf *pixbuf;

	pixbuf = xfce_icon_theme_load (xfce_icon_theme_get_for_screen (NULL),
                                       "sampleicon.png", 48);

        if (pixbuf)
        {
            control_class_set_icon (cc, pixbuf);
            g_object_unref (pixbuf);
        }
    }
    */
    TRACE ("leaves xfce_control_class_init");
    
}

/* Macro that checks panel API version */
XFCE_PLUGIN_CHECK_INIT
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.