Re: need help in plugin development....xfce4-mount-plugin
Olivier Fourdan <[email protected]>
| Newsgroups | gmane.comp.desktop.xfce.goodies.devel |
|---|---|
| Organization | http://www.xfce.org |
| Message-ID | <1117058055.6589.40.camel@shuttle> |
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