1 /*
2  * gms_gui.c: miniscript plugin for geany editor
3  *            Geany, a fast and lightweight IDE
4  *
5  * Copyright 2008 Pascal BURLOT <prublot(at)users(dot)sourceforge(dot)net>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20  * MA 02110-1301, USA.
21  *
22  */
23 
24 /**
25  * \file  gms_gui.c
26  * \brief it is the graphical user interface of the geany miniscript plugin
27  */
28 #include    "config.h"
29 #include    "geany.h"
30 
31 #include    <glib/gstdio.h>
32 #include    <glib/gprintf.h>
33 
34 #include    <stdlib.h>
35 #include    <string.h>
36 #include    <sys/stat.h>
37 #include    <sys/types.h>
38 #include    <unistd.h>
39 
40 #include    <pango/pango.h>
41 
42 #ifdef HAVE_LOCALE_H
43 #include    <locale.h>
44 #endif
45 
46 /* geany headers */
47 #include    "support.h"
48 #include    "plugindata.h"
49 #include    "editor.h"
50 #include    "document.h"
51 #include    "prefs.h"
52 #include    "utils.h"
53 #include    "ui_utils.h"
54 
55 /* user header */
56 #include    "gms_debug.h"
57 #include    "gms.h"
58 #include    "gms_gui.h"
59 
60 /*
61  * *****************************************************************************
62  *  Local Macro and new local type definition
63  */
64 
65 /*! \brief Number of script type */
66 #define GMS_NB_TYPE_SCRIPT  6
67 /*! \brief Number of char of the line buffer */
68 #define GMS_MAX_LINE        127
69 
70 /*! \brief macro uset to cast a gms_handle_t  to a gms_private_t pointer */
71 #define GMS_PRIVATE(p) ((gms_private_t *) p)
72 
73 /*! \brief definition of gui data structure */
74 typedef struct {
75     GtkWidget   *dlg          ; /*!< Dialog widget */
76     GtkWidget   *cb_st        ; /*!< Script type combobox */
77     GtkWidget   *t_script     ; /*!< script text */
78     GtkWidget   *rb_select    ; /*!< radio button : filtering the selection */
79     GtkWidget   *rb_doc       ; /*!< radio button : filtering the current document */
80     GtkWidget   *rb_session   ; /*!< radio button : filtering all documents of the current session */
81     GtkWidget   *rb_cdoc      ; /*!< radio button : the filter output is in the current document */
82     GtkWidget   *rb_ndoc      ; /*!< radio button : the filter output is in the current document */
83 
84     GtkWidget   *e_script[GMS_NB_TYPE_SCRIPT] ; /*!< entry for script configuration */
85     PangoFontDescription *fontdesc;
86 } gms_gui_t  ;
87 
88 /*! \brief definition of mini-script data structure */
89 typedef struct {
90     int         id ;                             /*!< ID of the instance */
91 	gchar      *config_dir  ;                    /*!< path of configuration files */
92     GString    *cmd         ;                    /*!< Command string of filtering */
93     GtkWidget  *mw          ;                    /*!< MainWindow of Geany */
94     gms_gui_t   w           ;                    /*!< Widgets of minis-script gui */
95     GString    *input_name  ;                    /*!< filename of the filter input */
96     GString    *filter_name ;                    /*!< filter filename */
97     GString    *output_name ;                    /*!< filename of the filter output */
98     GString    *error_name  ;                    /*!< errors filename */
99     GString    *script_cmd[GMS_NB_TYPE_SCRIPT];  /*!< array of script command names */
100 } gms_private_t  ;
101 /*
102  * *****************************************************************************
103  *  Global variables
104  */
105 
106 /*
107  * *****************************************************************************
108  *  Local variables
109  */
110 static unsigned char inst_cnt = 0  ; /*!< counter of instance */
111 static gchar bufline[GMS_MAX_LINE+1]; /*!< buffer used to read the configuration file */
112 
113 static const gchar pref_filename[]   = "gms.rc"    ; /*!< preferences filename */
114 static const gchar prefix_filename[] = "/tmp/gms"  ; /*!< prefix filename */
115 static const gchar in_ext[]          = ".in"       ; /*!< filename extension for the input file */
116 static const gchar out_ext[]         = ".out"      ; /*!< filename extension for the output file */
117 static const gchar filter_ext[]      = ".filter"   ; /*!< filename extension for the filter file */
118 static const gchar error_ext[]       = ".error"    ; /*!< filename extension for the error file */
119 
120 /**< \brief It's the default script command */
121 static const gchar *default_script_cmd[GMS_NB_TYPE_SCRIPT] = {
122     "${SHELL} ", "perl ", "python ", "sed -f ", "awk -f ", "cat - "  };
123 
124 /**< \brief It's the label for the script command combobox */
125 const gchar *label_script_cmd[GMS_NB_TYPE_SCRIPT] = {
126     "Shell", "Perl", "Python", "Sed", "Awk", "User" };
127 
128 /**< \brief It's the information message about geany mini script */
129 const char *geany_info = N_("<b>GMS : Geany Mini-Script filter Plugin</b>\n"
130 "This plugin is a tool to apply a script filter on:\n"
131 "   o the text selection,\n"
132 "   o the current document,\n"
133 "   o all documents of the current session.\n"
134 "\n"
135 "The filter type can be:\n"
136 "   o Unix shell script,\n"
137 "   o perl script,\n"
138 "   o python script,\n"
139 "   o sed commands,\n"
140 "   o awk script.\n"
141 "\n"
142 "<b>AUTHOR</b>\n"
143 "   Written by Pascal BURLOT (December,2008)\n"
144 "\n"
145 "<b>LICENSE:</b>\n"
146 "This program is free software; you can redistribute\n"
147 "it and/or modify it under the terms of the GNU \n"
148 "General Public License as published by the Free\n"
149 "Software Foundation; either version 2 of the License,\n"
150 "or (at your option) any later version.");
151 
152 /*
153  * *****************************************************************************
154  *  Local functions
155  */
156 
157 /**
158  * \brief the function loads the preferences file
159  */
load_prefs_file(gms_private_t * this)160 static void load_prefs_file(
161     gms_private_t *this  /**< pointer of mini-script data structure */
162     )
163 {
164     GString *gms_pref = g_string_new("") ;
165 
166     g_string_printf(gms_pref , "%s/plugins/%s", this->config_dir,pref_filename );
167 
168     if ( g_file_test( gms_pref->str, G_FILE_TEST_EXISTS ) == TRUE )
169     {
170         FILE *fd = g_fopen( gms_pref->str, "r" ) ;
171         if ( fd != NULL )
172         {
173             int  ii ;
174             for ( ii = 0 ; ii <GMS_NB_TYPE_SCRIPT ;ii++ )
175             {
176                 if ( fgets(bufline,GMS_MAX_LINE,fd) == NULL )
177                     break ;
178                 if ( fgets(bufline,GMS_MAX_LINE,fd) == NULL )
179                     break ;
180                 bufline[strlen(bufline)-1] = 0 ;
181                 g_string_assign(this->script_cmd[ii] , bufline ) ;
182             }
183             fclose(fd) ;
184         }
185      }
186     g_string_free( gms_pref , TRUE) ;
187 }
188 
189 /**
190  * \brief the function saves the preferences file
191  */
save_prefs_file(gms_private_t * this)192 static void save_prefs_file(
193         gms_private_t *this /**< pointer of mini-script data structure */
194     )
195 {
196     GString *gms_pref = g_string_new("");
197 
198     g_string_printf(gms_pref , "%s/plugins", this->config_dir );
199 
200     if ( g_file_test( this->config_dir, G_FILE_TEST_EXISTS ) != TRUE )
201         g_mkdir( this->config_dir, 0755 ) ;
202 
203     if ( g_file_test( gms_pref->str, G_FILE_TEST_EXISTS ) != TRUE )
204         g_mkdir( gms_pref->str, 0755 ) ;
205 
206     if ( g_file_test( gms_pref->str, G_FILE_TEST_IS_DIR ) == TRUE )
207     {
208         FILE *fd ;
209         g_string_append_c( gms_pref, '/' );
210         g_string_append( gms_pref, pref_filename );
211 
212         fd = g_fopen( gms_pref->str, "w" ) ;
213         if ( fd != NULL )
214         {
215             int  ii ;
216             for ( ii = 0 ; ii <GMS_NB_TYPE_SCRIPT ;ii++ )
217                 fprintf(fd,"# %s\n%s\n",label_script_cmd[ii],this->script_cmd[ii]->str);
218 
219             fclose(fd) ;
220         }
221     }
222     g_string_free( gms_pref , TRUE) ;
223 }
224 
225 /**
226  * \brief Callback associated to a button "new"
227  */
gms_cb_new(GtkWidget * w,gpointer data)228 static void gms_cb_new(
229     GtkWidget *w  ,
230     gpointer data
231     )
232 {
233     gms_private_t *this = GMS_PRIVATE(data) ;
234     GtkTextIter start;
235     GtkTextIter end;
236     GtkTextBuffer* text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW( this->w.t_script ) );
237     gtk_text_buffer_get_start_iter(text_buffer,&start);
238     gtk_text_buffer_get_end_iter(text_buffer,&end);
239     gtk_text_buffer_delete( text_buffer ,&start , &end) ;
240 }
241 
242 /**
243  * \brief Callback associated to a button "load"
244  */
gms_cb_load(GtkWidget * w,gpointer data)245 static void gms_cb_load(
246     GtkWidget *w  ,
247     gpointer  data
248     )
249 {
250     gms_private_t *this = GMS_PRIVATE(data) ;
251     GtkWidget    *p_dialog ;
252 
253     p_dialog = gtk_file_chooser_dialog_new (_("Load Mini-Script File"),
254                                     GTK_WINDOW(this->mw) ,
255                                     GTK_FILE_CHOOSER_ACTION_OPEN,
256                                     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
257                                     GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
258                                     NULL);
259     if ( p_dialog == NULL )
260         return ;
261 
262     if (gtk_dialog_run (GTK_DIALOG (p_dialog)) == GTK_RESPONSE_ACCEPT)
263     {
264         gchar         *filename = NULL;
265 
266         filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (p_dialog));
267 
268         if(filename != NULL)
269         {
270             gchar *contents = NULL;
271             GError *error = NULL ;
272 
273             if (g_file_get_contents(filename, &contents, NULL, &error ))
274             {
275                 gchar         *utf8 = NULL;
276                 GtkTextIter   start;
277                 GtkTextIter   end;
278                 GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW( this->w.t_script ) );
279 
280                 /* destroy the old text of buffer */
281                 gtk_text_buffer_get_start_iter(text_buffer,&start);
282                 gtk_text_buffer_get_end_iter(text_buffer,&end);
283                 gtk_text_buffer_delete( text_buffer ,&start , &end) ;
284 
285                 /* Copy file contents in GtkTextView */
286                 gtk_text_buffer_get_start_iter(text_buffer,&start);
287                 utf8 = g_locale_to_utf8 (contents, -1, NULL, NULL, NULL);
288                 GMS_G_FREE(contents);
289                 gtk_text_buffer_insert (text_buffer, &start, utf8, -1);
290                 GMS_G_FREE(utf8);
291             }
292             GMS_G_FREE(filename);
293         }
294     }
295     gtk_widget_destroy (p_dialog);
296 }
297 
298 
299 /**
300  * \brief Callback associated to a button "load"
301  */
gms_cb_save(GtkWidget * w,gpointer data)302 static void gms_cb_save(
303     GtkWidget *w  ,
304     gpointer  data
305     )
306 {
307     gms_private_t *this = GMS_PRIVATE(data) ;
308     GtkWidget    *p_dialog ;
309 
310     p_dialog = gtk_file_chooser_dialog_new (_("Save Mini-Script File"),
311                                     GTK_WINDOW(this->mw) ,
312                                     GTK_FILE_CHOOSER_ACTION_SAVE,
313                                     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
314                                     GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
315                                     NULL);
316     if ( p_dialog == NULL )
317         return ;
318 
319     if (gtk_dialog_run (GTK_DIALOG (p_dialog)) == GTK_RESPONSE_ACCEPT)
320     {
321         gchar         *filename = NULL;
322 
323         filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (p_dialog));
324 
325         if(filename != NULL)
326         {
327             gchar        *contents = NULL;
328             GtkTextIter   start;
329             GtkTextIter   end;
330             GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW( this->w.t_script ) );
331             gtk_text_buffer_get_start_iter(text_buffer,&start);
332             gtk_text_buffer_get_end_iter(text_buffer,&end);
333             contents=gtk_text_buffer_get_text(text_buffer,&start,&end,FALSE);
334             g_file_set_contents(filename, contents, -1 , NULL );
335             GMS_G_FREE(contents);
336             GMS_G_FREE(filename);
337        }
338     }
339     gtk_widget_destroy (p_dialog);
340 }
341 /**
342  * \brief Callback associated to a button "load"
343  */
gms_cb_info(GtkWidget * w,gpointer data)344 static void gms_cb_info(
345     GtkWidget *w  ,
346     gpointer  data
347     )
348 {
349     gms_private_t *this = GMS_PRIVATE(data) ;
350 
351     GtkWidget *dlg = gtk_message_dialog_new(GTK_WINDOW(this->mw),
352                                 GTK_DIALOG_DESTROY_WITH_PARENT,
353                                 GTK_MESSAGE_INFO,
354                                 GTK_BUTTONS_CLOSE,
355                                 NULL);
356     gtk_message_dialog_set_markup(GTK_MESSAGE_DIALOG(dlg), _(geany_info));
357 
358     gtk_dialog_run(GTK_DIALOG(dlg));
359     GMS_FREE_WIDGET(dlg);
360 }
361 
362 /*
363  * *****************************************************************************
364  *  Global functions
365  */
366 
new_button_from_stock(gboolean withtext,const gchar * stock_id)367 static GtkWidget  *new_button_from_stock( gboolean withtext, const gchar *stock_id )
368 {
369     GtkWidget  *button ;
370     if ( withtext )
371         button   = gtk_button_new_from_stock( stock_id  ) ;
372     else
373     {
374         button   = gtk_button_new() ;
375         gtk_container_add( GTK_CONTAINER(button),gtk_image_new_from_stock(stock_id , GTK_ICON_SIZE_SMALL_TOOLBAR ) );
376     }
377     return button ;
378 }
379 
380 /**
381  * \brief the function initializes the mini-script gui structure.
382  */
gms_new(GtkWidget * mw,gchar * font,gint tabs,gchar * config_dir)383 gms_handle_t gms_new(
384     GtkWidget *mw         , /**< Geany Main windows */
385     gchar     *font       , /**< Geany editor font */
386     gint       tabs       , /**< Geany editor tabstop */
387     gchar     *config_dir   /**< Geany Configuration Path */
388     )
389 {
390     gms_private_t *this = GMS_G_MALLOC0(gms_private_t,1);
391 
392     if ( this != NULL )
393     {
394         GtkBox     *vb_dlg        ; /*!< vbox of dialog box */
395         GtkWidget  *hb_st         ; /*!< Hbox for script type */
396         GtkWidget  *b_open        ; /*!< button for loading a existing script */
397         GtkWidget  *b_save        ; /*!< button for saving the current script */
398         GtkWidget  *b_new         ; /*!< button for erasing the script text box */
399         GtkWidget  *b_info        ; /*!< button for info box */
400         GtkWidget  *sb_script     ; /*!< Scroll box for script text */
401         GtkWidget  *hb_rb         ; /*!< Hbox for radio buttons */
402         GtkWidget  *f_rbi         ; /*!< frame for radio buttons : input filter */
403         GtkWidget  *hb_rbi        ; /*!< Hbox for radio buttons */
404         GtkWidget  *f_rbo         ; /*!< frame for radio buttons : input filter */
405         GtkWidget  *hb_rbo        ; /*!< Hbox for radio buttons */
406 
407         PangoTabArray* tabsarray  ;
408         GdkScreen  *ecran  = gdk_screen_get_default();
409         gint        width  = gdk_screen_get_width(ecran) ;
410         gint        height = gdk_screen_get_height(ecran) ;
411         gint        i , size_pid ;
412         gboolean    mode_txt_icon = FALSE ;
413 
414         this->mw = mw ;
415         this->cmd = g_string_new("");
416         this->config_dir =config_dir ;
417 
418         this->w.dlg = gtk_dialog_new_with_buttons(
419                         _("Mini-Script Filter"),
420                         GTK_WINDOW( mw ),
421                         GTK_DIALOG_DESTROY_WITH_PARENT|GTK_DIALOG_MODAL,
422                         GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL,
423                         GTK_STOCK_EXECUTE,GTK_RESPONSE_APPLY,
424                         NULL
425                          ) ;
426         vb_dlg   = GTK_BOX (gtk_dialog_get_content_area(GTK_DIALOG(this->w.dlg)))  ;
427 
428         if ( width > 800 )
429             width = 800 ;
430 
431         if ( height > 600 )
432             height = 600 ;
433 
434         gtk_window_set_default_size( GTK_WINDOW(this->w.dlg) , width/2 , height/2 ) ;
435 
436 
437      /* Hbox : type de script */
438         hb_st = gtk_hbox_new (FALSE, 0);
439         gtk_container_set_border_width (GTK_CONTAINER (hb_st), 0);
440         gtk_box_pack_start( vb_dlg , hb_st, FALSE, FALSE, 0);
441 
442         b_new   = new_button_from_stock( mode_txt_icon, GTK_STOCK_CLEAR  ) ;
443         gtk_box_pack_start( GTK_BOX (hb_st), b_new, FALSE, FALSE, 0);
444         g_signal_connect (G_OBJECT (b_new), "clicked",G_CALLBACK (gms_cb_new), (gpointer) this );
445         gtk_widget_set_tooltip_text(b_new, _("Clear the mini-script window"));
446 
447         b_open   = new_button_from_stock( mode_txt_icon, GTK_STOCK_OPEN  ) ;
448         gtk_box_pack_start( GTK_BOX (hb_st), b_open, FALSE, FALSE, 0);
449         g_signal_connect (G_OBJECT (b_open), "clicked",G_CALLBACK (gms_cb_load), (gpointer) this );
450         gtk_widget_set_tooltip_text(b_open, _("Load a mini-script into this window"));
451 
452         b_save   = new_button_from_stock( mode_txt_icon, GTK_STOCK_SAVE_AS  ) ;
453         gtk_box_pack_start( GTK_BOX (hb_st),b_save, FALSE, FALSE, 0);
454         g_signal_connect (G_OBJECT (b_save), "clicked",G_CALLBACK (gms_cb_save), (gpointer) this );
455         gtk_widget_set_tooltip_text(b_save, _("Save the mini-script into a file"));
456 
457         b_info   = new_button_from_stock( mode_txt_icon, GTK_STOCK_INFO  ) ;
458         gtk_box_pack_end( GTK_BOX (hb_st), b_info, FALSE, FALSE, 0);
459         g_signal_connect (G_OBJECT (b_info), "clicked",G_CALLBACK (gms_cb_info), (gpointer) this );
460         gtk_widget_set_tooltip_text(b_info, _("Display a information about the mini-script plugin"));
461 
462         this->w.cb_st = gtk_combo_box_text_new() ;
463         for ( i=0;i<GMS_NB_TYPE_SCRIPT ; i++ )
464            gtk_combo_box_text_append_text( GTK_COMBO_BOX_TEXT(this->w.cb_st), label_script_cmd[i] ) ;
465         gtk_combo_box_set_active(GTK_COMBO_BOX(this->w.cb_st), 0);
466         gtk_box_pack_start(GTK_BOX(hb_st), this->w.cb_st, FALSE, FALSE, 0);
467         gtk_widget_set_can_default(this->w.cb_st, TRUE);
468         gtk_widget_set_tooltip_text(this->w.cb_st, _("select the mini-script type"));
469 
470     /* Scroll Box : script */
471         sb_script =  gtk_scrolled_window_new (NULL,NULL);
472         gtk_container_set_border_width (GTK_CONTAINER (sb_script), 0);
473         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sb_script),
474                                         GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
475         gtk_box_pack_start(vb_dlg, sb_script, TRUE, TRUE, 0);
476 
477         this->w.t_script =  gtk_text_view_new();
478         this->w.fontdesc = pango_font_description_from_string(font);
479         gtk_widget_modify_font( this->w.t_script, this->w.fontdesc );
480         gtk_scrolled_window_add_with_viewport ( GTK_SCROLLED_WINDOW (sb_script), this->w.t_script);
481         { /* find the width of the space character */
482             gint largeur,hauteur ;
483             PangoLayout *layout = gtk_widget_create_pango_layout (this->w.t_script, " ");
484             pango_layout_set_font_description (layout, this->w.fontdesc);
485             pango_layout_get_pixel_size(layout, &largeur, &hauteur);
486             tabs = tabs*largeur ;
487             g_object_unref (layout);
488         }
489         tabsarray = pango_tab_array_new_with_positions ( 1,  TRUE  , PANGO_TAB_LEFT, tabs ) ;
490         gtk_text_view_set_tabs(GTK_TEXT_VIEW(this->w.t_script),tabsarray);
491 
492     /* Hbox : Radio bouttons for choosing the input/output: */
493         hb_rb = gtk_hbox_new (FALSE, 0);
494         gtk_container_set_border_width (GTK_CONTAINER (hb_rb), 0);
495         gtk_box_pack_start( vb_dlg, hb_rb, FALSE, FALSE, 0);
496 
497     /* Hbox : Radio bouttons for choosing the input:
498      *                   selection/current document/all documents of the current session */
499         f_rbi = gtk_frame_new (_("filter input") );
500         gtk_box_pack_start( GTK_BOX (hb_rb), f_rbi, FALSE, FALSE, 0);
501         gtk_widget_set_tooltip_text(f_rbi, _("select the input of mini-script filter"));
502 
503         hb_rbi = gtk_hbox_new (FALSE, 0);
504         gtk_container_set_border_width (GTK_CONTAINER (hb_rbi), 0);
505         gtk_container_add (GTK_CONTAINER (f_rbi), hb_rbi );
506 
507         this->w.rb_select  = gtk_radio_button_new_with_label( NULL, _("selection") ) ;
508         this->w.rb_doc     = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON( this->w.rb_select) ,_("document") ) ;
509         this->w.rb_session = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON( this->w.rb_select) ,_("session") ) ;
510         gtk_box_pack_start(GTK_BOX(hb_rbi), this->w.rb_select, TRUE, TRUE, 0);
511         gtk_box_pack_start(GTK_BOX(hb_rbi), this->w.rb_doc, TRUE, TRUE, 0);
512         gtk_box_pack_start(GTK_BOX(hb_rbi), this->w.rb_session, TRUE, TRUE, 0);
513         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(this->w.rb_doc) ,TRUE) ;
514 
515 
516     /* Hbox : Radio bouttons for choosing the output:
517      *                   current document/ or new document */
518         f_rbo = gtk_frame_new (_("filter output") );
519         gtk_box_pack_start( GTK_BOX(hb_rb), f_rbo, FALSE, FALSE, 0);
520         gtk_widget_set_tooltip_text(f_rbo, _("select the output of mini-script filter"));
521 
522         hb_rbo = gtk_hbox_new (FALSE, 0);
523         gtk_container_set_border_width (GTK_CONTAINER(hb_rbo), 0);
524         gtk_container_add (GTK_CONTAINER(f_rbo), hb_rbo );
525 
526         this->w.rb_cdoc    = gtk_radio_button_new_with_label( NULL, _("Current Doc.") ) ;
527         this->w.rb_ndoc    = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON( this->w.rb_cdoc) ,_("New Doc.") ) ;
528         gtk_box_pack_start(GTK_BOX(hb_rbo), this->w.rb_cdoc, TRUE, TRUE, 0);
529         gtk_box_pack_start(GTK_BOX(hb_rbo), this->w.rb_ndoc, TRUE, TRUE, 0);
530         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(this->w.rb_ndoc) ,TRUE) ;
531 
532         gtk_widget_show_all(GTK_WIDGET(vb_dlg));
533         this->id  = ++inst_cnt ;
534 
535         this->input_name = g_string_new(prefix_filename) ;
536         this->filter_name= g_string_new(prefix_filename) ;
537         this->output_name= g_string_new(prefix_filename) ;
538         this->error_name = g_string_new(prefix_filename) ;
539 
540         size_pid = (gint)(2*sizeof(pid_t)) ;
541         g_string_append_printf( this->input_name,"%02x_%0*x%s",
542                     this->id,size_pid, getpid(), in_ext ) ;
543 
544         g_string_append_printf(this->filter_name,"%02x_%0*x%s",
545                     this->id,size_pid, getpid(), filter_ext ) ;
546 
547         g_string_append_printf(this->output_name,"%02x_%0*x%s",
548                     this->id,size_pid, getpid(), out_ext ) ;
549 
550         g_string_append_printf(this->error_name,"%02x_%0*x%s",
551                     this->id,size_pid, getpid(), error_ext ) ;
552 
553         for ( i=0;i<GMS_NB_TYPE_SCRIPT ; i++ )
554         {
555             this->script_cmd[i]=g_string_new(default_script_cmd[i] ) ;
556             this->w.e_script[i]=NULL;
557         }
558         load_prefs_file(this) ;
559 
560     }
561 
562     return GMS_HANDLE(this) ;
563 }
564 /**
565  * \brief the function destroys the mini-script gui structure.
566  */
567 
gms_delete(gms_handle_t * hnd)568 void gms_delete(
569     gms_handle_t *hnd  /**< handle of mini-script data structure */
570     )
571 {
572     if ( hnd != NULL )
573     {
574         gms_private_t *this = GMS_PRIVATE( *hnd ) ;
575         gint i ;
576         gboolean flag = TRUE ;
577 
578         GMS_FREE_FONTDESC(this->w.fontdesc );
579         GMS_FREE_WIDGET(this->w.dlg);
580 
581         g_string_free( this->input_name  ,flag) ;
582         g_string_free( this->output_name ,flag) ;
583         g_string_free( this->filter_name ,flag) ;
584         g_string_free( this->cmd         ,flag) ;
585 
586         for ( i=0;i<GMS_NB_TYPE_SCRIPT ; i++ )
587             g_string_free(this->script_cmd[i] ,flag) ;
588 
589         GMS_G_FREE( this )  ;
590     }
591 }
592 
593 /**
594  * \brief the function runs the mini-script dialog.
595  */
gms_dlg(gms_handle_t hnd)596 int gms_dlg(
597     gms_handle_t hnd /**< handle of mini-script data structure */
598     )
599 {
600     gms_private_t *this = GMS_PRIVATE( hnd ) ;
601     gint ret = 0 ;
602 
603     if ( this == NULL )
604         return 0 ;
605 
606     gtk_widget_show(this->w.dlg);
607     ret = gtk_dialog_run(GTK_DIALOG(this->w.dlg));
608     gtk_widget_hide(this->w.dlg);
609 
610     if ( ret == GTK_RESPONSE_APPLY )
611         return 1 ;
612     else
613         return 0 ;
614 }
615 
616 /**
617  * \brief the function get the input mode.
618  */
gms_get_input_mode(gms_handle_t hnd)619 gms_input_t  gms_get_input_mode(
620     gms_handle_t hnd /**< handle of mini-script data structure */
621     )
622 {
623     gms_private_t *this = GMS_PRIVATE( hnd ) ;
624     gms_input_t mode  = IN_CURRENT_DOC ;
625 
626     if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(this->w.rb_select) ) == TRUE )
627         mode  = IN_SELECTION ;
628     else  if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(this->w.rb_session) ) == TRUE )
629         mode  = IN_DOCS_SESSION ;
630 
631     return mode ;
632 }
633 
634 /**
635  * \brief the function get the output mode.
636  */
gms_get_output_mode(gms_handle_t hnd)637 gms_output_t  gms_get_output_mode(
638     gms_handle_t hnd /**< handle of mini-script data structure */
639     )
640 {
641     gms_private_t *this = GMS_PRIVATE( hnd ) ;
642     gms_output_t mode  = OUT_CURRENT_DOC ;
643 
644     if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(this->w.rb_ndoc) ) == TRUE )
645         mode  = OUT_NEW_DOC ;
646 
647     return mode ;
648 }
649 
650 /**
651  * \brief the function get the input filename for filter input.
652  */
gms_get_in_filename(gms_handle_t hnd)653 gchar *gms_get_in_filename(
654     gms_handle_t hnd /**< handle of mini-script data structure */
655     )
656 {
657     gms_private_t *this = GMS_PRIVATE( hnd ) ;
658     return this->input_name->str ;
659 }
660 
661 /**
662  * \brief the function get the output filename for filter result.
663  */
gms_get_out_filename(gms_handle_t hnd)664 gchar *gms_get_out_filename(
665     gms_handle_t hnd /**< handle of mini-script data structure */
666     )
667 {
668     gms_private_t *this = GMS_PRIVATE( hnd ) ;
669     return this->output_name->str ;
670 }
671 
672 /**
673  * \brief the function get the output filename for filter script.
674  */
gms_get_filter_filename(gms_handle_t hnd)675 gchar *gms_get_filter_filename( gms_handle_t hnd )
676 {
677     gms_private_t *this = GMS_PRIVATE( hnd ) ;
678     return this->filter_name->str ;
679 }
680 
681 /**
682  * \brief the function get the error filename for filter script.
683  */
gms_get_error_filename(gms_handle_t hnd)684 gchar *gms_get_error_filename(
685     gms_handle_t hnd /**< handle of mini-script data structure */
686     )
687 {
688     gms_private_t *this = GMS_PRIVATE( hnd ) ;
689     return this->error_name->str ;
690 }
691 
692 /**
693  * \brief the function creates the filter file.
694  */
gms_create_filter_file(gms_handle_t hnd)695 void  gms_create_filter_file(
696     gms_handle_t hnd /**< handle of mini-script data structure */
697     )
698 {
699     gms_private_t *this = GMS_PRIVATE( hnd ) ;
700     gchar           *contents = NULL;
701     GtkTextIter      start;
702     GtkTextIter      end;
703     GtkTextBuffer   *text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW( this->w.t_script ) );
704 
705     gtk_text_buffer_get_start_iter(text_buffer,&start);
706     gtk_text_buffer_get_end_iter(text_buffer,&end);
707     contents=gtk_text_buffer_get_text(text_buffer,&start,&end,FALSE);
708     g_file_set_contents(this->filter_name->str, contents, -1 , NULL );
709     GMS_G_FREE(contents);
710 }
711 
712 /**
713  * \brief the function creates the command string.
714  */
gms_get_str_command(gms_handle_t hnd)715 gchar *gms_get_str_command(
716     gms_handle_t hnd /**< handle of mini-script data structure */
717     )
718 {
719     gms_private_t *this = GMS_PRIVATE( hnd ) ;
720     gint ii_script = gtk_combo_box_get_active(GTK_COMBO_BOX(this->w.cb_st) ) ;
721 
722     g_string_printf( this->cmd,"cat %s | %s %s > %s 2> %s",
723                                 this->input_name->str,
724                                     this->script_cmd[ii_script]->str,
725                                         this->filter_name->str,
726                                             this->output_name->str,
727                                                 this->error_name->str );
728     return this->cmd->str  ;
729 }
730 
731 /**
732  * \brief the function creates the configuration gui.
733  */
734 
gms_configure_gui(gms_handle_t hnd)735 GtkWidget   *gms_configure_gui(
736     gms_handle_t hnd /**< handle of mini-script data structure */
737     )
738 {
739     gms_private_t *this = GMS_PRIVATE( hnd ) ;
740 
741     volatile gint ii ;
742     GtkWidget *vb_pref        ; /*!< vbox for mini-script configuration */
743     GtkWidget  *f_script      ; /*!< frame for configuration script */
744     GtkWidget  *t_script      ; /*!< table for configuration script */
745     GtkWidget  *w ;
746 
747     vb_pref= gtk_vbox_new(FALSE, 6);
748     f_script = gtk_frame_new (_("script configuration") );
749     gtk_box_pack_start( GTK_BOX (vb_pref), f_script, FALSE, FALSE, 0);
750 
751     t_script = gtk_table_new( GMS_NB_TYPE_SCRIPT ,3,FALSE) ;
752     gtk_container_add (GTK_CONTAINER (f_script), t_script );
753 
754     for ( ii = 0 ; ii <GMS_NB_TYPE_SCRIPT ;ii++ )
755     {
756         w = gtk_label_new(label_script_cmd[ii]);
757         gtk_table_attach_defaults(GTK_TABLE(t_script),w, 0,1,ii,ii+1 );
758 
759         this->w.e_script[ii] = gtk_entry_new();
760         gtk_entry_set_text(GTK_ENTRY(this->w.e_script[ii]), this->script_cmd[ii]->str);
761         gtk_table_attach_defaults(GTK_TABLE(t_script),this->w.e_script[ii], 1,2,ii,ii+1 );
762     }
763 
764     gtk_widget_show_all(vb_pref);
765     return vb_pref ;
766 }
767 
768 /**
769  * \brief Callback associated to a button "new"
770  */
on_gms_configure_response(GtkDialog * dialog,gint response,gpointer user_data)771 void on_gms_configure_response(GtkDialog *dialog, gint response, gpointer user_data   )
772 {
773     if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY)
774     {
775         int  ii ;
776         gms_private_t *this = GMS_PRIVATE(user_data) ;
777 
778         for ( ii = 0 ; ii <GMS_NB_TYPE_SCRIPT ;ii++ )
779             if (this->w.e_script[ii]!=NULL )
780                 g_string_assign( this->script_cmd[ii] , gtk_entry_get_text(GTK_ENTRY(this->w.e_script[ii])));
781         save_prefs_file(this);
782     }
783 }
784