Logo Search packages:      
Sourcecode: vertex version File versions

editortdialog.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include <sys/types.h>
#include <gtk/gtk.h>

#include "../include/string.h"
#include "../include/strexp.h"

#include "v3dmodel.h"
#include "v3dmp.h"

#include "guiutils.h"

#include "editor.h"
#include "editorlist.h"

#include "editortdialog.h"
#include "editortdialogcb.h"

#include "vmacfg.h"
#include "vmacfglist.h"
#include "vmastyles.h"
#include "vma.h"
#include "config.h"

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


#include "images/icon_search_20x20.xpm"
#include "images/icon_cancel_20x20.xpm"


static char **EditorTDialogParseStringFetch(const char *s, int *count);
static char **EditorTDialogParseStringApply(char *s, int *count);

void EditorTDialogSetValues(
      ma_editor_tdialog_struct *d,
      int model_num,
      int primitive_num
);
void EditorTDialogClear(ma_editor_tdialog_struct *d);
void EditorTDialogFetch(
        ma_editor_struct *editor, ma_editor_tdialog_struct *d 
);
void EditorTDialogApply(
        ma_editor_struct *editor, ma_editor_tdialog_struct *d
);

gbool EditorTDialogDoFind(
        ma_editor_tdialog_struct *d, GtkText *text,
        char *haystack, char *needle,
        int haystack_len, int start_pos,
        gbool case_sensitive,
        gbool move_to,
        gbool *search_wrapped
);

int EditorTDialogCreate(
        ma_editor_struct *editor, ma_editor_tdialog_struct *d
);
void EditorTDialogReset(
      ma_editor_tdialog_struct *d, gbool need_unmap
);
void EditorTDialogUpdateAppearance(ma_editor_tdialog_struct *d);
void EditorTDialogUpdateMenus(ma_editor_tdialog_struct *d);
void EditorTDialogDestroy(
        ma_editor_struct *editor, ma_editor_tdialog_struct *d
);


#define MAX(a,b)        (((a) > (b)) ? (a) : (b))
#define MIN(a,b)        (((a) < (b)) ? (a) : (b))
#define CLIP(a,l,h)     (MIN(MAX((a),(l)),(h)))

#define ISCR(c)         (((c) == '\n') || ((c) == '\r'))


/*
 *    Called by EditorTDialogFetch() to take the given string and
 *    reformat it for fetching.
 *
 *    Returns a new dynamically allocated array of strings which must be
 *    deallocated by the calling function.
 *
 *    Any occurance of '\n' will be replaced with a '\\' and '\n'
 *    character then the string terminated and a new string allocated.
 */
static char **EditorTDialogParseStringFetch(const char *s, int *count)
{
      char **strv, *strptr;
      int i, strc = 0;


      if((s == NULL) || (count == NULL))
          return(NULL);

      /* If given string is empty, return single string. */
      if((*s) == '\0')
      {
          strc = 1;
          strv = (char **)calloc(strc, sizeof(char *));
          if(strv == NULL)
          {
            strc = 0;
          }
          else
          {
            strv[strc - 1] = strdup("");
          }

          (*count) = strc;
          return(strv);
      }

      /* Explode string at all '\n' deliminators. */
      strv = strchrexp(s, '\n', &strc);

      /* More than 1 string exploded? */
      if(strc > 1)
      {
          /* Itterate through each string except for last string. */
          for(i = 0; i < (strc - 1); i++)
          {
            strptr = strv[i];
            if(strptr == NULL)
                continue;

            strv[i] = strcatalloc(strptr, "\\");
          }
      }

      (*count) = strc;
      return(strv);
}

/*
 *      Called by EditorTDialogApply() to take the given string and
 *      reformat it for apply.
 *
 *      Returns a new dynamically allocated array of strings which must be
 *      deallocated by the calling function.
 *
 *      Any occurance of '\\' and '\n' will be replaced with a '\n'.
 *
 *    Given string s may be modified.
 */
static char **EditorTDialogParseStringApply(char *s, int *count)
{
      char *last, *cur, *end, *strptr, **strv = NULL;
      int len, strn, strc = 0;


        if((s == NULL) || (count == NULL))
            return(NULL);

      /* Explode by deliminating at each '\n' character but not
       * '\\' and '\n' characters.
       */
      last = cur = s;
      while(1)
      {
          strn = strc;
          strc = strn + 1;
          strv = (char **)realloc(strv, strc * sizeof(char *));
          if(strv == NULL)
          {
            strc = 0;
            (*count) = strc;
            return(NULL);
          }
          else
          {
            strv[strn] = NULL;
          }

          /* Seek to next deliminator if any from cur (not last). */
          end = strchr(cur, '\n');
          if(end != NULL)
          {
            /* Check if deliminator had a '\\' prefixing it. */
            if((end > s) ? ((*(end - 1)) == '\\') : 0)
            {
                /* Shorten the given string s at ptr position
                 * end - 1.
                 */
                char *sp;
                for(sp = end - 1; (*sp) != '\0'; sp++)
                  (*sp) = (*(sp + 1));

                cur = end + 0;      /* Seek to end, which is shifted. */
                strc--; /* Don't allocate a new string. */
            }
            else
            {
                /* Plain '\n' deliminator. */
                len = (int)(end - last);
                strptr = (char *)malloc(
                  (len + 1) * sizeof(char)
                );
                if(strptr != NULL)
                {
                  if(len > 0)
                      memcpy(strptr, last, len);
                  strptr[len] = '\0';
                  strv[strn] = strptr;
                }

                last = cur = end + 1;
            }
          }
          else
          {
            /* No more deliminators, last string. */
            strv[strn] = strdup(last);
            break;
          }
      }

      /* If last string is empty, remove it from the list. */
      if(strc > 0)
      {
          strptr = strv[strc - 1];
          if((*strptr) == '\0')
          {
            free(strptr);
            strc--;
          }
      }
      if(strc <= 0)
      {
          strc = 0;
          free(strv);
          strv = NULL;
      }

      (*count) = strc;
      return(strv);
}

/*
 *    Updates the text dialog's referance numbers to the model and
 *    primitive. Any input can be -1.
 */
void EditorTDialogSetValues(
        ma_editor_tdialog_struct *d,
        int model_num,     
        int primitive_num
)
{
        if(d == NULL)
            return;

      d->model_num = model_num;
      d->primitive_num = primitive_num;

      return;
}

/*
 *    Clears all text in the text dialog's text widget and resets its
 *    has_changes to FALSE.
 */
void EditorTDialogClear(ma_editor_tdialog_struct *d)
{
      GtkText *text;

      if(d == NULL)
          return;

      text = (GtkText *)d->text;
      if(text == NULL)
          return;

      /* Begin clearing text. */
      d->text_operating = TRUE;
      gtk_text_set_point(text, 0);
      gtk_text_freeze(text);
      gtk_editable_delete_text(
          GTK_EDITABLE(text), 0, -1
      );
      gtk_text_thaw(text);
      d->text_operating = FALSE;

      /* Reset has changes (since no more text). */
      d->has_changes = FALSE;

      return;
}

/*
 *      Editor text dialog fetch callback, fetches text value for the
 *      currently selected model and/or primitive on the editor.
 */
void EditorTDialogFetch(
        ma_editor_struct *editor, ma_editor_tdialog_struct *d
)
{
      gint model_num, pn;
      v3d_model_struct *model_ptr;
      gpointer p;
      GtkStyle *style_ptr;
      GtkText *text;
      GdkFont *font;
      gint i, n, strc;
      gchar **strv;
      const gchar *line_ptr;


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

      text = (GtkText *)d->text;
      if(text == NULL)
          return;

      style_ptr = styles_list.text_editable;
      font = ((style_ptr == NULL) ? NULL : style_ptr->font);

      /* Get number and pointer to selected model on editor. */
      model_num = EditorSelectedModelIndex(editor);
      model_ptr = V3DModelListGetPtr(
          editor->model, editor->total_models, model_num
      );
      if(model_ptr == NULL)
          return;

      /* Handle by model type. */
      switch(model_ptr->type)
      {
        case V3D_MODEL_TYPE_STANDARD:
          /* Is exactly one primitive selected? */
          if(editor->total_selected_primitives == 1)
            pn = editor->selected_primitive[0];
          else
            pn = -1;
          /* Get pointer to selected primitive. */
          p = V3DMPListGetPtr(
            model_ptr->primitive, model_ptr->total_primitives,
            pn
          );
          if(p != NULL)
          {
            mp_comment_struct *mp_comment;

            switch(V3DMPGetType(p))
            {
              case V3DMP_TYPE_COMMENT:
                mp_comment = (mp_comment_struct *)p;
                d->text_operating = TRUE;
                gtk_text_set_point(text, 0);
                gtk_text_freeze(text);
                for(i = 0; i < mp_comment->total_lines; i++)
                {
                  strv = EditorTDialogParseStringFetch(
                      mp_comment->line[i], &strc
                  );
                  for(n = 0; n < strc; n++)
                  {
                      line_ptr = (const char *)strv[n];
                      if(line_ptr == NULL)
                        continue;

                      gtk_text_insert(
                        text, font, NULL, NULL,
                        line_ptr, -1
                      );
                      gtk_text_insert(
                        text, font, NULL, NULL,
                        "\n", -1
                      );
                  }
                  StringFreeArray(strv, strc);
                }
                gtk_text_thaw(text);
                d->text_operating = FALSE;
                break;

            }
          }
          break;

        case V3D_MODEL_TYPE_OTHER_DATA:
          d->text_operating = TRUE;
          gtk_text_set_point(text, 0);
          gtk_text_freeze(text);
          for(i = 0; i < model_ptr->total_other_data_lines; i++)
          {
            strv = EditorTDialogParseStringFetch(
                model_ptr->other_data_line[i], &strc
            );
            for(n = 0; n < strc; n++)
            {
                            line_ptr = (const char *)strv[n];
                            if(line_ptr == NULL)
                                continue;
                  
                            gtk_text_insert(
                                text, font, NULL, NULL,
                                line_ptr, -1
                            );
                            gtk_text_insert(
                                text, font, NULL, NULL,
                                "\n", -1
                            );
            }
            StringFreeArray(strv, strc);
          }
          gtk_text_thaw(text);
          d->text_operating = FALSE;
          break;
      }

      return;
}       
 
/*
 *      Editor text dialog apply callback, applies text value to
 *      currently selected model and/or primitive on the editor.
 *
 *    The item for a corresponding primitive (if any) on the editor's
 *    primitives list will be updated as needed.
 */
void EditorTDialogApply(
        ma_editor_struct *editor, ma_editor_tdialog_struct *d
)
{
      gint model_num, pn;
        v3d_model_struct *model_ptr;
      gpointer *p;
        GtkText *text;
      gchar *text_data;


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

        text = (GtkText *)d->text;
        if(text == NULL)
            return;


        /* Get number and pointer to selected model on editor. */
        model_num = EditorSelectedModelIndex(editor);
        model_ptr = V3DModelListGetPtr(
            editor->model, editor->total_models, model_num
        );
        if(model_ptr == NULL)
            return;

        /* Handle by model type. */
        switch(model_ptr->type)
        {
          case V3D_MODEL_TYPE_STANDARD:
            /* Is exactly one primitive selected? */
            if(editor->total_selected_primitives == 1)
                pn = editor->selected_primitive[0];
            else
                pn = -1;
            /* Get pointer to selected primitive. */
            p = V3DMPListGetPtr(
                model_ptr->primitive, model_ptr->total_primitives,
                pn
            );
            if(p != NULL)
            {
                mp_comment_struct *mp_comment;

                switch(V3DMPGetType(p))
                {
                  case V3DMP_TYPE_COMMENT:  
                    mp_comment = (mp_comment_struct *)p;
                    d->text_operating = TRUE;
                text_data = gtk_editable_get_chars(
                  GTK_EDITABLE(text), 0, -1
                );
                if(text_data != NULL)
                {
                  StringFreeArray(
                      mp_comment->line, mp_comment->total_lines
                  );
                  mp_comment->line = EditorTDialogParseStringApply(
                      text_data, &mp_comment->total_lines
                  );
                  g_free(text_data);
                }
                    d->text_operating = FALSE;

                /* Need to update listing on primitives list. */
                EditorListPrimitivesSetComment(
                  editor->primitives_list, pn, p, FALSE
                );
                    break;

                }
            }
            break;

          case V3D_MODEL_TYPE_OTHER_DATA:
            d->text_operating = TRUE;
          text_data = gtk_editable_get_chars(
            GTK_EDITABLE(text), 0, -1
          );
          if(text_data != NULL)
          {
            StringFreeArray(
                model_ptr->other_data_line,
                model_ptr->total_other_data_lines
            );
            model_ptr->other_data_line = EditorTDialogParseStringApply(
                text_data, &model_ptr->total_other_data_lines
            );
            g_free(text_data);
          }
            d->text_operating = FALSE;
            break;
        }
}        


/*
 *      Procedure to find needle from haystack with respect to
 *      the given text widget.
 *
 *      Both needle and haystack may be modified by this function,
 *      but never deallocated.
 *
 *      Given GtkText widget will be updated and instructed to select
 *      the matched text if a match was made. If case_sensitive is TRUE
 *      then the search will be made case sensitive, and if move_to is
 *      set to TRUE then gtk_editable_set_position() will be called to
 *      scroll to the new matched position.
 *
 *      If haystack_len is -1 then strlen() will be called on haystack
 *      to get the actual length. Given start_pos will be sanitized,
 *      if start_pos is >= haystack_len then start_pos will be set to 0.
 *
 *      Returns TRUE if a match is made.
 *
 *      Pointer to search_wrapped will be set to TRUE if a match
 *      was made after a search wrapped through the entire haystack
 *      buffer.
 */
gbool EditorTDialogDoFind(
        ma_editor_tdialog_struct *d, GtkText *text,
        char *haystack, char *needle,
        int haystack_len, int start_pos,
        gbool case_sensitive,
        gbool move_to,
        gbool *search_wrapped
)
{
      ma_editor_struct *editor;
      gchar *bp, *match_ptr;


        /* Reset search wrapped. */
        if(search_wrapped != NULL)
            (*search_wrapped) = FALSE;

        /* Inputs valid? */
        if((d == NULL) || (text == NULL) ||
           (haystack == NULL) || (needle == NULL)
        )
            return(FALSE);

      /* Get pointer to editor. */
      editor = (ma_editor_struct *)d->editor_ptr;
      if(editor == NULL)
          return(FALSE);

        /* Need to get haystack length ourself? */
        if(haystack_len < 0)
            haystack_len = strlen(haystack);

        /* Empty haystack? */
        if(haystack_len < 1)
            return(FALSE);

        /* Empty needle? */
        if((*needle) == '\0')
            return(FALSE);

/*
        EditorSetStatusMessage(editor, "Finding...");
 */

        /* Sanitize starting position. */
        if(start_pos >= haystack_len)
            start_pos = 0;
        else if(start_pos < 0)
            start_pos = 0;


        /* Case insensitive search? */
        if(!case_sensitive)
        {
            /* Need to modify buffers to upper case. */

            /* Modify ending portion of haystack. */
            bp = (char *)(haystack + start_pos);
            while((*bp) != '\0')
            {
                (*bp) = toupper(*bp);
                bp++;
            }

            /* Modify needle. */
            bp = needle;
            while((*bp) != '\0')
            {
                (*bp) = toupper(*bp);
                bp++;
            }
        }


        /* Begin search from starting position. */
        match_ptr = strstr(
            (char *)(haystack + start_pos),
            needle
        );
        if(match_ptr == NULL)
        {
            /* Did not get match, so start from beginning of haystack
             * and search again. First check if this is case insensitive.
             */
            if(!case_sensitive)
            {
                /* Toupper the beginning portion of the buffer. */
                bp = haystack;
                while(bp < (char *)(haystack + start_pos))
                {
                    (*bp) = toupper(*bp);
                    bp++;
                }
            }
            /* Now try match again for the second time starting form the
             * beginning.
             */
            match_ptr = strstr( 
                (char *)(haystack + 0),
                needle
            );
            if(match_ptr != NULL)
            {
                /* Got match the second time, now mark search wrapped
                 * as true.
                 */
                if(search_wrapped != NULL)
                    (*search_wrapped) = TRUE;
            }
        }

/*
        EditorSetStatusMessage(editor, "Find done");
 */

        /* Did we get a match? */
        if(match_ptr == NULL)
        {
            /* Sorry, no match made. */
            return(FALSE);
        }
        else
        {
            /* Got match. */
            int match_start_pos = (int)(match_ptr - haystack);
            int needle_len = strlen(needle);

            if(match_start_pos < 0)
                match_start_pos = 0;

            /* Now modify the text widget, set new cursor position and
             * select the matched string.
             */
            if(1)
            {
                GtkEditable *editable = (GtkEditable *)text;

                /* Scroll to new matched position? */
                if(move_to)
                {
                    gtk_text_set_point(text, match_start_pos);
                    gtk_editable_set_position(
                        editable, match_start_pos
                    );
                }

                if(needle_len > 0)
                {
                    gtk_editable_select_region(
                        editable,
                        match_start_pos,
                        match_start_pos + needle_len
                    );
                }
            }

            return(TRUE);
        }
}



/*
 *    Sets up the text dialog d which is assumed from on the
 *    given editor.
 *
 *    Should be called from EditorCreate().
 */
int EditorTDialogCreate(
        ma_editor_struct *editor, ma_editor_tdialog_struct *d
)
{
      GtkWidget *w, *parent, *parent2, *parent3, *scroll_parent;
      void *combo_rtn;
      gint toplevel_width, toplevel_height;
        gint    bw = 25,
                bh = 25,
                sw = 5,
                sh = -1;


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


        /* Get previous toplevel size. */
      toplevel_width = VMACFGItemListGetValueI(
            option, VMA_CFG_PARM_TDIALOG_WIDTH
        );
      if(toplevel_width < 1)
          toplevel_width = VMA_EDITOR_TDIALOG_DEF_WIDTH;

      toplevel_height = VMACFGItemListGetValueI(
            option, VMA_CFG_PARM_TDIALOG_HEIGHT
        );
        if(toplevel_height < 1)
            toplevel_height = VMA_EDITOR_TDIALOG_DEF_HEIGHT;


      /* Get parent as the text_dialog_toplevel from the editor,
       * this will be used as the parent for the pull out widget.
       */
      parent = editor->text_dialog_toplevel;
      if(parent == NULL)
          return(-1);

      /* Set initial values. */
      d->pulled_out = FALSE;
      d->has_changes = FALSE;
      d->editor_ptr = (void *)editor;

      /* Get cursors. */
      d->text_cur = gdk_cursor_new(GDK_XTERM);


      /* Create pull out horizontal widget. */
      w = GUIPullOutCreateH(
          parent,
          FALSE, 0,           /* Homogenious and spacing. */
          TRUE, TRUE, 0,      /* Expand, fill, and padding. */
          toplevel_width, toplevel_height,
          d,
          EditorTDialogPullOutCB,
          d,
          EditorTDialogPushInCB
      );
      d->toplevel = parent = w;


      /* Main vbox. */
      w = gtk_vbox_new(FALSE, 0);
        gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, 0);
      gtk_widget_show(w);
      parent = w;


        /* ********************************************************** */
      /* Tool bar. */
      w = gtk_handle_box_new();
        gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
        gtk_widget_show(w);
        parent2 = w;

        /* Tool bar hbox inside handle. */
        w = gtk_hbox_new(FALSE, 0);
        gtk_container_add(GTK_CONTAINER(parent2), w);
        gtk_container_border_width(GTK_CONTAINER(w), 2);
        gtk_widget_show(w);
        parent3 = w;

      /* Find icon. */
      w = (GtkWidget *)GUICreateMenuItemIcon(
          (u_int8_t **)icon_search_20x20_xpm
      );
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
      gtk_widget_set_usize(w, 20, 20);
        gtk_widget_show(w);

        /* Find combo. */
        w = (GtkWidget *)GUIComboCreate(
            NULL,               /* Label. */
            NULL,               /* Initial text value. */
            NULL,               /* Initial glist of items. */
            20,                 /* Max items. */
            &combo_rtn,         /* Combo widget return. */
            (void *)d,
            EditorTDialogFindActivateCB,
            NULL
        );
        d->find_combo = (GtkWidget *)combo_rtn;
        gtk_combo_set_case_sensitive(
            (GtkCombo *)combo_rtn,
            TRUE
        );
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
        gtk_widget_show(w);


        /* Separator. */
        w = gtk_label_new("");
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
        gtk_widget_set_usize(w, sw, sh);
        gtk_widget_show(w); 

      /* Revert button. */
        w = (GtkWidget *)GUIButtonPixmap(
            (u_int8_t **)icon_cancel_20x20_xpm
        );
        d->revert_btn = w;
        gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NONE);
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
        gtk_widget_set_usize(w, bw, bh);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(EditorTDialogRevertCB),
            (gpointer)d
        );
        gtk_widget_show(w);



        /* ********************************************************** */
        /* Hbox for table which will hold text widget. */
        w = gtk_hbox_new(FALSE, 0);
        gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, 0);
        gtk_widget_show(w);
        parent2 = w;

        /* Table for text and scroll bar widgets. */
        w = gtk_table_new(2, 2, FALSE);
        gtk_table_set_row_spacing(GTK_TABLE(w), 0, 2);
        gtk_table_set_col_spacing(GTK_TABLE(w), 0, 2);
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 2);
        gtk_widget_show(w);
        parent2 = w;

      d->text = w = gtk_text_new(NULL, NULL);
        /* Need to connect button_press_event signal_after just
         * after text widget is created, this is so that the right
         * click menu can be mapped properly.
         */
/*
        gtk_signal_connect_after(
            GTK_OBJECT(w), "button_press_event",
            GTK_SIGNAL_FUNC(EditorTDialogMenuMapCB),
            (gpointer)d
        );
        gtk_signal_connect_after(
            GTK_OBJECT(w), "key_press_event",
            GTK_SIGNAL_FUNC(EditorTDialogKeyEventCB),
            (gpointer)d
        );
 */
        gtk_text_set_editable(GTK_TEXT(w), TRUE);
        gtk_text_set_word_wrap(GTK_TEXT(w), TRUE);
        gtk_table_attach(
            GTK_TABLE(parent2), w,
            0, 1, 0, 1,
            GTK_EXPAND | GTK_SHRINK | GTK_FILL,
            GTK_EXPAND | GTK_SHRINK | GTK_FILL,
            0, 0
        );
        gtk_signal_connect(
            GTK_OBJECT(w), "changed",  
            GTK_SIGNAL_FUNC(EditorTDialogTextChangeCB),
            (gpointer)d
        );
        gtk_signal_connect(
            GTK_OBJECT(w), "insert_text",
            GTK_SIGNAL_FUNC(EditorTDialogTextInsertCB),
            (gpointer)d
        );
        gtk_signal_connect(
            GTK_OBJECT(w), "delete_text",
            GTK_SIGNAL_FUNC(EditorTDialogTextDeleteCB),
            (gpointer)d
        );
        gtk_widget_realize(w);
        if(d->text_cur != NULL)
            gdk_window_set_cursor(w->window, d->text_cur);
        gtk_widget_show(w);

        scroll_parent = gtk_vscrollbar_new(GTK_TEXT(w)->vadj);
        gtk_table_attach(
            GTK_TABLE(parent2), scroll_parent,
            1, 2, 0, 1,
            GTK_FILL,
            GTK_EXPAND | GTK_SHRINK | GTK_FILL,   
            0, 0
        );
        gtk_widget_show(scroll_parent);

      /* Reset values, update apperance, and menus. */
      EditorTDialogReset(d, FALSE);
      EditorTDialogUpdateAppearance(d);

      return(0);
}

/*
 *    Resets all values on the given dialog structure.
 */
void EditorTDialogReset(ma_editor_tdialog_struct *d, gbool need_unmap)
{
      GtkCombo *combo;

      if(d == NULL)
          return;

        EditorTDialogSetValues(d, -1, -1);
        EditorTDialogClear(d);

      combo = (GtkCombo *)d->find_combo;
      if(combo != NULL)
      {
          gtk_entry_set_text(GTK_ENTRY(combo->entry), "");
          GUIComboClearAll(combo);
      }

        combo = (GtkCombo *)d->replace_combo;
        if(combo != NULL)
        {
            gtk_entry_set_text(GTK_ENTRY(combo->entry), "");
            GUIComboClearAll(combo);
        }

      /* If need_unmap is TRUE then interprite that as we need
       * to push in the text dialog.
       */
      if(need_unmap)
          GUIPullOutPushIn(d->toplevel);
}


/*
 *    Updates apperance values on the given text dialog.
 *
 *    This function should be called whenever the global configuration
 *    has been changed.
 */
void EditorTDialogUpdateAppearance(ma_editor_tdialog_struct *d)
{
        static gbool reenterant = FALSE;
        GtkWidget *w;


        if(d == NULL)
            return;

        if(reenterant)
            return;
        else
            reenterant = TRUE;

      /* Set text widget font. */
      w = d->text;
        if(w != NULL)
      {
          const gchar *font_name = VMACFGItemListGetValueS(
            option, VMA_CFG_PARM_FONT_NAME_EDITABLE
          );
          GtkRcStyle *rcstyle = gtk_rc_style_new();
          if(font_name != NULL)
          {
            g_free(rcstyle->font_name);
            rcstyle->font_name = g_strdup(font_name);
          }

          gtk_widget_modify_style(w, rcstyle);

          GUIRCStyleDeallocUnref(rcstyle);
      }

      /* Update menus. */
        EditorTDialogUpdateMenus(d);

      reenterant = FALSE;
}

/*
 *    Updates menus and buttons on the text dialog.
 */
void EditorTDialogUpdateMenus(ma_editor_tdialog_struct *d)
{
        static gbool reenterant = FALSE;
        GtkWidget *w;
        gbool sensitivity;


      if(d == NULL)
          return;

        if(reenterant)
            return;
        else
            reenterant = TRUE;

#define SET_WIDGET_SENSITIVITY            \
{ \
 if(w != NULL) \
  gtk_widget_set_sensitive(w, sensitivity); \
}

#define SET_CHECK_MENU_ITEM_STATE   \
{ \
 if(w != NULL) \
  gtk_check_menu_item_set_active( \
   GTK_CHECK_MENU_ITEM(w), \
   state \
  ); \
}


      w = d->find_combo;
      if(w != NULL)
      {


      }

      w = d->replace_combo;
      if(w != NULL)
      {


      }

      w = d->revert_btn;
      if(w != NULL)
      {
          sensitivity = d->has_changes;
          SET_WIDGET_SENSITIVITY
      }

#undef SET_WIDGET_SENSITIVITY
#undef SET_CHECK_MENU_ITEM_STATE

      reenterant = FALSE;
      return;
}

/*
 *    Destroys the specified editor text dialog and deallocates
 *    its structure.
 */
void EditorTDialogDestroy(
      ma_editor_struct *editor, ma_editor_tdialog_struct *d
)
{
      GtkWidget *w;
      GdkCursor *cur;


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

      EditorTDialogReset(d, TRUE);

#define DO_DESTROY_WIDGET     \
{ \
 if(w != NULL) \
  gtk_widget_destroy(w); \
}
#define DO_DESTROY_CURSOR     \
{ \
 if(cur != NULL) \
  gdk_cursor_destroy(cur); \
}

      w = d->text;
      d->text = NULL;
      DO_DESTROY_WIDGET

      w = d->toplevel;
      d->toplevel = NULL;
      DO_DESTROY_WIDGET

      cur = d->text_cur;
      d->text_cur = NULL;
      DO_DESTROY_CURSOR

#undef DO_DESTROY_WIDGET
#undef DO_DESTROY_CURSOR

      memset(d, 0x00, sizeof(ma_editor_tdialog_struct));

      return;
}

Generated by  Doxygen 1.6.0   Back to index