home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / app / errorconsole.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-17  |  10.0 KB  |  370 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * errorconsole.c - text window for collecting error messages
  5.  * Copyright (C) 1998 Nick Fetchak <nuke@bayside.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20.  */
  21.  
  22. #include "config.h"
  23.  
  24. #include <glib.h>
  25.  
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <sys/types.h>
  30. #ifdef HAVE_DIRENT_H
  31. #include <dirent.h>
  32. #endif
  33. #ifdef HAVE_UNISTD_H
  34. #include <unistd.h>
  35. #endif
  36. #include <errno.h>
  37. #include <fcntl.h>
  38. #include <sys/stat.h>
  39.  
  40. #ifdef G_OS_WIN32
  41. #include <io.h>
  42. #ifndef S_IRUSR
  43. #define S_IRUSR _S_IREAD
  44. #endif
  45. #ifndef S_IWUSR
  46. #define S_IWUSR _S_IWRITE
  47. #endif
  48. #endif
  49.  
  50. #include <gtk/gtk.h>
  51.  
  52. #include "apptypes.h"
  53.  
  54. #include "appenv.h"
  55. #include "commands.h"
  56. #include "gimpui.h"
  57. #include "session.h"
  58. #include "dialog_handler.h"
  59.  
  60. #include "libgimp/gimpintl.h"
  61.  
  62. #define ERRORS_ALL       0
  63. #define ERRORS_SELECTION 1
  64.  
  65. static GtkWidget * error_console = NULL;
  66. static GtkWidget * text;
  67.  
  68.  
  69. static void
  70. error_console_close_callback (GtkWidget    *widget,
  71.                   gpointer     data)
  72. {
  73.   gtk_widget_hide (error_console);
  74.  
  75.   /* FIXME: interact with preferences */
  76.   message_handler = MESSAGE_BOX;
  77. }
  78.  
  79. static void
  80. error_console_clear_callback (GtkWidget    *widget,
  81.                   gpointer     data)
  82. {
  83.   gtk_editable_delete_text
  84.     (GTK_EDITABLE (text), 0, gtk_text_get_length (GTK_TEXT (text)));
  85. }
  86.  
  87. void
  88. error_console_free (void)
  89. {                                     
  90.   if (error_console)
  91.     session_get_window_info (error_console, &error_console_session_info);
  92. }
  93.  
  94. gint
  95. error_console_write_file (gchar *path,
  96.               gint   textscope)
  97. {
  98.   gint fd;
  99.   gint text_length;
  100.   gint bytes_written;
  101.   gchar    *text_contents;
  102.   GtkText *gtext;
  103.  
  104.   gtext = GTK_TEXT (text);
  105.  
  106.   fd = open (path, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
  107.   
  108.   if (fd == -1)
  109.     return FALSE;
  110.  
  111.   if (textscope == ERRORS_ALL)
  112.     {
  113.       text_contents =
  114.         gtk_editable_get_chars (GTK_EDITABLE (text), 0,
  115.                 gtk_text_get_length (GTK_TEXT (text)));
  116.     }
  117.   else
  118.     {
  119.       gint selection_start, selection_end, temp;
  120.       
  121.       selection_start = GTK_TEXT (text)->editable.selection_start_pos;
  122.       selection_end = GTK_TEXT (text)->editable.selection_end_pos;
  123.  
  124.       if (selection_start > selection_end)
  125.         {
  126.       temp = selection_start;
  127.       selection_start = selection_end;
  128.       selection_end = temp;
  129.     }
  130.  
  131.       text_contents = gtk_editable_get_chars (GTK_EDITABLE (text),
  132.                           selection_start,
  133.                           selection_end);
  134.     }
  135.  
  136.   text_length = strlen (text_contents);
  137.  
  138.   if (text_contents && (text_length > 0))
  139.     {
  140.       bytes_written = write (fd, text_contents, text_length);
  141.       
  142.       g_free (text_contents);
  143.       close (fd);
  144.       
  145.       if (bytes_written != text_length)
  146.         return FALSE;
  147.       else
  148.     return TRUE;
  149.     }
  150.  
  151.   close (fd);
  152.   return TRUE;
  153. }
  154.  
  155. static void
  156. error_console_file_ok_callback (GtkWidget *widget,
  157.                 gpointer   data)
  158. {
  159.   GtkWidget *filesel;
  160.   gchar        *filename;
  161.   gint         textscope;
  162.  
  163.   filesel = (GtkWidget *) data;
  164.   filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION (filesel));
  165.   
  166.   textscope = (gint) gtk_object_get_user_data (GTK_OBJECT (filesel));
  167.  
  168.   if (!error_console_write_file (filename, textscope))
  169.     {
  170.       GString    *string;
  171.  
  172.       string = g_string_new ("");
  173.       g_string_sprintf (string, _("Error opening file %s: %s"),
  174.             filename, g_strerror (errno));
  175.       g_message (string->str);
  176.       g_string_free (string, TRUE);
  177.     }
  178.   else
  179.     gtk_widget_destroy (filesel);
  180. }
  181.  
  182. static void
  183. error_console_menu_callback (gint textscope)
  184. {
  185.   GtkWidget *filesel;
  186.  
  187.   if (!(GTK_TEXT (text)->editable.has_selection) &&
  188.       (textscope == ERRORS_SELECTION))
  189.     {
  190.       g_message (_("Can't save, nothing selected!"));
  191.       return;
  192.     }
  193.   
  194.   filesel = gtk_file_selection_new (_("Save error log to file..."));
  195.   gtk_window_set_position (GTK_WINDOW (filesel), GTK_WIN_POS_MOUSE);
  196.   gtk_window_set_wmclass (GTK_WINDOW (filesel), "save_errors", "Gimp");
  197.  
  198.   gtk_container_set_border_width (GTK_CONTAINER (filesel), 2);
  199.   gtk_container_set_border_width (GTK_CONTAINER (GTK_FILE_SELECTION (filesel)->button_area), 2);
  200.  
  201.   gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->cancel_button),
  202.                  "clicked", (GtkSignalFunc) gtk_widget_destroy,
  203.                  GTK_OBJECT (filesel));
  204.  
  205.   gtk_object_set_user_data (GTK_OBJECT (filesel), (gpointer) textscope);
  206.   gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->ok_button),
  207.                 "clicked", (GtkSignalFunc) error_console_file_ok_callback,
  208.               filesel);
  209.  
  210.   gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->cancel_button),
  211.                  "delete_event", (GtkSignalFunc) gtk_widget_destroy,
  212.                  GTK_OBJECT (filesel));
  213.  
  214.   /*  Connect the "F1" help key  */
  215.   gimp_help_connect_help_accel (filesel,
  216.                 gimp_standard_help_func,
  217.                 "dialogs/error_console.html");
  218.  
  219.   gtk_widget_show (filesel);
  220. }
  221.  
  222. static gint
  223. text_clicked_callback (GtkWidget      *widget,
  224.                GdkEventButton *event, 
  225.                gpointer           data)
  226. {
  227.   GtkMenu *menu = (GtkMenu *) data;
  228.   GtkText *gtext;
  229.   
  230.   gtext = GTK_TEXT (text);
  231.  
  232.   switch (event->button)
  233.     {
  234.     case 1:
  235.     case 2:
  236.       break;
  237.  
  238.     case 3:
  239.       gtk_signal_emit_stop_by_name (GTK_OBJECT (text), "button_press_event");
  240.       gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event->button, event->time);
  241.  
  242.       /*  wheelmouse support  */
  243.     case 4:
  244.       {
  245.     GtkAdjustment *adj = gtext->vadj;
  246.     gfloat new_value = adj->value - adj->page_increment / 2;
  247.     new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
  248.     gtk_adjustment_set_value (adj, new_value);
  249.       }
  250.       break;
  251.  
  252.     case 5:
  253.       {
  254.     GtkAdjustment *adj = gtext->vadj;
  255.     gfloat new_value = adj->value + adj->page_increment / 2;
  256.     new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
  257.     gtk_adjustment_set_value (adj, new_value);
  258.       }
  259.       break;
  260.  
  261.     default:
  262.       break;
  263.     }
  264.  
  265.   return TRUE; 
  266. }
  267.  
  268. static void
  269. error_console_create_window (void)
  270. {
  271.   GtkWidget *table;
  272.   GtkWidget *vscrollbar;
  273.   GtkWidget *menu;
  274.   GtkWidget *menuitem;
  275.  
  276.   error_console = gimp_dialog_new (_("GIMP Error Console"), "error_console",
  277.                    gimp_standard_help_func,
  278.                    "dialogs/error_console.html",
  279.                    GTK_WIN_POS_NONE,
  280.                    TRUE, TRUE, FALSE,
  281.  
  282.                    _("Clear"), error_console_clear_callback,
  283.                    NULL, NULL, NULL, FALSE, FALSE,
  284.                    _("Close"), error_console_close_callback,
  285.                    text, NULL, NULL, TRUE, TRUE,
  286.  
  287.                    NULL);
  288.   /* register this one only */
  289.   dialog_register (error_console);
  290.   session_set_window_geometry (error_console, &error_console_session_info,
  291.                    TRUE); 
  292.  
  293.   /* The next line should disappear when setting the size works in SM */
  294.   gtk_widget_set_usize (error_console, 250, 300);
  295.  
  296.   table = gtk_table_new (2, 2, FALSE);
  297.   gtk_table_set_row_spacing (GTK_TABLE (table), 0, 2);
  298.   gtk_table_set_col_spacing (GTK_TABLE (table), 0, 2);
  299.   gtk_container_set_border_width (GTK_CONTAINER (table), 2);
  300.   gtk_container_add (GTK_CONTAINER (GTK_DIALOG (error_console)->vbox), table);
  301.   gtk_widget_show (table);
  302.  
  303.   menu = gtk_menu_new ();
  304.  
  305.   menuitem = gtk_menu_item_new_with_label (_("Write all errors to file..."));
  306.   gtk_menu_append (GTK_MENU (menu), menuitem);
  307.   gtk_signal_connect_object (GTK_OBJECT(menuitem), "activate",
  308.                  (GtkSignalFunc) error_console_menu_callback,
  309.                  (gpointer) ERRORS_ALL);
  310.   gtk_widget_show (menuitem);
  311.   
  312.   menuitem = gtk_menu_item_new_with_label (_("Write selection to file..."));
  313.   gtk_menu_append (GTK_MENU (menu), menuitem);
  314.   gtk_signal_connect_object (GTK_OBJECT(menuitem), "activate",
  315.                  (GtkSignalFunc) error_console_menu_callback,
  316.                  (gpointer) ERRORS_SELECTION);
  317.   gtk_widget_show (menuitem);
  318.  
  319.   /*  The output text widget  */
  320.   text = gtk_text_new (NULL, NULL);
  321.   gtk_text_set_editable (GTK_TEXT (text), FALSE);
  322.   gtk_text_set_word_wrap (GTK_TEXT (text), TRUE);
  323.   gtk_table_attach (GTK_TABLE (table), text, 0, 1, 0, 1,
  324.                     GTK_EXPAND | GTK_SHRINK | GTK_FILL,
  325.                     GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
  326.  
  327.   gtk_widget_set_events (text, GDK_BUTTON_PRESS_MASK);
  328.   gtk_signal_connect (GTK_OBJECT (text), "button_press_event",
  329.               GTK_SIGNAL_FUNC (text_clicked_callback), GTK_MENU (menu));
  330.  
  331.   gtk_widget_show (text);
  332.  
  333.   vscrollbar = gtk_vscrollbar_new (GTK_TEXT (text)->vadj);
  334.   gtk_table_attach (GTK_TABLE (table), vscrollbar, 1, 2, 0, 1,
  335.                     GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
  336.   gtk_widget_show (vscrollbar);
  337.  
  338.   gtk_widget_show (error_console);
  339. }
  340.  
  341. void
  342. error_console_add (gchar *errormsg)
  343. {
  344.   if (!error_console)
  345.     {
  346.       error_console_create_window ();
  347.  
  348.       /* FIMXE: interact with preferences */
  349.       message_handler = ERROR_CONSOLE;
  350.     } 
  351.   else 
  352.     {
  353.       if (!GTK_WIDGET_VISIBLE (error_console))
  354.     {
  355.       gtk_widget_show (error_console);
  356.  
  357.       /* FIXME: interact with preferences */
  358.       message_handler = ERROR_CONSOLE;
  359.     }
  360.       else 
  361.     gdk_window_raise (error_console->window);
  362.     }
  363.     
  364.   if (errormsg)
  365.     {
  366.       gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, errormsg, -1);
  367.       gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, "\n", -1);
  368.     }
  369. }
  370.