Re: need help in plugin development....xfce4-mount-plugin

jean-baptiste dulong <[email protected]>
Newsgroups gmane.comp.desktop.xfce.goodies.devel
Message-ID <[email protected]>
great !
that should work.
thanks a lot
merci.

Olivier Fourdan a écrit :
> Hi
> ... or maybe simply using g_object_set_data()/g_object_get_data() could
> help too.
> 
> Cheers,
> Olivier.
> 
> On Wed, 2005-05-25 at 21:18 +0200, jean-baptiste dulong wrote:
> 
>>Hi,
>>I'm working on the xfce4-mount-plugin and would like to add a new 
>>functionality. I'd like the plugin to launch a command upon a 
>>successfull mount (eg: a terminal). The command won't depend on a 
>>specific device but will be a general options for the plugin.
>>Therefore I added an element in the structure that hold the plugin 
>>(Control->data) to store that command :
>>
>>typedef struct
>>{
>>	/* added string to hold command value */
>>	char * on_mount_cmd ;
>>	GtkWidget * button ;
>>	GtkWidget * menu ;
>>	GPtrArray * pdisks ;
>>	GPtrArray * pdisk_display ;
>>} t_mounter ;
>>
>>I also added a mounter_read_config and a mounter_write_config function 
>>to store and restore the option value.
>>My next step (before implementing a graphical interface for the user to 
>>change the options) is to actually use the value in on_mount_cmd when 
>>mounting a device.
>>For mounting a device, I catch an event from a menu item with this 
>>simple function :
>>
>>static void on_activate_disk_display(GtkWidget * widget,t_disk * disk)
>>{
>>	if (disk != NULL)
>>	{
>>		if (disk->mount_info != NULL)
>>		{
>>			disk_umount(disk);
>>		}
>>		else
>>		{
>>			disk_mount(disk);					 
>>/*exec_cmd_silent(g_strconcat(mt->on_mount_cmd,disk->mount_point,NULL),FALSE,TRUE);*/
>>		}
>>	}
>>}
>>And this function would love to use mt->on_mount_cmd to launch 
>>something, but we don't have access to it and the gpointer element in 
>>the callback function is already used, we need a pointer on the t_disk * 
>>disk element.
>>So is there a way to access the Control->data from some function like 
>>this one ?? Is it possible to add argument to the function with a 
>>pointer to Control->data ?? Is there a magic spell ??
>>
>>If all this doesn't sound clear at all, leave it, I'll spend my 
>>desperate nights on it... :-))
>>If the answer is trivial, it will help anyway...
>>
>>
>>plain text document attachment (mount-plugin.c)
>>/* 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 
>>{
>>	char * on_mount_cmd ;
>>	GtkWidget * button ;
>>	GtkWidget * menu ;
>>	GPtrArray * pdisks ; /* contains pointers to struct t_disk */
>>	GPtrArray * pdisk_display ; /*contains pointers to 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_activate_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*/
>>			//exec_cmd_silent(g_strconcat(mt->on_mount_cmd,disk->mount_point,NULL),FALSE,TRUE);
>>		}
>>	}
>>}
>>
>>/*---------------------------------------------------------*/
>>
>>/*-------------------- 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,10);
>>		gtk_container_add(GTK_CONTAINER(dd->menu_item), dd->hbox);
>>		
>>		dd->label_disk = gtk_label_new(g_strconcat(disk->device," -> ",disk->mount_point,NULL));
>>		/*change to uniform label size*/
>>		gtk_label_set_width_chars(GTK_LABEL(dd->label_disk),28);
>>		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("");
>>		/*change to uniform label size*/
>>		gtk_label_set_width_chars(GTK_LABEL(dd->label_mount_info),25);
>>		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 ;
>>}
>>/*-----------------------------------------------------------*/
>>
>>
>>/*-------------------- disk_display_refresh -----------------*/
>>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("[%s/%s] %s free", 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_data_free -----------------*/
>>static void mounter_data_free(t_mounter * mt)
>>{
>>	TRACE ("enters mounter_data_free");
>>	disks_free(&(mt->pdisks));
>>	g_ptr_array_free(mt->pdisk_display,TRUE);
>>	mt->pdisk_display = NULL;
>>	gtk_widget_destroy(GTK_WIDGET(mt->menu));
>>	mt->menu = NULL ;
>>	TRACE ("leaves mounter_data_free");
>>}
>>/*----------------------------------------------*/
>>
>>/*--------------- mounter_free -----------------*/
>>static void mounter_free(Control * control)
>>{
>>	TRACE ("enters mounter_free");
>>	t_mounter * mt = (t_mounter*) control->data ;
>>	mounter_data_free(mt);
>>	g_free(mt->on_mount_cmd);
>>	g_free(mt);
>>	TRACE ("leaves mounter_free");
>>}
>>/*----------------------------------------------*/
>>/*---------------- mounter_data_new --------------------------*/
>>static void mounter_data_new(t_mounter * mt)
>>{
>>	int i ;
>>	t_disk * disk ;
>>	t_disk_display * disk_display ;
>>	
>>	/*get static infos from /etc/fstab */
>>	mt->pdisks = disks_new();
>>	
>>	/* get dynamic infos on mounts */
>>	disks_refresh(mt->pdisks);
>>	
>>	/* 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);
>>	
>>	return ;
>>}
>>/*------------------------------------------------------*/
>>
>>/*---------------------- mounter_refresh ---------------*/
>>static void mounter_refresh(t_mounter * mt)
>>{
>>	TRACE ("enters mounter_refresh");
>>	
>>	mounter_data_free(mt);
>>	mounter_data_new(mt);
>>
>>	TRACE ("leaves mounter_refresh");
>>	
>>}
>>/*---------------------------------------------------------*/
>>
>>/* --------------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_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 ;
>>}
>>/*------------------------------------------------------*/
>>
>>/*---------------------- mounter_read_config --------------------*/
>>static void
>>mounter_read_config (Control * control, xmlNodePtr node)
>>{
>>    xmlChar *value;
>>    t_mounter *mt;
>>
>>    if (!node || !node->children)
>>	return;
>>
>>    mt = (t_mounter *) control->data;
>>
>>    /* on_mount_cmd */
>>
>>    value = xmlGetProp (node, (const xmlChar *) "on_mount_cmd");
>>    if (value)
>>    {
>>	g_free (mt->on_mount_cmd);
>>	mt->on_mount_cmd = (char *) value;
>>    }
>>
>>
>>}
>>/*-------------------------------------------------------*/
>>
>>/*------------------- mounter_write_config -----------------------*/
>>static void
>>mounter_write_config (Control * control, xmlNodePtr parent)
>>{
>>    char value[5];
>>    t_mounter * mt;
>>
>>    mt = (t_mounter *) control->data;
>>
>>    xmlSetProp (parent, "on_mount_cmd", mt->on_mount_cmd);
>>}
>>/*----------------------------------------------------------*/
>>
>>/*--------------- 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");
>>
>>}
>>/*--------------------------------------------*/
>>
>>/*------------------- create_mounter -------------------*/
>>static gboolean create_mounter_control (Control * control)
>>{
>>	TRACE ("enters create_mounter_control");
>>
>>	t_mounter * mounter ;
>>	
>>	mounter = g_new0(t_mounter,1);
>>
>>	/* default mount command */
>>	mounter->on_mount_cmd = "";	
>>
>>	/*plugin button */
>>	
>>	GdkPixbuf * pb ;
>>	pb = gdk_pixbuf_new_from_inline (sizeof(icon_plugin), icon_plugin, FALSE, NULL);
>>	mounter->button = xfce_iconbutton_new_from_pixbuf (pb);
>>	gtk_button_set_relief(GTK_BUTTON(mounter->button),GTK_RELIEF_NONE);
>>
>>	add_tooltip(GTK_WIDGET(mounter->button),"devices");
>>
>>	/*-------------------------------------------------------------*/
>>	g_signal_connect(G_OBJECT(mounter->button),"button_press_event",G_CALLBACK(on_button_press),mounter);
>>	gtk_widget_show(mounter->button);
>>	
>>	/*get the data*/	
>>	mounter_data_new(mounter);
>>
>>	gtk_container_add(GTK_CONTAINER(control->base), mounter->button);
>>	control->data = mounter ;
>>	TRACE ("leaves create_mounter_control");
>>	return TRUE;
>>	
>>}
>>
>>/*--------------------------------------------------------*/
>>
>>
>>
>>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/display devices";
>>    cc->create_control = (CreateControlFunc) create_mounter_control;
>>    cc->attach_callback = mounter_attach_callback;
>>    cc->free = mounter_free;
>>
>>    cc->read_config = mounter_read_config;
>>    cc->write_config = mounter_write_config;
>>    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
> 
> 
> 
> _______________________________________________
> xfce-goodies-dev mailing list
> [email protected]
> http://lists.berlios.de/mailman/listinfo/xfce-goodies-dev
> 

-- 
---------------------------------------------------
Jean-Baptiste Dulong
---------------------------------------------------
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.