Logo Search packages:      
Sourcecode: libjsw version File versions

cdialog.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>

#include "guiutils.h"
#include "cdialog.h"

#ifdef MEMWATCH
# include "memwatch.h"
#endif


/* Message icons. */
#include "images/icon_error_32x32.xpm"
#include "images/icon_info_32x32.xpm"
#include "images/icon_question_32x32.xpm"
#include "images/icon_warning_32x32.xpm"

/* Button icons. */
#include "images/icon_ok_20x20.xpm"
#include "images/icon_cancel_20x20.xpm"
#include "images/icon_help_20x20.xpm"


/* Confirmation dialog structure. */
typedef struct {

        gbool initialized;
        gbool map_state;
        gint last_icon_code;

      GtkAccelGroup     *accelgrp;

        GtkWidget       *toplevel,
                        *main_vbox,
                        *label_hbox,
                        *icon_pm,  
                        *icon_fixed,
                        *label,
                        *help_vbox,
                        *help_icon_pm,
                        *help_icon_fixed,
                        *help_label,
                        *button_hbox;

        GtkWidget       *ok_btn,
                        *yes_btn,
                        *yes_to_all_btn,
                        *no_btn,
                        *cancel_btn,
                        *ignore_btn,
                        *retry_btn,
                        *abort_btn,
                        *help_btn;

} cdialog_struct;


/* Callbacks. */
static void CDialogDestroyCB(GtkObject *object, gpointer data);       
static gint CDialogCloseCB(
      GtkWidget *widget, GdkEvent *event, gpointer data
);
static void CDialogButtonCB(GtkWidget *widget, gpointer data);

static void CDialogSetIcon(cdialog_struct *d, u_int8_t **icon_data);

gint CDialogInit(void);
void CDialogSetTransientFor(GtkWidget *w);
gbool CDialogIsQuery(void);
void CDialogBreakQuery(void);
gint CDialogGetResponse(
        const gchar *title,
        const gchar *message,
        const gchar *explaination,
        gint icon_code,
        guint show_buttons,         /* Any of CDIALOG_BTNFLAG_*. */
        guint default_button        /* One of CDIALOG_BTNFLAG_*. */
);
void CDialogMap(void);
void CDialogUnmap(void);
void CDialogShutdown(void);


#define CDIALOG_BTN_WIDTH     (100 + (2 * 3))
#define CDIALOG_BTN_HEIGHT    (30 + (2 * 3))

#define CDIALOG_NO_HELP_STR   "No help available."


static gint response_code = CDIALOG_RESPONSE_NOT_AVAILABLE;
static gint block_loop_level;
static cdialog_struct cdialog;


/*
 *    Destroy callback.
 */
static void CDialogDestroyCB(GtkObject *object, gpointer data)
{
      return;
}

/*
 *    Dialog close callback.
 */
static gint CDialogCloseCB(GtkWidget *widget, GdkEvent *event, gpointer data)
{
        cdialog_struct *d = (cdialog_struct *)data;
        if((widget == NULL) ||
           (d == NULL)  
        )
            return(FALSE);

      response_code = CDIALOG_RESPONSE_CANCEL;
        gtk_main_quit();
      block_loop_level--;
      return(TRUE);
}

/*
 *    Dialog button callback.
 */
static void CDialogButtonCB(GtkWidget *widget, gpointer data)
{
      GtkWidget *w;
      cdialog_struct *d = (cdialog_struct *)data;
      if((widget == NULL) || (d == NULL))
          return;


      /* Check if button is not shown, which implies this signal
       * was received synthetically or from an keyboard accelerator.
       * in which case we should ignore it.
       */
      if(!GTK_WIDGET_MAPPED(widget))
          return;


      /* Check which button was pressed. */
      if(widget == d->ok_btn)
          response_code = CDIALOG_RESPONSE_OK;
        else if(widget == d->yes_btn)
            response_code = CDIALOG_RESPONSE_YES;
        else if(widget == d->yes_to_all_btn)
            response_code = CDIALOG_RESPONSE_YES_TO_ALL;
        else if(widget == d->no_btn)
            response_code = CDIALOG_RESPONSE_NO;
        else if(widget == d->cancel_btn)
            response_code = CDIALOG_RESPONSE_CANCEL;
        else if(widget == d->help_btn)
      {
            response_code = CDIALOG_RESPONSE_HELP;
          w = d->help_vbox;
          if(w != NULL)
            gtk_widget_show(w);
          w = d->help_btn;
          if(w != NULL)
                gtk_widget_hide(w);

          return; /* Return, do not break out of block loop. */
      }

      /* Need to break out of the blocked loop. */
      gtk_main_quit();
      block_loop_level--;
}


/*
 *    Updates the dialog's icons as needed.
 */
static void CDialogSetIcon(cdialog_struct *d, u_int8_t **icon_data)
{
        GdkGC *gc;
        GtkWidget *w, *window, *pixmap;
        GdkPixmap *gdk_pixmap;
        GdkBitmap *mask;
        GtkStyle *style;
        gint width, height;


        if((d == NULL) || (icon_data == NULL))
            return;

        window = d->toplevel;
        if(window == NULL)
            return;

      /* Get style. */
        style = gtk_widget_get_style(d->toplevel);
      if(style == NULL)
          style = gtk_widget_get_default_style();
      if(style == NULL)
          return;

        gc = style->black_gc;


        /* Get fixed widget as parent(must be valid). */
        w = d->icon_fixed;
        if(w == NULL)
            return;

      /* Create new pixmap. */
        gdk_pixmap = gdk_pixmap_create_from_xpm_d(
            window->window,
            &mask,
            &style->bg[GTK_STATE_NORMAL],
            (gchar **)icon_data
        );
        pixmap = gtk_pixmap_new(gdk_pixmap, mask);
        gdk_window_get_size((GdkWindow *)gdk_pixmap, &width, &height);

        /* Adjust size of fixed widget to fit pixmap. */
        gtk_widget_set_usize(w, width, height);

        /* Put pixmap into fixed widget. */
        gtk_fixed_put(GTK_FIXED(w), pixmap, 0, 0);
      gtk_widget_shape_combine_mask(w, mask, 0, 0);
        gtk_widget_show(pixmap);

      gdk_pixmap_unref(gdk_pixmap);
      if(mask != NULL)
          gdk_bitmap_unref(mask);


        /* Destroy the previous pixmap. */
        if(d->icon_pm != NULL)
            gtk_widget_destroy(d->icon_pm);

      /* Record new pixmap. */
        d->icon_pm = pixmap;


        /* Create the pixmap for the help icon (as needed). */
        w = d->help_icon_fixed;
        if(w == NULL)
            return;

      if(d->help_icon_pm == NULL)
      {
            gdk_pixmap = gdk_pixmap_create_from_xpm_d(
                window->window,
                &mask,
                &style->bg[GTK_STATE_NORMAL],
                (gchar **)icon_help_20x20_xpm
            );
            pixmap = gtk_pixmap_new(gdk_pixmap, mask);
            gdk_window_get_size((GdkWindow *)gdk_pixmap, &width, &height);

            /* Adjust size of fixed widget to fit pixmap. */
            gtk_widget_set_usize(w, width, height);

            /* Put pixmap into fixed widget. */
            gtk_fixed_put(GTK_FIXED(w), pixmap, 0, 0);
          gtk_widget_shape_combine_mask(w, mask, 0, 0);
            gtk_widget_show(pixmap);

          gdk_pixmap_unref(gdk_pixmap);
          if(mask != NULL)
            gdk_bitmap_unref(mask);

          /* Record new pixmap. */
            d->help_icon_pm = pixmap;
      }


      /* Set WM icon for toplevel. */
      GUISetWMIcon(window->window, icon_data);
}


/*
 *    Initializes the confirmation dialog.
 *
 *    Returns non-zero on error.
 */
gint CDialogInit(void)
{
      GtkWidget *w, *parent, *parent2, *parent3, *parent4, *parent5;
      GdkWindow *window;
      GtkAccelGroup *accelgrp;
        cdialog_struct *d = &cdialog;

const gchar *rcstr = "\n\
style \"cdialog-tooltips-style\" { \n\
 bg[NORMAL] = \"#ffffc0\"\n\
 fg[NORMAL] = \"#000000\"\n\
}\n\
widget \"*cdialog-tooltips\" style \"cdialog-tooltips-style\"\n\
";


      /* Reset globals. */
      response_code = CDIALOG_RESPONSE_NOT_AVAILABLE;
      block_loop_level = 0;


      /* Reset values. */
      memset(d, 0x00, sizeof(cdialog_struct));

      d->initialized = TRUE;
      d->map_state = FALSE;
      d->last_icon_code = CDIALOG_ICON_WARNING;

      /* Parse rc string for help style. */
      gtk_rc_parse_string(rcstr);

      /* Keyboard accelerator group. */
      d->accelgrp = accelgrp = gtk_accel_group_new();


        /* Toplevel. */
      d->toplevel = w = gtk_window_new(GTK_WINDOW_DIALOG);
        gtk_widget_realize(w);
      gtk_window_set_title(GTK_WINDOW(w), "Message");
      window = w->window;
      if(window != NULL)
      {
          gdk_window_set_decorations(
            window,
            GDK_DECOR_TITLE | GDK_DECOR_MENU | GDK_DECOR_MINIMIZE
          );
          gdk_window_set_functions(
            window,
            GDK_FUNC_MOVE | GDK_FUNC_MINIMIZE | GDK_FUNC_CLOSE
          );
      }
      gtk_signal_connect(
            GTK_OBJECT(w), "delete_event",
            GTK_SIGNAL_FUNC(CDialogCloseCB),
            (gpointer)d
        );
        gtk_signal_connect(
            GTK_OBJECT(w), "destroy",
            GTK_SIGNAL_FUNC(CDialogDestroyCB),
            (gpointer)d
        );
        gtk_container_border_width(GTK_CONTAINER(w), 0);
        gtk_accel_group_attach(accelgrp, GTK_OBJECT(w));
        parent = w;


      /* Main vbox. */
      d->main_vbox = w = gtk_vbox_new(FALSE, 0);
        gtk_container_add(GTK_CONTAINER(parent), w);
        gtk_widget_show(w);
        parent = w;


      /* Hbox to hold icon and message label. */
      d->label_hbox = w = gtk_hbox_new(FALSE, 0);
        gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, 5);
      gtk_widget_show(w);
      parent2 = w;

      /* Icon box and icon. */
      w = gtk_vbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 5);
        gtk_widget_show(w);
        parent3 = w;

      d->icon_fixed = w = gtk_fixed_new();
        d->icon_pm = NULL;
      gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, FALSE, 0);
        gtk_widget_realize(w);
        gtk_widget_show(w);

      /* Label. */
        d->label = w = gtk_label_new("Are you sure?");
        gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 5);
        gtk_widget_show(w);


      /* Separator. */
      w = gtk_hseparator_new();
        gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
        gtk_widget_show(w);


      /* Vbox containing help label and another separator. */
      w = gtk_vbox_new(FALSE, 0);
      d->help_vbox = w;
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 2);
      /* Do not show this widget. */
      parent2 = w;

        /* Help label hbox, containing icon and help message label. */
        w = gtk_hbox_new(FALSE, 0);
        d->label_hbox = w;
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 5);
        gtk_widget_show(w);
        parent3 = w;

        /* Icon box and icon. */
        w = gtk_vbox_new(FALSE, 0);
        gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, FALSE, 5);
        gtk_widget_show(w);
        parent4 = w;

      d->help_icon_fixed = w = gtk_fixed_new();
      d->help_icon_pm = NULL;
        gtk_box_pack_start(GTK_BOX(parent4), w, TRUE, FALSE, 0);
        gtk_widget_realize(w);
        gtk_widget_show(w);

      /* Help frame, fixed, and label. */
      w = gtk_frame_new(NULL);
      gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_IN);
      gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, 5);
      gtk_widget_show(w);
      parent4 = w;

      w = gtk_fixed_new();
      gtk_container_set_border_width(GTK_CONTAINER(w), 5);
/*    gtk_widget_set_name(w, "gtk-tooltips"); */
      gtk_widget_set_name(w, "cdialog-tooltips");
      gtk_container_add(GTK_CONTAINER(parent4), w);
      gtk_widget_show(w);
      parent5 = w;

      w = gtk_label_new(CDIALOG_NO_HELP_STR);
        d->help_label = w;
        gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_fixed_put(GTK_FIXED(parent5), w, 0, 0);
        gtk_widget_show(w);


        /* Separator. */
        w = gtk_hseparator_new();
        gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
        gtk_widget_show(w);


      /* Buttons hbox. */
      w = gtk_hbox_new(TRUE, 0);
        gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
        gtk_widget_show(w);
        parent2 = w;

      /* OK button. */
      d->ok_btn = w = GUIButtonPixmapLabelH(
          (u_int8_t **)icon_ok_20x20_xpm, "OK", NULL
      );
        gtk_widget_set_usize(w, CDIALOG_BTN_WIDTH, CDIALOG_BTN_HEIGHT);
      GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 0);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(CDialogButtonCB),
            (gpointer)d
        );
        gtk_accel_group_add(
            accelgrp, GDK_space, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_accel_group_add(
            accelgrp, GDK_Return, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_accel_group_add(
            accelgrp, GDK_3270_Enter, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_accel_group_add(
            accelgrp, GDK_KP_Enter, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_accel_group_add(
            accelgrp, GDK_ISO_Enter, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );

      /* Yes button. */
      d->yes_btn = w = GUIButtonPixmapLabelH(
            (u_int8_t **)icon_ok_20x20_xpm, "Yes", NULL
        );
        gtk_widget_set_usize(w, CDIALOG_BTN_WIDTH, CDIALOG_BTN_HEIGHT);
        GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 0);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(CDialogButtonCB),
            (gpointer)d
        );
        gtk_accel_group_add(
            accelgrp, 'y', 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );

        /* Yes to all button. */
      d->yes_to_all_btn = w = GUIButtonPixmapLabelH(
            (u_int8_t **)icon_ok_20x20_xpm, "Yes to all", NULL
        );
        gtk_widget_set_usize(w, CDIALOG_BTN_WIDTH, CDIALOG_BTN_HEIGHT);
        GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 0);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(CDialogButtonCB),
            (gpointer)d
        );
        gtk_accel_group_add(
            accelgrp, 'a', 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );

        /* No button. */  
      d->no_btn = w = GUIButtonPixmapLabelH(
            (u_int8_t **)icon_cancel_20x20_xpm, "No", NULL
        );
        gtk_widget_set_usize(w, CDIALOG_BTN_WIDTH, CDIALOG_BTN_HEIGHT);
        GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 0);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(CDialogButtonCB),
            (gpointer)d
        );
        gtk_accel_group_add(
            accelgrp, 'n', 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );

        /* Cancel button. */
      d->cancel_btn = w = GUIButtonPixmapLabelH(
            (u_int8_t **)icon_cancel_20x20_xpm, "Cancel", NULL
        );
        gtk_widget_set_usize(w, CDIALOG_BTN_WIDTH, CDIALOG_BTN_HEIGHT);
        GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 0);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(CDialogButtonCB),
            (gpointer)d
        );
        gtk_accel_group_add(
            accelgrp, 'c', 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_accel_group_add(
            accelgrp, GDK_Escape, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );

        /* Ignore button. */
      d->ignore_btn = w = GUIButtonPixmapLabelH(
            (u_int8_t **)icon_cancel_20x20_xpm, "Ignore", NULL
        );
        gtk_widget_set_usize(w, CDIALOG_BTN_WIDTH, CDIALOG_BTN_HEIGHT);
        GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 0);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(CDialogButtonCB),
            (gpointer)d
        );
        gtk_accel_group_add(
            accelgrp, 'i', 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );

        /* Retry button. */
      d->retry_btn = w = GUIButtonPixmapLabelH(
            (u_int8_t **)icon_ok_20x20_xpm, "Retry", NULL
        );
        gtk_widget_set_usize(w, CDIALOG_BTN_WIDTH, CDIALOG_BTN_HEIGHT);
        GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 0);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(CDialogButtonCB),
            (gpointer)d
        );
        gtk_accel_group_add(
            accelgrp, 'r', 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );

        /* Abort button. */
      d->abort_btn = w = GUIButtonPixmapLabelH(
            (u_int8_t **)icon_cancel_20x20_xpm, "Abort", NULL
        );
        gtk_widget_set_usize(w, CDIALOG_BTN_WIDTH, CDIALOG_BTN_HEIGHT);
        GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 0);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(CDialogButtonCB),
            (gpointer)d
        );
      /* Use 'b' as the keyboard accel key for "Abort", since 'a' is
       * taken by "Yes To All".
       */
        gtk_accel_group_add(
            accelgrp, 'b', 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );


        /* Help button. */
      d->help_btn = w = GUIButtonPixmapLabelH(
            (u_int8_t **)icon_help_20x20_xpm, "Help", NULL
        );
        gtk_widget_set_usize(w, CDIALOG_BTN_WIDTH, CDIALOG_BTN_HEIGHT);
        GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 0);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(CDialogButtonCB), d
        );
        gtk_accel_group_add(
            accelgrp, 'h', 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_accel_group_add(
            accelgrp, GDK_question, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_accel_group_add(
            accelgrp, GDK_questiondown, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_accel_group_add(
            accelgrp, GDK_Arabic_question_mark, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );


      /* Set default icon. */
      CDialogSetIcon(d, (u_int8_t **)icon_warning_32x32_xpm);


      return(0);
}

/*
 *    Sets dialog to be a transient for the given toplevel window
 *    widget w. If w is NULL then no transient for will be unset.
 */
void CDialogSetTransientFor(GtkWidget *w)
{
        cdialog_struct *d = &cdialog;

      if(!d->initialized)
          return;

      if(d->toplevel != NULL)
      {
          if(w != NULL)
          {
            /* Given widget if not NULL, must be a window. */
            if(!GTK_IS_WINDOW(GTK_OBJECT(w)))
                return;

            gtk_window_set_modal(
                GTK_WINDOW(d->toplevel), TRUE
            );
/*          gtk_grab_add(d->toplevel); */
            gtk_window_set_transient_for(
                GTK_WINDOW(d->toplevel), GTK_WINDOW(w)
            );
          }
          else
          {
            gtk_window_set_modal(
                GTK_WINDOW(d->toplevel), FALSE
            );
            gtk_window_set_transient_for(
                GTK_WINDOW(d->toplevel), NULL
            );
          }
      }
}

/*
 *    Returns TRUE if currently blocking for query.
 */
gbool CDialogIsQuery(void)
{
      if(block_loop_level > 0)
          return(TRUE);
      else
          return(FALSE);
}

/*
 *      Ends query if any and returns a not available response.
 */
void CDialogBreakQuery(void)
{
        response_code = CDIALOG_RESPONSE_NOT_AVAILABLE;

        /* Break out of an additional blocking loops. */
        while(block_loop_level > 0)
        {
            gtk_main_quit();
            block_loop_level--;
        }
        block_loop_level = 0;
}

/*
 *    Block input and wait for a response.
 *
 *    Returns one of CDIALOG_RESPONSE_*.
 *
 *    If any values are set NULL then that value will not be modified
 *    from since the last usage except for explaination. If explaination
 *    is NULL then it will not be reset to the value of
 *    CDIALOG_NO_HELP_STR.
 */
gint CDialogGetResponse(
      const gchar *title,
      const gchar *message,
      const gchar *explaination,
      gint icon_code,
      guint show_buttons,           /* Any of CDIALOG_BTNFLAG_*. */
      guint default_button          /* Any of CDIALOG_BTNFLAG_*. */
)
{
      GtkWidget *w;
      cdialog_struct *d = &cdialog;


      /* Do not handle response if already waiting for a response,
       * return with a not available response code.
       */
      if(block_loop_level > 0)
          return(CDIALOG_RESPONSE_NOT_AVAILABLE);

      /* Reset response code. */
      response_code = CDIALOG_RESPONSE_NOT_AVAILABLE;

      /* Dialog initialized? */
        if(!d->initialized)
            return(response_code);

      /* Change title. */
      if(title != NULL)
      {
          w = d->toplevel;
          if(w != NULL)
            gtk_window_set_title(GTK_WINDOW(w), title);
      }

      /* Set message label text. */
      if(message != NULL)
      {
            w = d->label;
            if(w != NULL)
                gtk_label_set_text(GTK_LABEL(w), message);
      }

      /* Set help message label text. */
      w = d->help_label;
      if(w != NULL)
          gtk_label_set_text(
            GTK_LABEL(w),
            ((explaination == NULL) ? CDIALOG_NO_HELP_STR : explaination)
          );

      /* Update icon. */
      if(icon_code != d->last_icon_code)
      {
          d->last_icon_code = icon_code;
          switch(icon_code)
          {
            case CDIALOG_ICON_ERROR:
            CDialogSetIcon(d, (u_int8_t **)icon_error_32x32_xpm);
            break;

              case CDIALOG_ICON_QUESTION:
                CDialogSetIcon(d, (u_int8_t **)icon_question_32x32_xpm);
                break;

              case CDIALOG_ICON_WARNING:
                CDialogSetIcon(d, (u_int8_t **)icon_warning_32x32_xpm);
                break;

              default:
                CDialogSetIcon(d, (u_int8_t **)icon_info_32x32_xpm);
                break;
          }
      }

      /* Show/hide buttons. */
#define DO_MAP_BUTTON   \
{ \
 if(w != NULL) \
  gtk_widget_show(w); \
}
#define DO_UNMAP_BUTTON \
{ \
 if(w != NULL) \
  gtk_widget_hide(w); \
}
#define DO_DEFAULT_BUTTON     \
{ \
 if(w != NULL) \
 { \
  gtk_widget_grab_focus(w); \
  gtk_widget_grab_default(w); \
 } \
}
#define DO_UNDEFAULT_BUTTON   \
{ \
 if(w != NULL) \
 { \
/*  GTK_WIDGET_UNSET_FLAGS(w, GTK_HAS_DEFAULT); \
  GTK_WIDGET_UNSET_FLAGS(w, GTK_RECEIVES_DEFAULT);  */ \
 } \
}       

      w = d->ok_btn;
      if(show_buttons & CDIALOG_BTNFLAG_OK)
          DO_MAP_BUTTON
      else
          DO_UNMAP_BUTTON
      if(default_button & CDIALOG_BTNFLAG_OK)
          DO_DEFAULT_BUTTON
      else
          DO_UNDEFAULT_BUTTON

      w = d->yes_btn;
        if(show_buttons & CDIALOG_BTNFLAG_YES)
            DO_MAP_BUTTON 
      else
          DO_UNMAP_BUTTON
        if(default_button & CDIALOG_BTNFLAG_YES)
            DO_DEFAULT_BUTTON
        else
            DO_UNDEFAULT_BUTTON

      w = d->yes_to_all_btn;
        if(show_buttons & CDIALOG_BTNFLAG_YES_TO_ALL)
            DO_MAP_BUTTON
        else
            DO_UNMAP_BUTTON
        if(default_button & CDIALOG_BTNFLAG_YES_TO_ALL)
            DO_DEFAULT_BUTTON
        else
            DO_UNDEFAULT_BUTTON

      w = d->no_btn;
        if(show_buttons & CDIALOG_BTNFLAG_NO)
            DO_MAP_BUTTON
        else
            DO_UNMAP_BUTTON
        if(default_button & CDIALOG_BTNFLAG_NO)
            DO_DEFAULT_BUTTON
        else
            DO_UNDEFAULT_BUTTON

      w = d->cancel_btn;
        if(show_buttons & CDIALOG_BTNFLAG_CANCEL)
            DO_MAP_BUTTON
        else
            DO_UNMAP_BUTTON
        if(default_button & CDIALOG_BTNFLAG_CANCEL)
            DO_DEFAULT_BUTTON
        else
            DO_UNDEFAULT_BUTTON

      w = d->ignore_btn;
        if(show_buttons & CDIALOG_BTNFLAG_IGNORE)
            DO_MAP_BUTTON
        else
            DO_UNMAP_BUTTON
        if(default_button & CDIALOG_BTNFLAG_IGNORE)
            DO_DEFAULT_BUTTON
        else
            DO_UNDEFAULT_BUTTON

        w = d->retry_btn;
        if(show_buttons & CDIALOG_BTNFLAG_RETRY)
            DO_MAP_BUTTON
        else
            DO_UNMAP_BUTTON
        if(default_button & CDIALOG_BTNFLAG_RETRY)
            DO_DEFAULT_BUTTON
        else
            DO_UNDEFAULT_BUTTON

        w = d->abort_btn;
        if(show_buttons & CDIALOG_BTNFLAG_ABORT)
            DO_MAP_BUTTON
        else
            DO_UNMAP_BUTTON
        if(default_button & CDIALOG_BTNFLAG_ABORT)
            DO_DEFAULT_BUTTON
        else
            DO_UNDEFAULT_BUTTON

      w = d->help_btn;
        if(show_buttons & CDIALOG_BTNFLAG_HELP)
            DO_MAP_BUTTON
        else
            DO_UNMAP_BUTTON
        if(default_button & CDIALOG_BTNFLAG_HELP)
            DO_DEFAULT_BUTTON
        else
            DO_UNDEFAULT_BUTTON

#undef DO_MAP_BUTTON
#undef DO_UNMAP_BUTTON
#undef DO_DEFAULT_BUTTON
#undef DO_UNDEFAULT_BUTTON

      /* Unmap help vbox initially. */
      w = d->help_vbox;
      if(w != NULL)
          gtk_widget_hide(w);

      /* Since we've setted new values for the widgets, the size of
       * the entire dialog may need to change. Here we need to notify
       * GTK+ about the size change.
       */
      if(d->toplevel != NULL)
          gtk_widget_queue_resize(d->toplevel);


      /* Map dialog. */
      CDialogMap();

      /* Block GUI untill response. */
      block_loop_level++;
      gtk_main();

      /* Unmap dialog. */
      CDialogUnmap();

      /* Break out of an additional blocking loops. */
      while(block_loop_level > 0)
      {
          gtk_main_quit();
          block_loop_level--;
      }
      block_loop_level = 0;

      return(response_code);
}


/*
 *    Maps the confirmation dialog.
 */
void CDialogMap(void)
{
        GtkWidget *w;
        cdialog_struct *d = &cdialog;


        if(d == NULL)
            return;

        if(!d->initialized)
            return;

        if(!d->map_state)
        {
            w = d->toplevel;
            if(w != NULL)
                gtk_widget_show(w);
            
            d->map_state = TRUE;
        }
}

/*
 *    Unmaps the confirmation dialog.
 */
void CDialogUnmap(void)
{
        cdialog_struct *d = &cdialog;
      GtkWidget *w;


      if(d == NULL)
          return;

      if(!d->initialized)
          return;

      if(d->map_state)
      {
          w = d->toplevel;
          if(w != NULL)
            gtk_widget_hide(w);

          d->map_state = FALSE;
      }
}

/*
 *    Shuts down the confirmation dialog.
 */
void CDialogShutdown(void)
{
      GtkWidget **w;
      cdialog_struct *d = &cdialog;


        /* Reset globals. */
        response_code = CDIALOG_RESPONSE_NOT_AVAILABLE;

        /* Break out of an additional blocking loops. */
        while(block_loop_level > 0)
        {
            gtk_main_quit();
            block_loop_level--;
        }
        block_loop_level = 0;

      /* Unmap dialog. */
      CDialogUnmap();

      /* Is dialog initialized? */
      if(d->initialized)
      {
          /* Begin destroying dialog widgets. */

#define DO_DESTROY_WIDGET       \
{ \
 if((*w) != NULL) \
 { \
  GtkWidget *tmp_w = *w; \
  (*w) = NULL; \
  gtk_widget_destroy(tmp_w); \
 } \
}

            w = &d->icon_pm;
          DO_DESTROY_WIDGET

            w = &d->help_icon_pm;
          DO_DESTROY_WIDGET

            w = &d->ok_btn;
            DO_DESTROY_WIDGET
            w = &d->yes_btn;
            DO_DESTROY_WIDGET
            w = &d->yes_to_all_btn;
            DO_DESTROY_WIDGET
            w = &d->no_btn;
            DO_DESTROY_WIDGET
            w = &d->cancel_btn;
            DO_DESTROY_WIDGET
            w = &d->ignore_btn;
            DO_DESTROY_WIDGET
            w = &d->retry_btn;
            DO_DESTROY_WIDGET
            w = &d->abort_btn;
            DO_DESTROY_WIDGET
            w = &d->help_btn;
            DO_DESTROY_WIDGET

          w = &d->toplevel;
          d->main_vbox = NULL;
          d->icon_fixed = NULL;
          d->label = NULL;
            d->label_hbox = NULL;
          d->help_label = NULL;
          d->help_icon_fixed = NULL;
            d->help_vbox = NULL;
          d->button_hbox = NULL;
          DO_DESTROY_WIDGET

          if(d->accelgrp != NULL)
          {
            gtk_accel_group_unref(d->accelgrp);
            d->accelgrp = NULL;
          }

#undef DO_DESTROY_WIDGET
      }

      /* Clear dialog structure. */
      memset(d, 0x00, sizeof(cdialog_struct));
}

Generated by  Doxygen 1.6.0   Back to index