source: trunk/third/gnome-utils/logview/actions.c @ 18366

Revision 18366, 27.5 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18365, which included commits to RCS files with non-trunk default branches.
Line 
1#include <config.h>
2#include "logview.h"
3#include <string.h>
4#include <stdlib.h>
5#include <sys/types.h>
6#include <regex.h>
7#include <gnome.h>
8
9#define MAX_NUM_MATCHES     10
10#define DELIM               ":"
11
12void mon_edit_actions (GtkWidget *widget, gpointer data);
13
14static GList *copy_actions_db (GList *db);
15void free_actions_db (GList **db);
16void free_action (Action *action);
17void print_actions_db (GList *db);
18void make_tree_from_actions_db (GList *db);
19void clear_actions_db (GList *db);
20
21static void edit_actions_entry_cb (GtkWidget *widget, gpointer data);
22static void remove_actions_entry_cb (GtkWidget *widget, gpointer data);
23static void add_actions_entry_cb (GtkWidget *widget, gpointer data);
24static void edit_action_entry (Action *action);
25static void set_atk_relation (GtkWidget *label, GtkWidget *widget);
26
27int exec_action_in_db (Log *log, LogLine *line, GList *db);
28int read_actions_db (char *filename, GList **db);
29int write_actions_db (char *filename, GList *db);
30
31
32
33extern GList *actions_db;
34
35
36static GList *local_actions_db = NULL;
37
38GtkWidget *actions_dialog = NULL;
39GtkWidget *ctree_view;
40GtkTreeStore *ctree = NULL;
41GtkTreeIter *selected_node = NULL;
42GtkTreeIter *ctree_parent = NULL;
43
44static void
45apply_actions (GtkWidget *w, gpointer data)
46{
47        char *fname;
48
49        free_actions_db (&actions_db);
50        actions_db = local_actions_db;
51        local_actions_db = NULL;
52
53        fname = gnome_util_home_file ("gnome-system-log-actions.db");
54        if (write_actions_db (fname, actions_db)) {
55                gtk_widget_destroy (actions_dialog);
56        }
57        g_free (fname);
58}
59
60
61/* ----------------------------------------------------------------------
62   NAME:        mon_edit_actions
63   DESCRIPTION: Create widow where actions are added and changed.
64   ---------------------------------------------------------------------- */
65
66void
67mon_edit_actions (GtkWidget *widget, gpointer data)
68{
69  GtkWidget *hbox;
70  GtkWidget *button;
71  GtkWidget *swin;
72  GtkBox *vbox;
73  GtkWidget *vbox2;
74  const gchar *title[] = {N_("Action database")};
75  GtkCellRenderer *cell_renderer;
76  GtkTreeViewColumn *column;
77  GtkTooltips *tips;
78
79  tips = gtk_tooltips_new ();
80
81  /* Create main window ------------------------------------------------  */
82  actions_dialog = gtk_dialog_new ();
83  gtk_container_set_border_width (GTK_CONTAINER (actions_dialog), 5);
84  gtk_window_set_title (GTK_WINDOW (actions_dialog), _("Actions"));
85  gtk_widget_set_size_request (actions_dialog, 400, -1);
86
87  button = gtk_dialog_add_button (GTK_DIALOG (actions_dialog),
88                      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
89  gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
90                      GTK_SIGNAL_FUNC (gtk_widget_destroy),
91                      GTK_OBJECT (actions_dialog));
92  button = gtk_dialog_add_button (GTK_DIALOG (actions_dialog),
93                      GTK_STOCK_OK, GTK_RESPONSE_OK);
94  gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
95                      GTK_SIGNAL_FUNC (apply_actions),
96                      GTK_OBJECT (actions_dialog));
97  gtk_dialog_set_default_response (GTK_DIALOG (actions_dialog), GTK_RESPONSE_OK);
98
99  vbox = GTK_BOX (GTK_DIALOG (actions_dialog)->vbox);
100
101  hbox = gtk_hbox_new (FALSE, 2);
102  gtk_box_pack_start (vbox, hbox, TRUE, TRUE, 0);
103  gtk_widget_show (hbox);
104
105  /* List with actions */
106
107  ctree = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
108  cell_renderer = gtk_cell_renderer_text_new ();
109  ctree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (ctree));
110  g_object_unref (G_OBJECT (ctree));
111  column = gtk_tree_view_column_new_with_attributes (*title, cell_renderer,
112                                                     "text", 0, NULL);
113  gtk_tree_view_append_column (GTK_TREE_VIEW (ctree_view), column);
114  selected_node = NULL;
115  swin = gtk_scrolled_window_new (NULL, NULL);
116  gtk_container_add (GTK_CONTAINER (swin), GTK_WIDGET (ctree_view));
117  gtk_tree_view_set_reorderable (GTK_TREE_VIEW (ctree_view), TRUE);
118  gtk_widget_set_size_request (GTK_WIDGET (ctree_view), -1, 300);
119
120/* ----------------------------------------------------------------------
121  gtk_signal_connect (GTK_OBJECT (ctree), "button_press_event",
122  GTK_SIGNAL_FUNC (button_press), NULL);
123  gtk_signal_connect_after (GTK_OBJECT (ctree), "button_press_event",
124  GTK_SIGNAL_FUNC (after_press), NULL);
125  gtk_signal_connect (GTK_OBJECT (ctree), "button_release_event",
126  GTK_SIGNAL_FUNC (button_release), NULL);
127  gtk_signal_connect_after (GTK_OBJECT (ctree), "button_release_event",
128  GTK_SIGNAL_FUNC (after_press), NULL);
129  gtk_signal_connect_after (GTK_OBJECT (ctree), "tree_move",
130  GTK_SIGNAL_FUNC (after_move), NULL);
131  -------------------------------------------------------------------- */
132
133  gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (swin), TRUE, TRUE, 0);
134  gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), FALSE);
135  gtk_tree_view_column_set_alignment ( GTK_TREE_VIEW_COLUMN (column), 0.1);
136  gtk_tree_selection_set_mode ( (GtkTreeSelection *)gtk_tree_view_get_selection
137                               (GTK_TREE_VIEW (ctree_view)),
138                                GTK_SELECTION_SINGLE);
139  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
140                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
141  gtk_tree_view_column_set_fixed_width ( GTK_TREE_VIEW_COLUMN (column), 300);
142  gtk_widget_show_all (GTK_WIDGET(swin));
143     
144     
145  /* Buttons in the side ------------------------------------------------ */
146
147  vbox2 = gtk_vbox_new (FALSE, 2);
148  gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, TRUE, 0);
149  gtk_box_set_spacing (GTK_BOX (hbox), GNOME_PAD_BIG);
150  gtk_widget_show (vbox2);
151
152  button = gtk_button_new_with_mnemonic (_("_Add"));
153  gtk_signal_connect (GTK_OBJECT (button), "clicked",
154                      GTK_SIGNAL_FUNC (add_actions_entry_cb), NULL);
155  gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
156  gtk_widget_show (button);
157  gtk_tooltips_set_tip (tips, button, "Add an action", NULL);
158 
159  button = gtk_button_new_with_mnemonic (_("_Edit"));
160  gtk_signal_connect (GTK_OBJECT (button), "clicked",
161                      GTK_SIGNAL_FUNC (edit_actions_entry_cb), NULL);
162  gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
163  gtk_widget_show (button);
164  gtk_tooltips_set_tip (tips, button, "Edit an action", NULL);
165 
166  button = gtk_button_new_with_mnemonic (_("_Remove"));
167  gtk_signal_connect (GTK_OBJECT (button), "clicked",
168                      GTK_SIGNAL_FUNC (remove_actions_entry_cb), NULL);
169  gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
170  gtk_widget_show (button);
171  gtk_tooltips_set_tip (tips, button, "Remove an action", NULL);
172
173  /* Copy all actions */
174  free_actions_db (&local_actions_db);
175  local_actions_db = copy_actions_db (actions_db);
176
177  /* Generate tree with action database */
178  make_tree_from_actions_db (local_actions_db);
179
180  gtk_widget_show (actions_dialog);
181}
182
183
184/* ----------------------------------------------------------------------
185   NAME:          make_tree_from_actions_db
186   DESCRIPTION:   Create the tree from the database.
187   ---------------------------------------------------------------------- */
188
189void
190make_tree_from_actions_db (GList *db)
191{
192  char buffer[50];
193  GList *item;
194  GList *sibling = NULL;
195  Action *action;
196  GtkTreeIter newiter;
197
198  /* Create first item */
199  ctree_parent = NULL;
200  buffer[0] = '\0';
201
202  for(item = db; item != NULL; item=item->next)
203    {
204      action = (Action *)item->data;
205      if (strncmp (buffer, action->tag, 49) != 0) {
206          strncpy (buffer, action->tag, 50);
207          buffer[49] = '\0';
208          /* Add an action with a new tag as a top level node(parent node) */ 
209          gtk_tree_store_append (ctree, &newiter, NULL);
210          gtk_tree_store_set (ctree, &newiter, 0, buffer, 1,
211                              (gpointer)action, -1);
212          ctree_parent = gtk_tree_iter_copy (&newiter);
213        }
214      else {
215          /* If Tag of new action is same as an existing action's tag, add
216             the new action as a child to the existing action(parent) */
217
218          gtk_tree_store_append (ctree, &newiter, ctree_parent);
219          gtk_tree_store_set (ctree, &newiter, 0, buffer, 1,
220                              (gpointer)action, -1);
221        }
222    }
223
224  /* done. */
225  return;
226
227}
228
229static int
230action_compare (gconstpointer a, gconstpointer b)
231{
232        const Action *aa = a;
233        const Action *bb = b;
234
235        return strcmp (aa->tag, bb->tag);
236}
237
238
239
240/* ----------------------------------------------------------------------
241   NAME:        read_action_db
242   DESCRIPTION: Reads the database with regular expressions to match.
243   ---------------------------------------------------------------------- */
244
245int
246read_actions_db (char *filename, GList **db)
247{
248  Action *item;
249  FILE *fp;
250  char buffer[1024];
251  char *c1, *tok;
252  int done;
253
254  /* Open regexp DB */
255  fp = fopen (filename, "r");
256  if (fp == NULL)
257    {
258      g_snprintf (buffer, sizeof (buffer),
259                  _("Cannot open action data base <%s>! Open failed."),
260                  filename);
261      ShowErrMessage (buffer);
262      return(-1);
263    }
264
265
266  /* Start parsing file */
267  done = FALSE;
268  buffer[1023] = '\0';
269  while (!done)
270    {
271
272      /* Read line */
273      if (fgets( buffer, 1023, fp) == NULL)
274        {
275          done = TRUE;
276          continue;
277        }
278      /* Skip spaces */
279      c1 = buffer;
280      while (*c1 == ' ' || *c1 == '\t') c1++;
281      if (*c1 == '\0' || *c1 == '\n')
282        continue; /* Nothing to do here */
283      /* Ignore lines that begin with '#' */
284      if (*c1 == '#')
285        continue;
286
287      /* Alloc memory for item */
288      item = g_new0 (Action, 1);
289
290      /* Read TAG */
291      tok = strtok (c1, DELIM);
292      if (tok == NULL)
293        {
294          ShowErrMessage (_("Error parsing actions data base"));
295          free_actions_db (db);
296          return (-1);
297        }
298      strncpy (item->tag, tok, 49);
299      item->tag[49] = '\0';
300
301      /* Read log regexp . */
302      tok = strtok (NULL, DELIM);
303      if (tok != NULL)
304        item->log_name = g_strdup (tok);
305      else
306        {
307          ShowErrMessage (_("Error parsing actions data base"));
308          free_actions_db (db);
309          return (-1);
310        }
311
312      /* Read process regexp . */
313      tok = strtok (NULL, DELIM);
314      if (tok != NULL)
315        item->process = g_strdup (tok);
316      else
317        {
318          ShowErrMessage (_("Error parsing actions data base"));
319          free_actions_db (db);
320          return (-1);
321        }
322
323      /* Read message regexp . */
324      tok = strtok (NULL, DELIM);
325      if (tok != NULL)
326        item->message = g_strdup (tok);
327      else
328        {
329          ShowErrMessage (_("Error parsing actions data base"));
330          free_actions_db (db);
331          return (-1);
332        }
333
334      /* Read description regexp . */
335      tok = strtok (NULL, DELIM);
336      if (tok != NULL)
337        item->description = g_strdup (tok);
338      else
339        {
340          ShowErrMessage (_("Error parsing actions data base"));
341          free_actions_db (db);
342          return (-1);
343        }
344
345      /* Read action regexp . */
346      tok = strtok (NULL, "\0\n");
347      if (tok != NULL)
348        item->action = g_strdup (tok);
349      else
350        {
351          ShowErrMessage (_("Error parsing actions data base"));
352          free_actions_db (db);
353          return (-1);
354        }
355
356     
357      /* Add item to list */
358      if (item != NULL)
359        *db = g_list_append (*db, item);
360    }
361
362  *db = g_list_sort (*db, action_compare);
363
364  return TRUE;
365}
366
367
368/* ----------------------------------------------------------------------
369   NAME:        write_regexp_db
370   DESCRIPTION: This file generates the actions DB file. It assumes that
371                all the entries in each action are valid.
372   ---------------------------------------------------------------------- */
373
374int
375write_actions_db (char *filename, GList *db)
376{
377  GList *item;
378  Action *action;
379  FILE *fp;
380
381 
382  fp = fopen (filename, "w");
383  if (fp == NULL)
384    {
385      ShowErrMessage (_("Can't write to actions database!"));
386      return FALSE;
387    }
388 
389  /* Write a  header to the DB file */
390  fprintf (fp, "#\n# Actions DB\n#\n# Generated by logview. Don't edit by hand\n");
391  fprintf (fp, "# unless you know what you are doing!\n#\n\n");
392 
393  /* Search for daemon in our list */
394  item = g_list_first (db);
395  for (item = g_list_first (db); item != NULL; item=item->next)
396    {
397      action = (Action *)item->data;
398      /* Check that there is a valid entry */
399      if (*action->tag == '\0' || action->log_name == NULL ||
400           action->process == NULL || action->message == NULL ||
401           action->description == NULL ||
402           action->action == NULL)
403        continue;
404
405      /* write entry */
406      fprintf (fp, "%s:%s:%s:%s:%s:%s\n", action->tag,
407               action->log_name, action->process,
408               action->message, action->description,
409               action->action);
410    }
411
412  fclose (fp);
413
414  return TRUE;
415}
416
417/* ----------------------------------------------------------------------
418   NAME:        free_actions_db
419   DESCRIPTION:
420   ---------------------------------------------------------------------- */
421
422void
423free_actions_db (GList **db)
424{
425        if (*db != NULL) {
426                clear_actions_db (*db);
427                g_list_free (*db);
428                *db = NULL;
429        }
430}
431
432/* ----------------------------------------------------------------------
433   NAME:        exec_action_in_db
434   DESCRIPTION: Try to find the error message in line in the database.
435   ---------------------------------------------------------------------- */
436
437int
438exec_action_in_db (Log *log, LogLine *line, GList *db)
439{
440  GList *item;
441  Action *cur_action = NULL;
442  regex_t preg;
443  regmatch_t matches[MAX_NUM_MATCHES];
444  int doesnt_match;
445  pid_t pid;
446
447  /* Search for daemon in our list */
448  for (item = db; item != NULL; item = item->next)
449    {
450      doesnt_match = FALSE;
451      cur_action = (Action *)item->data;
452      regcomp (&preg, cur_action->log_name, REG_EXTENDED);
453      doesnt_match = regexec (&preg, log->name, MAX_NUM_MATCHES, matches, 0);
454      regfree (&preg);
455      if (doesnt_match)
456        continue;
457      regcomp (&preg, cur_action->process, REG_EXTENDED);
458      doesnt_match = regexec (&preg, line->process, MAX_NUM_MATCHES, matches, 0);
459      regfree (&preg);
460      if (doesnt_match)
461        continue;
462      regcomp (&preg, cur_action->message, REG_EXTENDED);
463      doesnt_match = regexec (&preg, line->message, MAX_NUM_MATCHES, matches, 0);
464      regfree (&preg);
465      if (doesnt_match)
466        continue;
467     
468      break;
469    }
470
471  if (item == NULL)
472      return FALSE; /* not in our list */
473
474  /* If there is a non-null action execute it */
475  if (cur_action != NULL)
476   {
477     if ((pid = fork()) < 0)
478      {
479        return FALSE;
480      }
481     else if (pid == 0)
482      {
483        if (execlp(cur_action->action, cur_action->action, NULL) == -1)
484         {
485           ShowErrMessage (_("Error while executing specified action"));
486           exit(1);
487         }
488      }
489   }
490
491  return TRUE;
492}
493
494/* ----------------------------------------------------------------------
495   NAME:        add_actions_entry_cb
496   DESCRIPTION: Add an entry to the actions DB.
497   ---------------------------------------------------------------------- */
498
499static void
500add_actions_entry_cb (GtkWidget *widget, gpointer data)
501{
502  Action *action;
503
504  action = g_new (Action, 1);
505 
506  g_snprintf (action->tag, sizeof (action->tag), _("<empty>"));
507  action->log_name = g_strdup (_("log name regexp"));
508  action->process = g_strdup (_("process regexp"));
509  action->message = g_strdup (_("message regexp"));
510  action->action = g_strdup (_("action to execute when regexps are TRUE"));
511  action->description = g_strdup (_("description"));
512
513  edit_action_entry (action);
514
515}
516
517static void
518remove_actions_entry_cb (GtkWidget *widget, gpointer data)
519{
520  Action *action;
521  GtkTreeSelection *selection;
522  GtkTreeIter newiter;
523  GtkTreeModel *model = NULL;
524  gboolean selected;
525
526  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ctree_view));
527  selected = gtk_tree_selection_get_selected (selection, &model, &newiter);
528  if (selected == FALSE)
529          return;
530
531  selected_node = gtk_tree_iter_copy (&newiter);
532  gtk_tree_model_get (GTK_TREE_MODEL (model), selected_node, 1,
533                      (gpointer)&action, -1);
534
535  if (action != NULL) {
536          local_actions_db = g_list_remove (local_actions_db, action);
537          gtk_tree_store_clear (ctree);
538          selected_node = NULL;
539          make_tree_from_actions_db (local_actions_db);
540  }
541}
542
543/* ----------------------------------------------------------------------
544   NAME:        edit_actions_entry_cb
545   DESCRIPTION: Function called when the edit button is pressed.
546   ---------------------------------------------------------------------- */
547
548static void
549edit_actions_entry_cb (GtkWidget *widget, gpointer data)
550{
551  Action *action;
552  GtkTreeSelection *selection;
553  GtkTreeIter newiter;
554  GtkTreeModel *model = NULL;
555  gboolean selected;
556
557  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ctree_view));
558  selected = gtk_tree_selection_get_selected (selection, &model, &newiter);
559  if (selected == FALSE)
560          return;
561
562  selected_node = gtk_tree_iter_copy (&newiter);
563  gtk_tree_model_get (GTK_TREE_MODEL (model), selected_node, 1,
564                      (gpointer)&action, -1);
565
566  edit_action_entry (action);
567}
568
569static Action *edited_action = NULL;
570
571static void
572apply_edit (GtkWidget *w, gpointer data)
573{
574        char *text;
575        GtkTextBuffer *buffer;
576        GtkTextIter start, end;
577        GtkWidget *action_record = data;
578        GtkWidget *tag =
579                gtk_object_get_data (GTK_OBJECT (action_record), "tag");
580        GtkWidget *log_name =
581                gtk_object_get_data (GTK_OBJECT (action_record), "log_name");
582        GtkWidget *process =
583                gtk_object_get_data (GTK_OBJECT (action_record), "process");
584        GtkWidget *message =
585                gtk_object_get_data (GTK_OBJECT (action_record), "message");
586        GtkWidget *action =
587                gtk_object_get_data (GTK_OBJECT (action_record), "action");
588        GtkWidget *description =
589                gtk_object_get_data (GTK_OBJECT (action_record), "description");
590
591        text = gtk_editable_get_chars (GTK_EDITABLE (tag), 0, -1);
592        strncpy (edited_action->tag, text, 50);
593        edited_action->tag[49] = '\0';
594
595        g_free (edited_action->log_name);
596        edited_action->log_name =
597                gtk_editable_get_chars (GTK_EDITABLE (log_name), 0, -1);
598        g_free (edited_action->process);
599        edited_action->process =
600                gtk_editable_get_chars (GTK_EDITABLE (process), 0, -1);
601        g_free (edited_action->message);
602        edited_action->message =
603                gtk_editable_get_chars (GTK_EDITABLE (message), 0, -1);
604        g_free (edited_action->action);
605        edited_action->action =
606                gtk_editable_get_chars (GTK_EDITABLE (action), 0, -1);
607        g_free (edited_action->description);
608        edited_action->description =
609                gtk_editable_get_chars (GTK_EDITABLE (description), 0, -1);
610
611        if ( ! g_list_find (local_actions_db, edited_action))
612                local_actions_db = g_list_prepend (local_actions_db,
613                                                   edited_action);
614
615        local_actions_db = g_list_sort (local_actions_db,
616                                        action_compare);
617
618        gtk_tree_store_clear (ctree);
619        selected_node = NULL;
620        make_tree_from_actions_db (local_actions_db);
621}
622
623/* ----------------------------------------------------------------------
624   NAME:        edit_action_entry
625   DESCRIPTION: Edit a DB record on a window.
626   ---------------------------------------------------------------------- */
627
628static void
629edit_action_entry (Action *action)
630{
631  GtkWidget *hbox;
632  GtkWidget *label;
633  GtkWidget *text;
634  GtkWidget *entry;
635  GtkWidget *action_record;
636  GtkWidget *button;
637  GtkBox *vbox;
638  GtkTooltips *tips;
639
640  if (!action)
641    return;
642
643  edited_action = action;
644 
645  /* Create main window ------------------------------------------------  */
646  action_record = gtk_dialog_new ();
647
648  gtk_window_set_title (GTK_WINDOW (action_record), "Edit Action");
649  button = gtk_dialog_add_button (GTK_DIALOG (action_record),
650               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
651  gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
652                      GTK_SIGNAL_FUNC (gtk_widget_destroy),
653                      GTK_OBJECT (action_record));
654
655  button = gtk_dialog_add_button (GTK_DIALOG (action_record),
656               GTK_STOCK_OK, GTK_RESPONSE_OK);
657  gtk_signal_connect (GTK_OBJECT (button), "clicked",
658                      GTK_SIGNAL_FUNC (apply_edit),
659                      action_record);
660  gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
661                      GTK_SIGNAL_FUNC (gtk_widget_destroy),
662                      GTK_OBJECT (action_record));
663  gtk_dialog_set_default_response (GTK_DIALOG (action_record), GTK_RESPONSE_OK);
664  gtk_container_set_border_width (GTK_CONTAINER (action_record), 5);
665  gtk_widget_set_size_request (action_record, 375, -1);
666
667
668  vbox = GTK_BOX (GTK_DIALOG(action_record)->vbox);
669
670  /* Show fields to edit ----------------------------------------------- */
671  tips = gtk_tooltips_new ();
672
673  /* Tag */
674  hbox = gtk_hbox_new (FALSE, 2);
675  gtk_box_pack_start (vbox, hbox, FALSE, FALSE, 0);
676  gtk_widget_show (hbox);
677  label = gtk_label_new_with_mnemonic ("_Tag:");
678  gtk_widget_set_size_request (label, 60, -1);
679  gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
680  gtk_widget_show (label);
681  entry = gtk_entry_new ();
682  gtk_widget_set_size_request (entry, 200, -1);
683  gtk_entry_set_editable (GTK_ENTRY (entry), TRUE);
684  gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
685  gtk_entry_set_text (GTK_ENTRY (entry), action->tag);
686  gtk_tooltips_set_tip (tips, entry, "Tag that identifies the log file.", NULL);
687  gtk_widget_show (entry);
688  gtk_object_set_data (GTK_OBJECT (action_record), "tag", entry);
689  set_atk_relation (label, entry);
690
691  /* log name */
692  hbox = gtk_hbox_new (FALSE, 2);
693  gtk_box_pack_start (vbox, hbox, FALSE, FALSE, 0);
694  gtk_widget_show (hbox);
695  label = gtk_label_new_with_mnemonic ("_Log name:");
696  gtk_widget_set_size_request (label, 60, -1);
697  gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
698  gtk_widget_show (label);
699  entry = gtk_entry_new ();
700  gtk_widget_set_size_request (entry, 200, -1);
701  gtk_entry_set_editable (GTK_ENTRY (entry), TRUE);
702  gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
703  gtk_entry_set_text (GTK_ENTRY (entry), action->log_name);
704  gtk_tooltips_set_tip (tips, entry, "Regular expression that will match the log name.",
705                        NULL);
706  gtk_widget_show (entry);
707  gtk_object_set_data (GTK_OBJECT (action_record), "log_name", entry);
708  set_atk_relation (label, entry);
709     
710  /* Process */
711  hbox = gtk_hbox_new (FALSE, 2);
712  gtk_box_pack_start (vbox, hbox, FALSE, FALSE, 0);
713  gtk_widget_show (hbox);
714  label = gtk_label_new_with_mnemonic ("_Process:");
715  gtk_widget_set_size_request (label, 60, -1);
716  gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
717  gtk_widget_show (label);
718  entry = gtk_entry_new ();
719  gtk_widget_set_size_request (entry, 200, -1);
720  gtk_entry_set_editable (GTK_ENTRY (entry), TRUE);
721  gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
722  gtk_entry_set_text (GTK_ENTRY (entry), action->process);
723  gtk_tooltips_set_tip (tips, entry, "Regular expression that will match process part of message.",
724                        NULL);
725  gtk_widget_show (entry);
726  gtk_object_set_data (GTK_OBJECT (action_record), "process", entry);
727  set_atk_relation (label, entry);
728
729  /* Message */
730  hbox = gtk_hbox_new (FALSE, 2);
731  gtk_box_pack_start (vbox, hbox, FALSE, FALSE, 0);
732  gtk_widget_show (hbox);
733  label = gtk_label_new_with_mnemonic ("_Message:");
734  gtk_widget_set_size_request (label, 60, -1);
735  gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
736  gtk_widget_show (label);
737  entry = gtk_entry_new ();
738  gtk_widget_set_size_request (entry, 200, -1);
739  gtk_entry_set_editable (GTK_ENTRY (entry), TRUE);
740  gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
741  gtk_entry_set_text (GTK_ENTRY (entry), action->message);
742  gtk_tooltips_set_tip (tips, entry, "Regular expression that will match the message.",
743                        NULL);
744  gtk_widget_show (entry);
745  gtk_object_set_data (GTK_OBJECT (action_record), "message", entry);
746  set_atk_relation (label, entry);
747
748  /* Action */
749  hbox = gtk_hbox_new (FALSE, 2);
750  gtk_box_pack_start (vbox, hbox, FALSE, FALSE, 0);
751  gtk_widget_show (hbox);
752  label = gtk_label_new_with_mnemonic ("_Action:");
753  gtk_widget_set_size_request (label, 60, -1);
754  gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
755  gtk_widget_show (label);
756  entry = gtk_entry_new ();
757  gtk_widget_set_size_request (entry, 200, -1);
758  gtk_entry_set_editable (GTK_ENTRY (entry), TRUE);
759  gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
760  gtk_entry_set_text (GTK_ENTRY (entry), action->action);
761  gtk_tooltips_set_tip (tips, entry, "Action that will be executed if all previous regexps. are matched. This is executed by a system command: system (action).",
762                        NULL);
763  gtk_widget_show (entry);
764  gtk_object_set_data (GTK_OBJECT (action_record), "action", entry);
765  set_atk_relation (label, entry);
766
767  /* Description */
768  hbox = gtk_hbox_new (FALSE, 2);
769  gtk_box_pack_start (vbox, hbox, FALSE, FALSE, 0);
770  gtk_widget_show (hbox);
771  label = gtk_label_new_with_mnemonic (_("_Description:"));
772  gtk_widget_set_size_request (label, 60, -1);
773  gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
774  gtk_widget_show (label);
775  text = gtk_entry_new ();
776  gtk_widget_set_size_request (text, 200, -1);
777  gtk_entry_set_editable (GTK_ENTRY (text), TRUE);
778  gtk_box_pack_start (GTK_BOX (hbox), text, TRUE, TRUE, 0);
779  gtk_entry_set_text (GTK_ENTRY (text), action->description);
780  gtk_tooltips_set_tip (tips, text, _("Description of this entry."), NULL);
781  gtk_widget_show (text);
782  gtk_object_set_data (GTK_OBJECT (action_record), "description", text);
783  set_atk_relation (label, text);
784
785  gtk_widget_show (action_record);
786}
787
788/* ----------------------------------------------------------------------
789   NAME:        print_actions_db
790   DESCRIPTION: Prints the database (for debbuging purposes).
791   ---------------------------------------------------------------------- */
792
793void
794print_actions_db (GList *db)
795{
796  GList *item;
797  Action *action;
798
799  /* Search for daemon in our list */
800 
801  for (item = g_list_first (db); item != NULL; item = item->next)
802    {
803      action = (Action *)item->data;
804      printf (_("tag: [%s]\nlog_name: [%s]\nprocess: [%s]\nmessage: [%s]\n"
805                "description: [%s]\naction: [%s]\n"),
806              action->tag,
807              action->log_name,
808              action->process,
809              action->message,
810              action->description,
811              action->action);
812    }
813     
814  return;
815
816}
817
818
819/* ----------------------------------------------------------------------
820   NAME:        clear_actions_db
821   DESCRIPTION: Free all memory used by actions DB.
822   ---------------------------------------------------------------------- */
823
824void
825clear_actions_db (GList *db)
826{
827  GList *item;
828  Action *action;
829
830  for (item = g_list_first (db); item != NULL; item = item->next)
831    {
832      action = (Action *)item->data;
833      free_action (action);
834      item->data = NULL;
835    }
836   
837  return;
838
839}
840
841/* ----------------------------------------------------------------------
842   NAME:        free_action
843   DESCRIPTION: Given an action struct, clear it.
844   ---------------------------------------------------------------------- */
845
846void
847free_action (Action *action)
848{
849        if (action) {
850                g_free (action->log_name);
851                g_free (action->process);
852                g_free (action->message);
853
854                g_free (action->action);
855                g_free (action->description);
856
857                g_free (action);
858        }
859}
860
861static GList *
862copy_actions_db (GList *db)
863{
864        GList *li;
865        GList *copy;
866
867        if (db == NULL)
868                return NULL;
869
870        copy = g_list_copy (db);
871        for (li = copy; li != NULL; li = li->next) {
872                Action *old = li->data;
873                Action *new = g_new0 (Action, 1);
874
875                /* these are the same size so strcpy is safe */
876                strcpy (new->tag, old->tag);
877
878                new->log_name = g_strdup (old->log_name);
879                new->process = g_strdup (old->process);
880                new->message = g_strdup (old->message);
881                new->action = g_strdup (old->action);
882                new->description = g_strdup (old->description);
883                li->data = new;
884        }
885
886        return copy;
887}
888
889static void
890set_atk_relation (GtkWidget *label, GtkWidget *widget)
891{
892        AtkObject *atk_widget;
893        AtkObject *atk_label;
894        AtkRelationSet *relation_set;
895        AtkRelation *relation;
896        AtkObject *targets[1];
897        atk_widget = gtk_widget_get_accessible (widget);
898        atk_label = gtk_widget_get_accessible (label);
899
900        /* Set label-for relation */
901        gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
902
903        /* Check if gail is loaded */
904        if (GTK_IS_ACCESSIBLE (atk_widget) == FALSE)
905                return;
906
907        /* Set labelled-by relation */
908        relation_set = atk_object_ref_relation_set (atk_widget);
909        targets[0] = atk_label;
910        relation = atk_relation_new (targets, 1, ATK_RELATION_LABELLED_BY);
911        atk_relation_set_add (relation_set, relation);
912        g_object_unref (G_OBJECT (relation));
913}
914
Note: See TracBrowser for help on using the repository browser.