Logo Search packages:      
Sourcecode: vertex version File versions

editoridialog.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 "editor.h"
#include "editoridialog.h"
#include "editoridialogcb.h"

#include "config.h"

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


#include "images/icon_ok_20x20.xpm"
#include "images/icon_select_20x20.xpm"
#include "images/icon_cancel_20x20.xpm"
#include "images/icon_help_20x20.xpm"


gint EditorIDialogCreate(
      ma_editor_struct *editor, ma_editor_idialog_struct *d
);
void EditorIDialogRecordWidget(
      ma_editor_idialog_struct *d, GtkWidget *w
);
GtkWidget *EditorIDialogGetWidget(
      ma_editor_idialog_struct *d, gint n
);
GtkWidget *EditorIDialogClientParent(ma_editor_idialog_struct *d);
void EditorIDialogReset(
        ma_editor_struct *editor, ma_editor_idialog_struct *d,
      gbool need_unmap
);
void EditorIDialogDestroy(
      ma_editor_struct *editor, ma_editor_idialog_struct *d
);

gint EditorIDialogMap(
        ma_editor_struct *editor, ma_editor_idialog_struct *d,
        const gchar *title,
        const gchar *ok_label, const gchar *apply_label,
        const gchar *cancel_label,
        gpointer client_data,
        void (*func_ok_cb)(gpointer, gpointer),
        void (*func_apply_cb)(gpointer, gpointer),
        void (*func_cancel_cb)(gpointer, gpointer)
);
void EditorIDialogUnmap(
        ma_editor_struct *editor, ma_editor_idialog_struct *d
);



/*
 *      Creates widgets for input dialog, intended to be called
 *    by EditorCreate().
 *
 *      All inputs must be valid.  
 */
gint EditorIDialogCreate(
        ma_editor_struct *editor, ma_editor_idialog_struct *d
)
{
      gint  bw = (100 + (2 * 3)),
            bh = (30 + (2 * 3));
        GtkWidget *w, *parent, *parent2;
      GtkWindow *editor_toplevel;
      gpointer label;
        GtkAccelGroup *accelgrp;


        if((editor == NULL) || (d == NULL))
            return(-1);

      /* Get editor's toplevel. */
      editor_toplevel = (GtkWindow *)editor->toplevel;


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

        d->initialized = TRUE;
        d->map_state = FALSE;
         
        d->editor_ptr = editor;

        d->client_widget = NULL;
        d->total_client_widgets = 0;

        d->client_data = NULL;
        d->func_ok_cb = NULL;
      d->func_apply_cb = NULL;
      d->func_cancel_cb = NULL;


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


        /* Toplevel. */
      d->toplevel = w = gtk_window_new(GTK_WINDOW_DIALOG);
        gtk_signal_connect(
            GTK_OBJECT(w), "key_press_event",
            GTK_SIGNAL_FUNC(EditorIDialogKeyEventCB),
            (gpointer)d
        );
        gtk_signal_connect(
            GTK_OBJECT(w), "key_release_event",
            GTK_SIGNAL_FUNC(EditorIDialogKeyEventCB),
            (gpointer)d
        );
        gtk_widget_add_events(
          w,
            GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK
        );
        gtk_widget_realize(w);

        gtk_signal_connect(
            GTK_OBJECT(w), "delete_event",
            GTK_SIGNAL_FUNC(EditorIDialogCloseCB),
            (gpointer)d
        );
        gtk_signal_connect(
            GTK_OBJECT(w), "destroy",
            GTK_SIGNAL_FUNC(EditorIDialogDestroyCB),
            (gpointer)d
        );
        gtk_container_border_width(GTK_CONTAINER(w), 0);
        gtk_accel_group_attach(accelgrp, GTK_OBJECT(w));
      gtk_window_set_transient_for(
          GTK_WINDOW(w), editor_toplevel
      );
        parent = w;


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

      /* Hbox to hold values vbox. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, 5);
        gtk_widget_show(w);
      parent2 = w;

      d->values_vbox_parent = w = gtk_vbox_new(FALSE, 0);
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 5);
        gtk_widget_show(w);

        /* Vbox for client functions to create child widgets on, leave
       * this member set to NULL for now. It will be created later
       * by a call to EditorIDialogClientParent().
       */
        d->values_vbox = NULL;

/* Create help vboxes? */  


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

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

        /* OK button. */
      d->ok_btn = w = GUIButtonPixmapLabelH(   
            (u_int8_t **)icon_ok_20x20_xpm, "OK", &label
        );
        d->ok_btn_label = (GtkWidget *)label;
        gtk_widget_set_usize(w, bw, bh);
        GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);   
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 5);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(EditorIDialogButtonCB),
            (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"
        );

        /* Apply button. */   
      d->apply_btn = w = GUIButtonPixmapLabelH(
            (u_int8_t **)icon_select_20x20_xpm, "Apply", &label
        );
        d->apply_btn_label = (GtkWidget *)label;
        gtk_widget_set_usize(w, bw, bh);
        GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 5);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(EditorIDialogButtonCB),
            d
        );
        gtk_accel_group_add(
            accelgrp, 'a', 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );

        /* Cancel button. */
      d->cancel_btn = w = GUIButtonPixmapLabelH(
            (u_int8_t **)icon_cancel_20x20_xpm, "Cancel", &label
        );
        d->cancel_btn_label = (GtkWidget *)label;
        gtk_widget_set_usize(w, bw, bh);
        GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 5);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(EditorIDialogButtonCB),
            (gpointer)d
        );
        gtk_accel_group_add(
            accelgrp, GDK_Escape, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );

        /* Help button. */
      d->help_btn = w = GUIButtonPixmapLabelH(
            (u_int8_t **)icon_help_20x20_xpm, "Help", &label
        );
        d->help_btn_label = (GtkWidget *)label;
        gtk_widget_set_usize(w, bw, bh);
        GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 5);
        gtk_signal_connect( 
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(EditorIDialogButtonCB),
            (gpointer)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"
        );


        return(0);
}

/*
 *    Records widget w to the client created widgets list on the
 *    editor input dialog d. The value for w can be NULL and will
 *    always be appended to the list.
 */
void EditorIDialogRecordWidget(
        ma_editor_idialog_struct *d, GtkWidget *w 
)
{
      gint n;


      if(d == NULL)
          return;

      if(d->total_client_widgets < 0)
          d->total_client_widgets = 0;

      n = d->total_client_widgets;
      d->total_client_widgets++;
      d->client_widget = (GtkWidget **)realloc(
          d->client_widget,
          d->total_client_widgets * sizeof(GtkWidget *)
      );
      if(d->client_widget == NULL)
      {
          d->total_client_widgets = 0;
          return;
      }

      d->client_widget[n] = w;

      return;
}

/*
 *    Returns the pointer to the nth recorded client widget on d,
 *    the pointer may be NULL if n is out of range or the originally
 *    set pointer was NULL from the client.
 */
GtkWidget *EditorIDialogGetWidget(
        ma_editor_idialog_struct *d, gint n       
)
{
      if(d == NULL)
          return(NULL);

      if((n < 0) || (n >= d->total_client_widgets))
          return(NULL);

      return(d->client_widget[n]);
}

/*
 *    Returns the vbox on the input dialog which client functions should
 *    use to create child widgets on.
 *
 *    Can return NULL on error.
 */
GtkWidget *EditorIDialogClientParent(ma_editor_idialog_struct *d)
{
      GtkWidget *w, *parent;


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

      if(!d->initialized)
          return(NULL);

      /* Get parent for values vbox on the dialog. */
      parent = d->values_vbox_parent;
      if(parent == NULL)
          return(NULL);

      /* Get values vbox which client functions will use to pack
       * their child widgets into.
       */
      w = d->values_vbox;

      /* Values vbox not created yet? */
      if(w == NULL)
      {
          /* Values vbox has not been created yet, so we need to create
           * it now before returning it.
           */
            d->values_vbox = w = gtk_vbox_new(FALSE, 0);
            gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, 0);
            gtk_widget_show(w);
      }

      return(w);
}


/*
 *    Resets all values on the input dialog and destroys
 *    the the values_vbox (if it is not NULL) thus destroying
 *    all client created widgets on the input dialog.
 */
void EditorIDialogReset(  
        ma_editor_struct *editor, ma_editor_idialog_struct *d,
      gbool need_unmap
)
{
      GtkWidget *w;


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

      /* Destroy values vbox which holds all client created child
       * widgets. This will cause all client function created widgets to
       * be destroyed.
       */
      w = d->values_vbox;
      if(w != NULL)
      {
          d->values_vbox = NULL;
          if(GTK_IS_WIDGET(w))
            gtk_widget_destroy(w);
      }

      /* Free list of client created widgets since they have been
       * destroyed when the values_vbox was destroyed.
       */
      free(d->client_widget);
      d->client_widget = NULL;
      d->total_client_widgets = 0;

      /* Reset values. */
      d->client_data = NULL;
      d->func_ok_cb = NULL;
      d->func_apply_cb = NULL;
      d->func_cancel_cb = NULL;

      /* Need to implicitly unmap input dialog? */
      if(need_unmap)
      {
            w = d->toplevel;
            if(w != NULL)  
                gtk_widget_hide(w);

            d->map_state = FALSE;
      }

      return;
}


/*
 *      Deallocates substructures on the input dialog, but not
 *      the input dialog structure itself.
 *
 *    Intended to be called by EditorDelete().
 */
void EditorIDialogDestroy(
        ma_editor_struct *editor, ma_editor_idialog_struct *d
)
{
      GtkWidget **w;


        if(d == NULL)
            return;

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

            w = &d->values_vbox;
          DO_DESTROY_WIDGET

          w = &d->toplevel;
          DO_DESTROY_WIDGET

          /* Free list of client set widgets. */
          g_free(d->client_widget); 
          d->client_widget = NULL;
          d->total_client_widgets = 0;


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

#undef DO_DESTROY_WIDGET
        }

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


/*
 *      Maps the editor's input dialog as needed and sets up
 *    values, returns non-zero if mapping was not successful or
 *    error was encountered.
 *
 *    Does not enter gtk main loop, that is up to the calling
 *    function.
 */
gint EditorIDialogMap(
        ma_editor_struct *editor, ma_editor_idialog_struct *d,
        const gchar *title,
        const gchar *ok_label, const gchar *apply_label,
        const gchar *cancel_label,
        gpointer client_data,
        void (*func_ok_cb)(gpointer, gpointer),
        void (*func_apply_cb)(gpointer, gpointer),
        void (*func_cancel_cb)(gpointer, gpointer)
)
{
        GtkWidget *w, *w2;

        if(d == NULL)
            return(-1);

        if(!d->initialized)
            return(-1);

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

      /* Set up OK button. */
      w = d->ok_btn;
      if(w != NULL)
      {
          w2 = d->ok_btn_label;
          if((ok_label != NULL) && (w2 != NULL))
          {
            gtk_label_set_text(GTK_LABEL(w2), ok_label);
            gtk_widget_grab_focus(w);
            gtk_widget_grab_default(w);
            gtk_widget_show(w);
          }
          else
          {
            gtk_widget_hide(w);
          }
      }

      /* Set up apply button. */
        w = d->apply_btn;
        if(w != NULL) 
        {
            w2 = d->apply_btn_label;
            if((apply_label != NULL) && (w2 != NULL))
            {
                gtk_label_set_text(GTK_LABEL(w2), apply_label);

                /* If ok button is now shown then this is default. */
                if(ok_label == NULL)
            {
                    gtk_widget_grab_focus(w);
                    gtk_widget_grab_default(w);
            }

                gtk_widget_show(w);
            }
            else
            {
                gtk_widget_hide(w);
            }
        }

      /* Set up cancel button. */
        w = d->cancel_btn;
        if(w != NULL)
        {
            w2 = d->cancel_btn_label;
            if((cancel_label != NULL) && (w2 != NULL))
            {
                gtk_label_set_text(GTK_LABEL(w2), cancel_label);

            /* Cancel button is default if the other buttons are not
             * shown.
             */
            if((ok_label == NULL) && (apply_label == NULL))
            {
                    gtk_widget_grab_focus(w);
                gtk_widget_grab_default(w);
            }

                gtk_widget_show(w);
            }
            else
            {
                gtk_widget_hide(w);
            }
        }

      /* Set up values. */
      d->client_data = client_data;
      d->func_ok_cb = func_ok_cb;
      d->func_apply_cb = func_apply_cb;
      d->func_cancel_cb = func_cancel_cb;


      /* Map as needed. */
        if(!d->map_state)
        {
            w = d->toplevel;
            if(w != NULL)
                gtk_widget_show(w);

            d->map_state = TRUE;
        }

        return(0);
}

/*
 *      Unmaps the editor's input dialog as needed.
 */
void EditorIDialogUnmap(
        ma_editor_struct *editor, ma_editor_idialog_struct *d
)
{
        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;
        }

        return;
}

Generated by  Doxygen 1.6.0   Back to index