listplugins.C

Go to the documentation of this file.
00001 /* Gnome gxsm - Gnome X Scanning Microscopy
00002  * universal STM/AFM/SARLS/SPALEED/... controlling and
00003  * data analysis software
00004  * 
00005  * Gxsm Plugin Name: listplugins.C
00006  * ========================================
00007  * 
00008  * Copyright (C) 1999 The Free Software Foundation
00009  *
00010  * Authors: Percy Zahl <zahl@fkp.uni-hannover.de>
00011  * additional features: Andreas Klust <klust@fkp.uni-hannover.de>
00012  *
00013  * This program is free software; you can redistribute it and/or modify
00014  * it under the terms of the GNU General Public License as published by
00015  * the Free Software Foundation; either version 2 of the License, or
00016  * (at your option) any later version.
00017  *
00018  * This program is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License
00024  * along with this program; if not, write to the Free Software
00025  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00026  */
00027 
00028 
00029 /* Please do not change the Begin/End lines of this comment section!
00030  * this is a LaTeX style section used for auto generation of the PlugIn Manual 
00031  * Chapter. Add a complete PlugIn documentation inbetween the Begin/End marks!
00032  * --------------------------------------------------------------------------------
00033 % BeginPlugInDocuSection
00034 % PlugInDocuCaption: Show plug-in details
00035 % PlugInName: listplugins
00036 % PlugInAuthor: Percy Zahl
00037 % PlugInAuthorEmail: zahl@users.sf.net
00038 % PlugInMenuPath: Tools/Plugin Details
00039 
00040 % PlugInDescription
00041 \label{plugin:listplugins}
00042 This plugin lists all currently loaded plugins and shows all available
00043 information about those.  In addition, it allows to call/run the About and
00044 Configure subroutines of each plugin -- if available. 
00045 
00046 % PlugInUsage
00047 Call it using the menu \GxsmMenu{Tools/Plugin Details}.
00048 
00049 %% OptPlugInKnownBugs
00050 %No known.
00051 
00052 % EndPlugInDocuSection
00053  * -------------------------------------------------------------------------------- 
00054  */
00055 
00056 
00057 #include <gtk/gtk.h>
00058 #include "config.h"
00059 #include "gxsm/plugin.h"
00060 
00061 // ===========================================
00062 // borrowed from gimp "pluginsdetails" PlugIn
00063 // ===========================================
00064 
00065 #define DBL_LIST_WIDTH  250
00066 #define DBL_WIDTH       (DBL_LIST_WIDTH + 300)
00067 #define DBL_HEIGHT      200
00068 
00069 typedef struct  
00070 {
00071   GtkWidget *dlg;
00072   GtkWidget *clist;
00073   GtkWidget *ctree;
00074   GtkWidget *search_entry;
00075   GtkWidget *descr_scroll;
00076   GtkWidget *name_button;
00077   GtkWidget *blurb_button;
00078   GtkWidget *scrolled_win;
00079   GtkWidget *ctree_scrolled_win;
00080   GtkWidget *info_table;
00081   GtkWidget *paned;
00082   GtkWidget *left_paned;
00083   GtkWidget *info_align;
00084   gint       num_plugins;
00085   gint       ctree_row;
00086   gint       clist_row;
00087   gint       c1size;
00088   gboolean   details_showing;
00089 } PDesc;
00090 
00091 PDesc *plugindesc = NULL;
00092 
00093 static void 
00094 dialog_search_callback (GnomeDialog *dlg, 
00095                         gpointer   data);
00096 static gint 
00097 procedure_clist_select_callback (GtkWidget      *widget,
00098                                  gint            row, 
00099                                  gint            column, 
00100                                  GdkEventButton *bevent,
00101                                  gpointer        data);
00102 static gint 
00103 procedure_ctree_select_callback (GtkWidget      *widget,
00104                                  GtkWidget      *row, 
00105                                  gint            column, 
00106                                  gpointer        data);
00107 static void 
00108 clist_click_column (GtkCList *clist, 
00109                     gint      column, 
00110                     gpointer  data);
00111 static gint 
00112 name_sort (GtkCList      *clist,
00113            gconstpointer  ptr1,
00114            gconstpointer  ptr2);
00115 static void 
00116 insert_into_ctree (PDesc      *pdesc,
00117                    gchar      *name,
00118                    gchar      *xtimestr,
00119                    gchar      *menu_str,
00120                    gchar      *types_str,
00121                    GHashTable *ghash,
00122                    GxsmPlugin      *GPlugin);
00123 static void
00124 get_plugin_info (PDesc *pdesc,
00125                  const gchar *search_text);
00126 static gint 
00127 page_select_callback (GtkNotebook     *notebook,
00128                       GtkNotebookPage *page,
00129                       guint            page_num,
00130                       gpointer         data);
00131 static gchar *
00132 format_menu_path (gchar *s);
00133 
00134 static void
00135 details_callback (GtkWidget *widget, 
00136                   gpointer   data);
00137 
00138 static void
00139 exec_callback (GtkWidget *widget, 
00140                gpointer   data);
00141 
00142 
00143 // ========================================
00144 // Gxsm PlugIn Setup Part
00145 // ========================================
00146 
00147 static void listplugins_about( void );
00148 static void listplugins_run(GtkWidget *w, void *data);
00149 static void listplugins_cleanup( void );
00150 void List_GxsmPlugins( void );
00151 
00152 GxsmPlugin listplugins_pi = {
00153   NULL,
00154   NULL,
00155   0,
00156   NULL,
00157   "GxsmPlugindetails",
00158   NULL,
00159   NULL,
00160   "Some code from Andy Thomas's Gimp Plugin: \"plugin details\",\n"
00161   "Gxsm Version by Percy Zahl",
00162   N_("_Tools/"),
00163   N_("Plugin Details"),
00164   N_("List/Configure available Gxsm Plugins"),
00165   "no more info",
00166   NULL,
00167   NULL,
00168   NULL,
00169   NULL,
00170   listplugins_about,
00171   NULL,
00172   listplugins_run,
00173   listplugins_cleanup
00174 };
00175 
00176 static const char *about_text = N_("Plugin Control for Gxsm:\n\n"
00177                                    "- View Gxsm-Plugin details and status\n"
00178                                    "- Call plugins About or Configurationfunction\n"
00179                                    "Plugin written in inspiration of \"The Gimp\" - Plugin Details:\n"
00180                                    "Displays plugin details"
00181                                    "Helps browse the plugin menus system. You can "
00182                                    "search for plugin names, sort by name or menu "
00183                                    "location and you can view a tree representation "
00184                                    "of the plugin menus. Can also be of help to find "
00185                                    "where new plugins have installed themselves in "
00186                                    "the menuing system"
00187                                    );
00188 
00189 
00190 GxsmPlugin *get_gxsm_plugin_info ( void ){ 
00191   listplugins_pi.description = g_strdup_printf(N_("Gxsm Plugin Details %s"), VERSION);
00192   return &listplugins_pi; 
00193 }
00194 
00195 static void listplugins_about(void)
00196 {
00197   const gchar *authors[] = { "Percy Zahl", "Andy Thomas, (Gimp: Plugin Details)", NULL};
00198   gtk_widget_show(gnome_about_new ( listplugins_pi.name,
00199                                     VERSION,
00200                                     N_("(C) 2000 the Free Software Foundation"),
00201                                     about_text,
00202                                     authors,
00203                                     NULL, NULL, NULL
00204                                     ));
00205 }
00206 
00207 static void listplugins_run(GtkWidget *w, void *data)
00208 {
00209   if(listplugins_pi.app){
00210     if(listplugins_pi.app->GxsmPlugins)
00211       List_GxsmPlugins();
00212     else
00213       listplugins_pi.app->message("Sorry, no Gxsm Plugins to list!");
00214   }
00215   else
00216           PI_DEBUG (DBG_L2, "Listplugins Plugin Run, sorry no Application Class available!" );
00217 }
00218 
00219 static void listplugins_cleanup( void ){
00220   if( plugindesc ){
00221     if( plugindesc->dlg )
00222       gnome_dialog_close( GNOME_DIALOG (plugindesc->dlg) );
00223     g_free( plugindesc );
00224     plugindesc = NULL;
00225   }
00226   while(gtk_events_pending()) gtk_main_iteration();
00227 }
00228 
00229 GtkWidget* create_GxsmPluginList (void);
00230 
00231 void List_GxsmPlugins( void )
00232 {
00233   GtkWidget *Dlg = create_GxsmPluginList ();
00234   gtk_widget_show (Dlg);
00235 }
00236 
00237 
00238 // ===================================================================================
00239 // code borrowed from gimp "pluginsdetails" PlugIn, modified for Gxsm PlugIns...
00240 // ===================================================================================
00241 
00242 static void dialog_clicked_cb(GnomeDialog * dialog, gint button_number, PDesc *p){
00243   switch(button_number){
00244   case 0:  dialog_search_callback(dialog, p); break;
00245   case 1:  listplugins_cleanup(); break;
00246   default: g_assert_not_reached();
00247   }
00248 }
00249 
00250 GtkWidget* create_GxsmPluginList ( void )
00251 {
00252   GtkWidget  *button;
00253   GtkWidget  *hbox, *searchhbox, *vbox;
00254   GtkWidget  *label, *notebook, *swindow;
00255   gchar      *clabels[4];
00256 
00257   plugindesc = g_new0 (PDesc, 1);
00258 
00259   /* the dialog box */
00260   plugindesc->dlg = gnome_dialog_new (_("Plugin Descriptions"), NULL);
00261   gtk_window_set_policy (GTK_WINDOW (plugindesc->dlg), TRUE, TRUE, FALSE);
00262   gnome_dialog_set_close(GNOME_DIALOG(plugindesc->dlg), FALSE);
00263   gnome_dialog_close_hides(GNOME_DIALOG(plugindesc->dlg), FALSE);
00264   gnome_dialog_set_default(GNOME_DIALOG(plugindesc->dlg), 0);
00265 
00266   GtkWidget *dialog_action_area = GNOME_DIALOG (plugindesc->dlg)->action_area;
00267   gtk_widget_show (dialog_action_area);
00268   gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area), GTK_BUTTONBOX_END);
00269   gtk_button_box_set_spacing (GTK_BUTTON_BOX (dialog_action_area), 8);
00270 
00271   gnome_dialog_append_button (GNOME_DIALOG (plugindesc->dlg), GNOME_STOCK_BUTTON_APPLY);
00272   GtkWidget *button1 = GTK_WIDGET (g_list_last (GNOME_DIALOG (plugindesc->dlg)->buttons)->data);
00273   gtk_widget_show (button1);
00274   GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
00275 
00276   gnome_dialog_append_button (GNOME_DIALOG (plugindesc->dlg), GNOME_STOCK_BUTTON_CANCEL);
00277   GtkWidget *button2 = GTK_WIDGET (g_list_last (GNOME_DIALOG (plugindesc->dlg)->buttons)->data);
00278   gtk_widget_show (button2);
00279   GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
00280 
00281   gtk_signal_connect(GTK_OBJECT(plugindesc->dlg), "clicked",
00282                      GTK_SIGNAL_FUNC(dialog_clicked_cb),
00283                      plugindesc);
00284 
00285   plugindesc->details_showing = FALSE;
00286 
00287   /* hbox : left=notebook ; right=description */
00288   
00289   plugindesc->paned = hbox = gtk_hpaned_new ();
00290 
00291   gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (plugindesc->dlg)->vbox), 
00292                       hbox, TRUE, TRUE, 0);
00293   gtk_widget_show (hbox);
00294 
00295 //  gtk_paned_set_handle_size (GTK_PANED (hbox), 0);
00296   gtk_paned_set_gutter_size (GTK_PANED (hbox), 0);
00297 
00298   /* left = vbox : the list and the search entry */
00299   
00300   plugindesc->left_paned = vbox = gtk_vbox_new (FALSE, 0);
00301   gtk_container_set_border_width (GTK_CONTAINER (vbox), 3); 
00302   gtk_paned_pack1 (GTK_PANED (hbox), vbox, FALSE, FALSE);
00303   gtk_widget_show (vbox);
00304 
00305   /* left = notebook */
00306 
00307   notebook = gtk_notebook_new ();
00308   gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
00309 
00310   /* list : list in a scrolled_win */
00311   
00312   clabels[0] = g_strdup (_("Menu Path")); 
00313   clabels[1] = g_strdup (_("Entry")); 
00314   clabels[2] = g_strdup (_("Name")); 
00315   clabels[3] = g_strdup (_("Type")); 
00316   plugindesc->clist = gtk_clist_new_with_titles (4, clabels); 
00317   g_free(clabels[3]);
00318   g_free(clabels[2]);
00319   g_free(clabels[1]);
00320   g_free(clabels[0]);
00321 
00322 
00323   gtk_signal_connect (GTK_OBJECT (plugindesc->clist), "click_column",
00324                       GTK_SIGNAL_FUNC (clist_click_column),
00325                       NULL);
00326   gtk_clist_column_titles_show (GTK_CLIST (plugindesc->clist));
00327   swindow = gtk_scrolled_window_new (NULL, NULL);
00328   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
00329                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
00330   gtk_clist_set_selection_mode (GTK_CLIST (plugindesc->clist),
00331                                 GTK_SELECTION_BROWSE);
00332 
00333   gtk_widget_set_usize (plugindesc->clist, DBL_LIST_WIDTH, DBL_HEIGHT);
00334   gtk_signal_connect (GTK_OBJECT (plugindesc->clist), "select_row",
00335                       GTK_SIGNAL_FUNC (procedure_clist_select_callback),
00336                       plugindesc);
00337   
00338   label = gtk_label_new (_("List View"));
00339   gtk_notebook_append_page (GTK_NOTEBOOK (notebook), swindow, label);
00340   gtk_container_add (GTK_CONTAINER (swindow), plugindesc->clist);
00341   gtk_widget_show (plugindesc->clist);
00342   gtk_widget_show (swindow);
00343 
00344   /* notebook->ctree */
00345   clabels[0] = g_strdup (_("Menu Path/Name")); 
00346   clabels[1] = g_strdup (_("Name")); 
00347   clabels[2] = g_strdup (_("Type")); 
00348   plugindesc->ctree = gtk_ctree_new_with_titles (3, 0, clabels);  
00349   g_free(clabels[2]);
00350   g_free(clabels[1]);
00351   g_free(clabels[0]);
00352 
00353   plugindesc->ctree_scrolled_win =
00354     swindow = gtk_scrolled_window_new (NULL, NULL);
00355   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
00356                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
00357   gtk_widget_set_usize (plugindesc->ctree, DBL_LIST_WIDTH, DBL_HEIGHT);
00358   gtk_signal_connect (GTK_OBJECT (plugindesc->ctree), "tree_select_row",
00359                       GTK_SIGNAL_FUNC (procedure_ctree_select_callback),
00360                       plugindesc);
00361   gtk_clist_set_column_auto_resize (GTK_CLIST (plugindesc->ctree), 0, TRUE);
00362   gtk_clist_set_column_auto_resize (GTK_CLIST (plugindesc->ctree), 1, TRUE);
00363   gtk_clist_set_column_auto_resize (GTK_CLIST (plugindesc->ctree), 2, TRUE);
00364   gtk_clist_column_titles_passive (GTK_CLIST (plugindesc->ctree));
00365 
00366   label = gtk_label_new (_("Tree View"));
00367   gtk_notebook_append_page (GTK_NOTEBOOK (notebook), swindow, label);
00368   gtk_container_add (GTK_CONTAINER (swindow), plugindesc->ctree);
00369 
00370   gtk_widget_show (plugindesc->ctree);
00371   gtk_widget_show (swindow);
00372 
00373   gtk_signal_connect_after (GTK_OBJECT (notebook), "switch_page",
00374                             GTK_SIGNAL_FUNC (page_select_callback),
00375                             plugindesc);
00376   
00377   gtk_widget_show (notebook);
00378 
00379   /* search entry & details button */
00380 
00381   searchhbox = gtk_hbox_new (FALSE, 4);
00382   gtk_box_pack_start (GTK_BOX (vbox),
00383                       searchhbox, FALSE, FALSE, 0);
00384   gtk_widget_show (searchhbox);
00385 
00386   label = gtk_label_new (_("Search:"));
00387   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
00388   gtk_box_pack_start (GTK_BOX (searchhbox), 
00389                       label, FALSE, FALSE, 0);
00390   gtk_widget_show(label);
00391 
00392   plugindesc->search_entry = gtk_entry_new ();
00393   gtk_box_pack_start (GTK_BOX (searchhbox), 
00394                       plugindesc->search_entry, TRUE, TRUE, 0);
00395   gtk_widget_show (plugindesc->search_entry);
00396 
00397   button = gtk_button_new_with_label (_("Details >>"));
00398   gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child), 2, 0);
00399   gtk_signal_connect (GTK_OBJECT (button), "clicked",
00400                       GTK_SIGNAL_FUNC (details_callback),
00401                       plugindesc);
00402   gtk_box_pack_start (GTK_BOX (searchhbox), button,
00403                       FALSE, FALSE, 0);
00404   gtk_widget_show (button);
00405 
00406   /* right = description */
00407   /* the right description is build on first click of the Details button */
00408  
00409   /* now build the list */
00410   dialog_search_callback (NULL, (gpointer) plugindesc);
00411 
00412   gtk_clist_set_selection_mode (GTK_CLIST (plugindesc->ctree),
00413                                 GTK_SELECTION_BROWSE);
00414 
00415   gtk_widget_show (plugindesc->clist); 
00416   gtk_widget_show (plugindesc->dlg);
00417   
00418   gtk_clist_select_row (GTK_CLIST (plugindesc->clist), 0, 0);
00419   gtk_clist_moveto (GTK_CLIST (plugindesc->clist), 0, 0, 0.0, 0.0);
00420 
00421   plugindesc->c1size = GTK_PANED (plugindesc->paned)->child1_size;
00422   GTK_PANED (plugindesc->paned)->child1_resize = TRUE;
00423 
00424   return plugindesc->dlg;
00425 }
00426 
00427 
00428 
00429 /* Bit of a fiddle but sorta has the effect I want... */
00430 
00431 static void
00432 details_callback (GtkWidget *widget, 
00433                   gpointer   data)
00434 {
00435   /* Show or hide the details window */ 
00436   PDesc *pdesc = (PDesc *)data;
00437   GtkLabel *lab = GTK_LABEL (GTK_BIN (widget)->child);
00438 
00439   /* This is a lame hack: 
00440      We add the description on the right on the first details_callback.
00441      Otherwise the window reacts quite weird on resizes */
00442   if (pdesc->descr_scroll == NULL)
00443     {
00444       pdesc->descr_scroll = gtk_scrolled_window_new (NULL, NULL);
00445       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pdesc->descr_scroll),
00446                                       GTK_POLICY_ALWAYS, 
00447                                       GTK_POLICY_ALWAYS);
00448       gtk_widget_set_usize (pdesc->descr_scroll, DBL_WIDTH - DBL_LIST_WIDTH, -1);
00449       gtk_paned_pack2 (GTK_PANED (pdesc->paned), pdesc->descr_scroll,
00450                        FALSE, TRUE);
00451       gtk_clist_select_row (GTK_CLIST(pdesc->clist), pdesc->clist_row, -1);
00452     }
00453 
00454   if (pdesc->details_showing == FALSE)
00455     {
00456       GTK_PANED (pdesc->paned)->child1_resize = FALSE;
00457       gtk_paned_set_gutter_size (GTK_PANED (pdesc->paned), 6);
00458       gtk_label_set_text (lab, _("Details <<"));
00459       gtk_widget_show (pdesc->descr_scroll);
00460       pdesc->details_showing = TRUE;
00461     }
00462   else
00463     {
00464       GtkWidget *p = GTK_WIDGET (pdesc->paned)->parent;
00465       GTK_PANED (pdesc->paned)->child1_resize = TRUE;
00466       GTK_PANED (pdesc->paned)->child2_resize = TRUE;
00467       gtk_paned_set_gutter_size (GTK_PANED (pdesc->paned), 0);
00468       gtk_label_set_text (lab, _("Details >>"));
00469       gtk_widget_hide (pdesc->descr_scroll);
00470       gtk_paned_set_position (GTK_PANED (pdesc->paned),
00471                               p->allocation.width);/*plugindesc->c1size);*/
00472       pdesc->details_showing = FALSE;
00473     }
00474 }
00475 
00476 static gchar *
00477 format_menu_path (gchar *s)
00478 {
00479   gchar **str_array;
00480   gchar  *newstr = NULL;
00481 
00482   if (!s)
00483     return s;
00484 
00485   str_array = g_strsplit (s, "/", 0);
00486 
00487   newstr = g_strjoinv ("->", str_array);
00488 
00489   g_strfreev (str_array);
00490 
00491   return newstr;
00492 }
00493 
00494 static int add_GxsmPluginInfo(int table_row, PDesc *pdesc, const gchar *Label, const gchar *value){
00495   gchar *Value = NULL;
00496   GtkWidget *label;
00497 
00498   if(value)
00499     Value = g_strdup(value);
00500   else
00501     Value = g_strdup("--");
00502 
00503   if(strlen(Value) < 40){
00504 
00505     label = gtk_label_new (Label);
00506     gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); 
00507     gtk_table_attach (GTK_TABLE (pdesc->info_table), label,
00508                       0, 1, table_row, table_row+1, GTK_FILL, GTK_FILL, 3, 6);
00509     gtk_widget_show(label);
00510     
00511     label = gtk_entry_new ();
00512     gtk_entry_set_text (GTK_ENTRY (label), Value);
00513     gtk_entry_set_editable (GTK_ENTRY (label), FALSE);
00514     gtk_table_attach (GTK_TABLE(pdesc->info_table), label,
00515                       1, strlen(Value)<10 ? 2:4, table_row, table_row+1, GTK_FILL, GTK_FILL, 0, 0);
00516     gtk_widget_show (label);
00517   }
00518   else{
00519     GtkWidget *text;
00520     GtkWidget *help;
00521     GtkWidget *vscrollbar;
00522 
00523     label = gtk_label_new (Label);
00524     gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); 
00525     gtk_table_attach (GTK_TABLE (pdesc->info_table), label,
00526                       0, 1, table_row, table_row+1, 
00527                       GTK_FILL, GTK_FILL, 3, 0);
00528     gtk_widget_show (label);
00529     
00530     help = gtk_table_new (2, 2, FALSE);
00531     gtk_table_set_row_spacing (GTK_TABLE (help), 0, 2);
00532     gtk_table_set_col_spacing (GTK_TABLE (help), 0, 2);
00533     gtk_table_attach (GTK_TABLE (pdesc->info_table), help,
00534                       1, 4, table_row, table_row+1, GTK_FILL, GTK_FILL, 3, 0);
00535     gtk_widget_show (help);
00536     table_row++;
00537     
00538     text = gtk_text_view_new ();
00539 //    gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (text), GTK_TEXT_WINDOW_LEFT, 2);
00540 //    gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (text), GTK_TEXT_WINDOW_RIGHT, 2);
00541 //    gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (text), GTK_TEXT_WINDOW_TOP, 2);
00542 //    gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (text), GTK_TEXT_WINDOW_BOTTOM, 2);
00543     gtk_text_view_set_editable (GTK_TEXT_VIEW (text), FALSE);
00544     gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text), GTK_WRAP_WORD);
00545 
00546     gtk_widget_set_usize (text, -1, 60);
00547     gtk_table_attach (GTK_TABLE (help), text, 0, 1, 0, 1,
00548                       (GtkAttachOptions)(GTK_EXPAND | GTK_SHRINK | GTK_FILL),
00549                       (GtkAttachOptions)(GTK_EXPAND | GTK_SHRINK | GTK_FILL), 
00550                       0, 0);
00551     gtk_widget_show (text);
00552     
00553     label = gtk_hseparator_new (); /* ok, not really a label ... :) */
00554     gtk_table_attach (GTK_TABLE (pdesc->info_table), label,
00555                       0, 4, table_row, table_row+1, GTK_FILL, GTK_FILL, 3, 6);
00556     gtk_text_buffer_set_text (GTK_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text))), Value, -1);
00557     gtk_widget_show(label);
00558   }
00559 
00560   g_free(Value);
00561 
00562   return ++table_row;
00563 }
00564 
00565 static void
00566 exec_callback (GtkWidget *widget, 
00567                gpointer   data){
00568   void (*run)(void) = (void (*)(void)) data;
00569   run();
00570 }
00571 
00572 static gint
00573 procedure_general_select_callback (PDesc *pdesc,
00574                                    GxsmPlugin *GPlugin)
00575 {
00576   GtkWidget *label, *button;
00577   GtkWidget *old_table;
00578   GtkWidget *old_align;
00579   gint       table_row = 0;
00580   gchar     *str;
00581 
00582   g_return_val_if_fail (pdesc != NULL, FALSE);
00583   g_return_val_if_fail (GPlugin != NULL, FALSE);
00584 
00585   if (pdesc->descr_scroll == NULL)
00586     return FALSE;
00587 
00588   old_table = pdesc->info_table;
00589   old_align = pdesc->info_align;
00590 
00591   pdesc->info_table = gtk_table_new (10, 5, FALSE);
00592   pdesc->info_align = gtk_alignment_new (0.5, 0.5, 0, 0);
00593 
00594   gtk_table_set_col_spacings (GTK_TABLE (pdesc->info_table), 3);
00595 
00596   /* Number of plugins */
00597 
00598   str = g_strdup_printf (_("Number of Plugin Interfaces: %d"),
00599                          pdesc->num_plugins);
00600   label = gtk_label_new (str);
00601   g_free (str);
00602   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
00603   gtk_table_attach (GTK_TABLE (pdesc->info_table), label,
00604                     0, 4, table_row, table_row+1, GTK_FILL, GTK_FILL, 0, 0);
00605   gtk_widget_show (label);
00606   table_row++;
00607 
00608   label = gtk_hseparator_new (); /* ok, not really a label ... :) */
00609   gtk_table_attach (GTK_TABLE (pdesc->info_table), label,
00610                     0, 4, table_row, table_row+1, GTK_FILL, GTK_FILL, 3, 6);
00611   gtk_widget_show (label);
00612   table_row++;
00613 
00614   /* menu path */
00615 
00616   label = gtk_label_new (_("Menu Path:"));
00617   gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); 
00618   gtk_table_attach (GTK_TABLE (pdesc->info_table), label,
00619                     0, 1, table_row, table_row+1, GTK_FILL, GTK_FILL, 3, 0);
00620   gtk_widget_show(label);
00621 
00622   gchar *mp = g_strconcat(GPlugin->menupath, GPlugin->menuentry, NULL);
00623   gchar *fmp = format_menu_path (mp);
00624   label = gtk_label_new (fmp);
00625   g_free(fmp);
00626   g_free(mp);
00627   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
00628   gtk_table_attach (GTK_TABLE (pdesc->info_table), label,
00629                     1, 4, table_row, table_row+1, GTK_FILL, GTK_FILL, 0, 0);
00630   gtk_widget_show (label);
00631   table_row++;
00632 
00633   label = gtk_hseparator_new (); /* ok, not really a label ... :) */
00634   gtk_table_attach (GTK_TABLE (pdesc->info_table), label,
00635                     0, 4, table_row, table_row+1, GTK_FILL, GTK_FILL, 3, 6);
00636   gtk_widget_show (label);
00637   table_row++;
00638 
00639   /* show GxsmPlugin Infos */
00640 
00641   table_row = add_GxsmPluginInfo(table_row, pdesc, N_("Plugin"), GPlugin->filename);
00642   table_row = add_GxsmPluginInfo(table_row, pdesc, N_("Name"), GPlugin->name);
00643   table_row = add_GxsmPluginInfo(table_row, pdesc, N_("Description"), GPlugin->description);
00644   table_row = add_GxsmPluginInfo(table_row, pdesc, N_("Category"), GPlugin->category 
00645                                  ? GPlugin->category : N_("(NULL): All"));
00646   table_row = add_GxsmPluginInfo(table_row, pdesc, N_("Authors"), GPlugin->authors);
00647   table_row = add_GxsmPluginInfo(table_row, pdesc, N_("Help"), GPlugin->help);
00648   table_row = add_GxsmPluginInfo(table_row, pdesc, N_("Info"), GPlugin->info);
00649   table_row = add_GxsmPluginInfo(table_row, pdesc, N_("Error"), GPlugin->errormsg);
00650   table_row = add_GxsmPluginInfo(table_row, pdesc, N_("Status"), GPlugin->status);
00651 
00652   label = gtk_hseparator_new (); /* ok, not really a label ... :) */
00653   gtk_table_attach (GTK_TABLE (pdesc->info_table), label,
00654                     0, 4, table_row, table_row+1, GTK_FILL, GTK_FILL, 3, 6);
00655   gtk_widget_show (label);
00656   table_row++;
00657 
00658   table_row = add_GxsmPluginInfo(table_row, pdesc, N_("Init"),      (GPlugin->init      ? N_("Yes") : N_("No")));
00659   table_row = add_GxsmPluginInfo(table_row, pdesc, N_("Query"),     (GPlugin->query     ? N_("Yes") : N_("No")));
00660 
00661   if(GPlugin->about){
00662     button = gtk_button_new_with_label (N_("Call"));
00663     gtk_signal_connect (GTK_OBJECT (button), "clicked",
00664                         GTK_SIGNAL_FUNC (exec_callback),
00665                         (gpointer) GPlugin->about);
00666     gtk_table_attach (GTK_TABLE (pdesc->info_table), button,
00667                       2, 4, table_row, table_row+1, GTK_FILL, GTK_FILL, 3, 6);
00668     gtk_widget_show (button);
00669   }
00670   table_row = add_GxsmPluginInfo(table_row, pdesc, N_("About"),     (GPlugin->about     ? N_("Yes") : N_("No")));
00671 
00672   if(GPlugin->configure){
00673     button = gtk_button_new_with_label (N_("Call"));
00674     gtk_signal_connect (GTK_OBJECT (button), "clicked",
00675                         GTK_SIGNAL_FUNC (exec_callback),
00676                         (gpointer) GPlugin->configure);
00677     gtk_table_attach (GTK_TABLE (pdesc->info_table), button,
00678                       2, 4, table_row, table_row+1, GTK_FILL, GTK_FILL, 3, 6);
00679     gtk_widget_show (button);
00680   }
00681   table_row = add_GxsmPluginInfo(table_row, pdesc, N_("Configure"), (GPlugin->configure ? N_("Yes") : N_("No")));
00682 
00683   table_row = add_GxsmPluginInfo(table_row, pdesc, N_("Run"),       (GPlugin->run       ? N_("Yes") : N_("No")));
00684   table_row = add_GxsmPluginInfo(table_row, pdesc, N_("Cleanup"),   (GPlugin->cleanup   ? N_("Yes") : N_("No")));
00685 
00686   label = gtk_hseparator_new (); // ok, not really a label ... :)
00687   gtk_table_attach (GTK_TABLE (pdesc->info_table), label,
00688                     0, 4, table_row, table_row+1, GTK_FILL, GTK_FILL, 3, 6);
00689   gtk_widget_show (label);
00690   table_row++;
00691 
00692   /* Remove old and replace with new */
00693 
00694   if (old_table)
00695     gtk_widget_destroy (old_table);
00696 
00697   if (old_align)
00698     gtk_widget_destroy (old_align);
00699 
00700   gtk_container_add (GTK_CONTAINER (pdesc->info_align),pdesc->info_table);
00701 
00702   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (pdesc->descr_scroll), 
00703                                          pdesc->info_align);
00704 
00705   gtk_widget_show (pdesc->info_table);
00706   gtk_widget_show (pdesc->info_align);
00707 
00708   return FALSE;
00709 }
00710 
00711 static void 
00712 expand_to (PDesc        *pdesc,
00713            GtkCTreeNode *parent)
00714 {
00715   if(parent)
00716     {
00717       expand_to (pdesc, (GTK_CTREE_ROW (parent))->parent);
00718       gtk_ctree_expand (GTK_CTREE (pdesc->ctree), parent);      
00719     }
00720 }
00721 
00722 static gint
00723 procedure_clist_select_callback (GtkWidget      *widget,
00724                                  gint            row, 
00725                                  gint            column, 
00726                                  GdkEventButton *bevent,
00727                                  gpointer        data)
00728 {
00729   GxsmPlugin *GPlugin;
00730   GtkCTreeNode * found_node; 
00731   PDesc *pdesc = (PDesc*)data;
00732 
00733   g_return_val_if_fail (pdesc != NULL, FALSE);
00734 
00735   GPlugin = (GxsmPlugin *) gtk_clist_get_row_data (GTK_CLIST (widget), row);
00736 
00737   if (!GPlugin)
00738     return FALSE;
00739 
00740   /* Must select the correct one in the ctree structure */
00741 
00742   found_node = gtk_ctree_find_by_row_data (GTK_CTREE (pdesc->ctree),
00743                                            NULL, GPlugin);
00744   
00745   if (found_node)
00746     {
00747       GtkCTreeRow   *ctr;
00748       GtkCTreeNode  *parent;
00749       gint sel_row;
00750 
00751       /* Make sure this is expanded */
00752 
00753       ctr = GTK_CTREE_ROW (found_node);
00754 
00755       parent = GTK_CTREE_NODE (ctr->parent);
00756 
00757       expand_to (pdesc, parent);
00758 
00759       sel_row = gtk_clist_find_row_from_data (GTK_CLIST (pdesc->ctree), GPlugin);
00760 
00761       gtk_widget_hide (pdesc->ctree); 
00762       gtk_widget_show (pdesc->ctree); 
00763 
00764       gtk_signal_handler_block_by_func (GTK_OBJECT(pdesc->ctree),
00765                                         GTK_SIGNAL_FUNC (procedure_ctree_select_callback),
00766                                         pdesc);
00767 
00768       gtk_clist_select_row (GTK_CLIST (pdesc->ctree), sel_row, -1);  
00769       gtk_ctree_select (GTK_CTREE (pdesc->ctree), found_node);
00770 
00771       gtk_clist_moveto (GTK_CLIST (pdesc->ctree),
00772                         sel_row,
00773                         0,
00774                         0.5, 0.5);
00775 
00776       gtk_signal_handler_unblock_by_func (GTK_OBJECT (pdesc->ctree),
00777                                           GTK_SIGNAL_FUNC (procedure_ctree_select_callback),
00778                                           pdesc);
00779 
00780       pdesc->ctree_row = sel_row;
00781     }
00782   else
00783     {
00784       g_warning ("Failed to find node in ctree");
00785     }
00786 
00787   return procedure_general_select_callback (pdesc, GPlugin);
00788 }
00789 
00790 /* This was an attempt to get around a problem in gtk 
00791  * where the scroll windows that contain ctree and clist
00792  * refuse to respond to the moveto funcions unless the
00793  * widgets are visible.
00794  * Still did not work 100% even after this.
00795  * Note the scrollbars are in the correct position but the
00796  * widget needs to be redrawn at the correct location.
00797  */
00798 
00799 static gint
00800 page_select_callback (GtkNotebook     *notebook,
00801                       GtkNotebookPage *page,
00802                       guint            page_num,
00803                       gpointer         data)
00804 {
00805   PDesc *pdesc = (PDesc *)data;
00806 
00807   if (page_num == 0)
00808     {
00809       gtk_clist_select_row (GTK_CLIST (pdesc->clist), pdesc->clist_row, -1);  
00810       gtk_clist_moveto (GTK_CLIST (pdesc->clist),
00811                         pdesc->clist_row,
00812                         0,
00813                         0.5, 0.0);
00814     }
00815   else
00816     {
00817       gtk_clist_select_row (GTK_CLIST (pdesc->ctree), pdesc->ctree_row, -1);  
00818       gtk_clist_moveto (GTK_CLIST (pdesc->ctree),
00819                         pdesc->ctree_row,
00820                         0,
00821                         0.5, 0.0);
00822     }
00823 
00824   return FALSE;
00825 }
00826 
00827 static gint
00828 procedure_ctree_select_callback (GtkWidget *widget,
00829                                  GtkWidget *row, 
00830                                  gint       column, 
00831                                  gpointer   data)
00832 {
00833   GxsmPlugin *GPlugin;
00834   PDesc *pdesc;
00835   gboolean is_leaf;
00836   gint sel_row;
00837 
00838   /* row is not a leaf the we have no interest in it */
00839 
00840   gtk_ctree_get_node_info (GTK_CTREE (widget),
00841                            GTK_CTREE_NODE (row),
00842                            NULL,
00843                            NULL,
00844                            NULL,
00845                            NULL,
00846                            NULL,
00847                            NULL,
00848                            &is_leaf,
00849                            NULL);
00850 
00851   if (!is_leaf)
00852     return FALSE;
00853 
00854   pdesc = (PDesc*) data;
00855 
00856   GPlugin = (GxsmPlugin *) gtk_ctree_node_get_row_data (GTK_CTREE (widget),
00857                                                  GTK_CTREE_NODE (row));
00858 
00859   /* Must set clist to this one */
00860   /* Block signals */
00861 
00862   gtk_signal_handler_block_by_func (GTK_OBJECT (pdesc->clist),
00863                                     GTK_SIGNAL_FUNC (procedure_clist_select_callback),
00864                                     pdesc);
00865 
00866   sel_row = gtk_clist_find_row_from_data (GTK_CLIST (pdesc->clist), GPlugin);
00867   gtk_clist_select_row (GTK_CLIST (pdesc->clist), sel_row, -1);  
00868   gtk_clist_moveto (GTK_CLIST (pdesc->clist),
00869                     sel_row,
00870                     0,
00871                     0.5, 0.5);
00872 
00873   gtk_signal_handler_unblock_by_func (GTK_OBJECT (pdesc->clist),
00874                                       GTK_SIGNAL_FUNC (procedure_clist_select_callback),
00875                                       pdesc);
00876 
00877   pdesc->clist_row = sel_row;
00878   
00879   return procedure_general_select_callback (pdesc, GPlugin);
00880 }
00881 
00882 static GtkCTreeNode *
00883 get_parent (PDesc       *pdesc,
00884             GHashTable  *ghash,
00885             gchar       *mpath)
00886 {
00887     GtkCTreeNode *parent;
00888     GtkCTreeNode *last_parent;
00889     gchar *tmp_ptr;
00890     gchar *str_ptr;
00891     gchar *leaf_ptr;
00892     gchar *labels[3];
00893     
00894     if (mpath == NULL)
00895         return NULL; /* Parent is root */
00896     
00897     parent = (GtkCTreeNode *) g_hash_table_lookup (ghash, mpath);
00898     
00899     if (parent)
00900         {
00901             /* found node */
00902             return parent;
00903         }
00904     
00905     /* Next one up */
00906     tmp_ptr = g_strdup (mpath);
00907     
00908     str_ptr = strrchr (tmp_ptr,'/');
00909     
00910     if (str_ptr == NULL)
00911         {
00912             /*       printf("Root node for %s\n",mpath); */
00913             leaf_ptr = mpath;
00914             tmp_ptr = "<root>";
00915             last_parent = NULL;
00916         }
00917     else
00918         {
00919             leaf_ptr = g_strdup(str_ptr+1);
00920             
00921             *str_ptr = '\000';
00922             
00923             last_parent = get_parent (pdesc, ghash, tmp_ptr);
00924         }
00925     
00926     labels[0] = g_strdup (leaf_ptr);
00927     labels[1] = g_strdup (""); 
00928     labels[2] = g_strdup (""); 
00929     
00930     /*   printf("get_parent::creating node %s under %s\n",leaf_ptr,tmp_ptr); */
00931     
00932     parent = gtk_ctree_insert_node (GTK_CTREE (pdesc->ctree),
00933                                     last_parent,
00934                                     NULL,
00935                                     labels,
00936                                     4,
00937                                     NULL,
00938                                     NULL,
00939                                     NULL,
00940                                     NULL,
00941                                     FALSE,
00942                                     FALSE);
00943     
00944     g_hash_table_insert (ghash, mpath, parent); 
00945     
00946     g_free(labels[2]);
00947     g_free(labels[1]);
00948     g_free(labels[0]);
00949     
00950     return parent;
00951 }
00952 
00953 static void
00954 insert_into_ctree (PDesc      *pdesc,
00955                    gchar      *name,
00956                    gchar      *xtimestr,
00957                    gchar      *menu_str,
00958                    gchar      *types_str,
00959                    GHashTable *ghash,
00960                    GxsmPlugin      *GPlugin)
00961 {
00962   gchar *labels[3];
00963   gchar *str_ptr;
00964   gchar *tmp_ptr;
00965   //  gchar *leaf_ptr;
00966   GtkCTreeNode *parent = NULL;
00967   GtkCTreeNode *leaf_node = NULL;
00968 
00969   /* Find all nodes */
00970   /* Last one is the leaf part */
00971 
00972   tmp_ptr = g_strdup (menu_str);
00973 
00974   str_ptr = strrchr (tmp_ptr, '/');
00975 
00976   if (str_ptr == NULL)
00977     return; /* No node */
00978 
00979   //  leaf_ptr = g_strdup (str_ptr + 1);
00980 
00981   *str_ptr = '\000';
00982 
00983   /*   printf("inserting %s...\n",menu_str); */
00984 
00985   parent = get_parent (pdesc, ghash, tmp_ptr);
00986 
00987   /* Last was a leaf */
00988   //   printf("found leaf %s parent = %p\n",leaf_ptr,parent);
00989   labels[0] = g_strdup (name);
00990   labels[1] = g_strdup (xtimestr);
00991   labels[2] = g_strdup (types_str);
00992 
00993   leaf_node = gtk_ctree_insert_node (GTK_CTREE (pdesc->ctree),
00994                                      parent,
00995                                      NULL,
00996                                      labels,
00997                                      4,
00998                                      NULL,
00999                                      NULL,
01000                                      NULL,
01001                                      NULL,
01002                                      TRUE,
01003                                      FALSE);
01004   g_free(labels[2]);
01005   g_free(labels[1]);
01006   g_free(labels[0]);
01007 
01008   gtk_ctree_node_set_row_data (GTK_CTREE (pdesc->ctree), leaf_node, GPlugin);
01009 }
01010 
01011 void GxsmPlugin_free (gpointer p)
01012 {
01013   //  GxsmPlugin *pinfo = (GxsmPlugin *) p;
01014   // may be used later to free some stuff...
01015 }
01016 
01017 static void
01018 get_plugin_info (PDesc *pdesc,
01019                  const gchar *search_text)
01020 {
01021   gint  row_count = 0;
01022   gchar *menu_strs;
01023 
01024   GHashTable* ghash = g_hash_table_new (g_str_hash, g_str_equal);
01025 
01026   // Gxsm Plugin Query...
01027   pdesc->num_plugins = listplugins_pi.app->GxsmPlugins->how_many();
01028 
01029   for( GList *node = listplugins_pi.app->GxsmPlugins->get_pluginlist();
01030        node; node = node->next )
01031     {
01032       GxsmPlugin *pinfo = (GxsmPlugin *) node->data;
01033       gchar *labels[4];
01034 
01035       if (search_text)
01036         if( !strstr( pinfo->menuentry, search_text) &&
01037             !strstr( pinfo->name, search_text)
01038             ){
01039           continue;
01040         }
01041 
01042       labels[0] = g_strdup (pinfo->menupath);
01043       labels[1] = g_strdup (pinfo->menuentry);
01044       labels[2] = g_strdup (pinfo->name);
01045       labels[3] = g_strdup (pinfo->query ? "Query-SelfInstall" : pinfo->run ? "Run-Cb" : "Math-PlugIn");
01046       
01047       gtk_clist_insert (GTK_CLIST (pdesc->clist), row_count, labels);
01048       
01049       gtk_clist_set_row_data_full (GTK_CLIST (pdesc->clist), row_count,
01050                                    pinfo, GxsmPlugin_free);
01051       
01052       row_count++;
01053       
01054       /* Now do the tree view.... */
01055       gtk_signal_handler_block_by_func (GTK_OBJECT(pdesc->ctree),
01056                                         GTK_SIGNAL_FUNC (procedure_ctree_select_callback),
01057                                         pdesc);
01058       menu_strs = g_strconcat(pinfo->menupath, pinfo->menuentry, NULL);
01059       insert_into_ctree (pdesc,
01060                          pinfo->menuentry,
01061                          pinfo->name,
01062                          menu_strs,
01063                          labels[3],
01064                          ghash,
01065                          pinfo);
01066       g_free(labels[3]);
01067       g_free(labels[2]);
01068       g_free(labels[1]);
01069       g_free(labels[0]);
01070       g_free(menu_strs);
01071 
01072       gtk_signal_handler_unblock_by_func (GTK_OBJECT (pdesc->ctree),
01073                                           GTK_SIGNAL_FUNC (procedure_ctree_select_callback),
01074                                           pdesc);
01075   }
01076 
01077   // HwI Plugin(s)
01078   for( GList *node = listplugins_pi.app->xsm->HwI_plugins->get_pluginlist();
01079        node; node = node->next )
01080     {
01081       GxsmPlugin *pinfo = (GxsmPlugin *) node->data;
01082       gchar *labels[4];
01083 
01084       if (search_text)
01085         if( !strstr( pinfo->menuentry, search_text) &&
01086             !strstr( pinfo->name, search_text)
01087             ){
01088           continue;
01089         }
01090 
01091       labels[0] = g_strdup (pinfo->menupath);
01092       labels[1] = g_strdup (pinfo->menuentry);
01093       labels[2] = g_strdup (pinfo->name);
01094       labels[3] = g_strdup (pinfo->query ? "HwI-Query-SelfInstall" : pinfo->run ? "HwI-Run-Cb" : "HwI-PlugIn");
01095       
01096       gtk_clist_insert (GTK_CLIST (pdesc->clist), row_count, labels);
01097       
01098       gtk_clist_set_row_data_full (GTK_CLIST (pdesc->clist), row_count,
01099                                    pinfo, GxsmPlugin_free);
01100       
01101       row_count++;
01102       
01103       /* Now do the tree view.... */
01104       gtk_signal_handler_block_by_func (GTK_OBJECT(pdesc->ctree),
01105                                         GTK_SIGNAL_FUNC (procedure_ctree_select_callback),
01106                                         pdesc);
01107       menu_strs = g_strconcat(pinfo->menupath, pinfo->menuentry, NULL);
01108       insert_into_ctree (pdesc,
01109                          pinfo->menuentry,
01110                          pinfo->name,
01111                          menu_strs,
01112                          labels[3],
01113                          ghash,
01114                          pinfo);
01115       g_free(labels[3]);
01116       g_free(labels[2]);
01117       g_free(labels[1]);
01118       g_free(labels[0]);
01119       g_free(menu_strs);
01120 
01121       gtk_signal_handler_unblock_by_func (GTK_OBJECT (pdesc->ctree),
01122                                           GTK_SIGNAL_FUNC (procedure_ctree_select_callback),
01123                                           pdesc);
01124   }
01125 }
01126 
01127 
01128 static void 
01129 dialog_search_callback (GnomeDialog *Dlg, 
01130                         gpointer   data)
01131 {
01132   PDesc *pdesc = (PDesc*)data;
01133   const gchar *search_text = NULL;
01134  
01135   if (Dlg != NULL)
01136     {
01137       /* The result of a button press... read entry data */
01138       search_text = gtk_entry_get_text (GTK_ENTRY (plugindesc->search_entry));
01139     }
01140 
01141   gtk_clist_freeze (GTK_CLIST (pdesc->ctree));
01142   gtk_clist_clear (GTK_CLIST (pdesc->ctree));
01143   gtk_clist_freeze (GTK_CLIST (pdesc->clist));
01144   gtk_clist_clear (GTK_CLIST (pdesc->clist));
01145 
01146   get_plugin_info (pdesc, search_text);
01147 
01148   gtk_clist_columns_autosize (GTK_CLIST (plugindesc->clist));
01149 
01150   gtk_clist_sort (GTK_CLIST (pdesc->clist));
01151   gtk_clist_thaw (GTK_CLIST (pdesc->clist));
01152   gtk_ctree_sort_recursive (GTK_CTREE (pdesc->ctree), NULL);
01153   gtk_clist_thaw (GTK_CLIST (pdesc->ctree));
01154 }
01155 
01156 
01157 static gint
01158 name_sort (GtkCList      *clist,
01159            gconstpointer  ptr1,
01160            gconstpointer  ptr2)
01161 {
01162   GtkCListRow *row1 = (GtkCListRow *) ptr1;
01163   GtkCListRow *row2 = (GtkCListRow *) ptr2;
01164 
01165   /* Get the data for the row */
01166   GxsmPlugin *row1_GxsmPlugin = (GxsmPlugin *) row1->data;
01167   GxsmPlugin *row2_GxsmPlugin = (GxsmPlugin *) row2->data;
01168 
01169   /* Want to sort on the date field */
01170 
01171   if (row2_GxsmPlugin->name < row1_GxsmPlugin->name)
01172     {
01173       return -1;
01174     }
01175 
01176   if (row2_GxsmPlugin->name > row1_GxsmPlugin->name)
01177     {
01178       return 1;
01179     }
01180 
01181   return 0;
01182 }
01183 
01184 
01185 static void 
01186 clist_click_column (GtkCList *clist, 
01187                     gint      column, 
01188                     gpointer  data)
01189 {
01190   if (column == 1)
01191     {
01192       gtk_clist_set_compare_func (clist, name_sort);
01193     }
01194   else
01195     {
01196       gtk_clist_set_compare_func (clist, NULL); /* Set back to default */
01197     }
01198 
01199   if (column == clist->sort_column)
01200     {
01201       if (clist->sort_type == GTK_SORT_ASCENDING)
01202         clist->sort_type = GTK_SORT_DESCENDING;
01203       else
01204         clist->sort_type = GTK_SORT_ASCENDING;
01205     }
01206   else
01207     gtk_clist_set_sort_column (clist, column);
01208   
01209   gtk_clist_sort (clist);
01210 }

Generated on Sat Apr 1 09:04:10 2006 for GXSM by  doxygen 1.4.6