Logo Search packages:      
Sourcecode: manedit version File versions  Download package

editor.c

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

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

#include "guiutils.h"
#include "fb.h"

#include "editor.h"
#include "editorfip.h"
#include "editorundo.h"
#include "editorcb.h"
#include "editordnd.h"
#include "viewerdnd.h"
#include "pref.h"
#include "manedit.h"
#include "maneditcb.h"
#include "maneditop.h"
#include "messages.h"
#include "config.h"

#include "images/manedit_48x48.xpm"
#include "images/manedit_16x16.xpm"
#include "images/manedit_20x20.xpm"
#include "images/mp_viewer_16x16.xpm"
#include "images/mp_viewer_20x20.xpm"

#include "images/icon_new_20x20.xpm"
#include "images/icon_open_20x20.xpm"
#include "images/icon_save_20x20.xpm"
#include "images/icon_save_as_20x20.xpm"
#include "images/icon_revert_20x20.xpm"
#include "images/icon_close_20x20.xpm"
#include "images/icon_exit_20x20.xpm"

#include "images/icon_undo_20x20.xpm"
#include "images/icon_redo_20x20.xpm"
#include "images/icon_cut_20x20.xpm"
#include "images/icon_copy_20x20.xpm"
#include "images/icon_paste_20x20.xpm"
#include "images/icon_clipboard_20x20.xpm"
#include "images/icon_options_20x20.xpm"

#include "images/icon_add_20x20.xpm"
#include "images/icon_remove_20x20.xpm"
#include "images/icon_properties2_20x20.xpm"

#include "images/icon_manpage_heading_20x20.xpm"
#include "images/icon_manpage_section_20x20.xpm"
/* #include "images/icon_help_20x20.xpm" */

#include "images/icon_paragraphi_20x20.xpm"
#include "images/icon_paragraphl_20x20.xpm"
#include "images/icon_paragraphr_20x20.xpm"
#include "images/icon_listitems_20x20.xpm"

#include "images/icon_bold_20x20.xpm"
#include "images/icon_underline_20x20.xpm"

#include "images/icon_break_20x20.xpm"

#include "images/icon_amp_20x20.xpm"
#include "images/icon_lessthan_20x20.xpm"
#include "images/icon_greaterthan_20x20.xpm"

#include "images/icon_strip_tags_20x20.xpm"

#include "images/icon_search_20x20.xpm"
#include "images/icon_replace_20x20.xpm"
#include "images/icon_replace_all_20x20.xpm"


editor_item_struct *EditorItemNew(
      editor_item_type type,
      editor_struct *editor,
      GtkCTree *ctree,
      GtkCTreeNode *parent,
      GtkCTreeNode *this_branch,
      gboolean is_leaf,
      gchar **line,           /* Transtered, not copied */
      gint total_lines
);
editor_item_struct *EditorItemDup(editor_item_struct *item);
void EditorItemDelete(editor_item_struct *item);

void EditorLayoutTrunkDeleteAll(editor_struct *editor);

void EditorBranchSelect(
      editor_struct *editor, GtkCTreeNode *branch
);

void EditorBranchSetData(
      GtkCTree *ctree, GtkCTreeNode *branch,
      editor_item_struct *item, GtkDestroyNotify destroy
);
editor_item_struct *EditorBranchGetData(
      GtkCTree *ctree, GtkCTreeNode *branch
);
void EditorItemSetToplevelHasChanges(
      editor_struct *editor, GtkCTreeNode *branch, gboolean has_changes
);

GtkCTreeNode *EditorItemGetFirstToplevel(editor_struct *editor);
GtkCTreeNode *EditorItemGetParent(
      editor_struct *editor, GtkCTreeNode *branch
);
GtkCTreeNode *EditorItemGetToplevel(
      editor_struct *editor, GtkCTreeNode *branch                   
);

void EditorSetBusy(editor_struct *editor);
void EditorSetReady(editor_struct *editor);

static void EditorCreateMenuBar(editor_struct *editor, GtkWidget *parent);
static void EditorCreateToolBar(editor_struct *editor, GtkWidget *parent);
static void EditorCreateStatusBar(editor_struct *editor, GtkWidget *parent);

editor_struct *EditorNew(void *core_ptr);
void EditorUpdateMenus(editor_struct *editor);
void EditorSetStatusPosition(editor_struct *editor, gint row, gint column);
void EditorSetStatusMessage(editor_struct *editor, const gchar *mesg);
void EditorSetStatusProgress(editor_struct *editor, gfloat percent);
void EditorRecordPositions(editor_struct *editor);
void EditorResetUndos(editor_struct *editor);
void EditorReset(editor_struct *editor, gboolean need_unmap);
void EditorMap(editor_struct *editor);
void EditorUnmap(editor_struct *editor);
void EditorDelete(editor_struct *editor);


#define ATOI(s)         (((s) != NULL) ? atoi(s) : 0)
#define ATOL(s)         (((s) != NULL) ? atol(s) : 0)
#define ATOF(s)         (((s) != NULL) ? atof(s) : 0.0f)
#define STRDUP(s)       (((s) != NULL) ? g_strdup(s) : NULL)

#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 STRLEN(s)       (((s) != NULL) ? strlen(s) : 0)
#define STRISEMPTY(s)   (((s) != NULL) ? (*(s) == '\0') : TRUE)


/*
 *    Creates a new Editor Item.
 *
 *    The list of strings line will be transtered, not coppied. The
 *    calling function must not reference them again after this call.
 */
editor_item_struct *EditorItemNew(
      editor_item_type type,
      editor_struct *editor,
      GtkCTree *ctree,
      GtkCTreeNode *parent,
      GtkCTreeNode *this_branch,
      gboolean is_leaf,
      gchar **line,                 /* Transfered, not coppied */
      gint total_lines
)
{
      editor_item_struct *item = EDITOR_ITEM(g_malloc0(
          sizeof(editor_item_struct)
      ));
      if(item == NULL)
      {
          strlistfree(line, total_lines);
          return(NULL);
      }

      item->type = type;
      item->editor = editor;
      item->ctree = ctree;
      item->parent = parent;
      item->this_branch = this_branch;
      item->is_leaf = is_leaf;
      item->line = line;            /* Transfered, not coppied */
      item->total_lines = total_lines;

      return(item);
}

/*
 *    Makes a duplicate of the given item including all its
 *    allocated sub structures.
 */
editor_item_struct *EditorItemDup(editor_item_struct *item)
{
      gint i;
      editor_item_struct *new_item, *src_item = item;

      if(src_item == NULL)
          return(NULL);

      new_item = EDITOR_ITEM(g_malloc0(
          sizeof(editor_item_struct)
      ));
      if(new_item != NULL)
      {
          /* First copy value */
          memcpy(new_item, src_item, sizeof(editor_item_struct));


          /* Copy allocated substructures */

          /* File names */
          new_item->name = STRDUP(src_item->name);
          new_item->full_path = STRDUP(src_item->full_path);

          /* Header title heading values */
          new_item->header_name = STRDUP(src_item->header_name);
          new_item->header_section_number = STRDUP(
            src_item->header_section_number
          );
          new_item->header_version = STRDUP(src_item->header_version);
          new_item->header_author = STRDUP(src_item->header_author);
          new_item->header_catagory = STRDUP(src_item->header_catagory);

          /* Section name */
          new_item->section_name = STRDUP(src_item->section_name);

          /* Lines */
          if(new_item->total_lines > 0)
          {
            new_item->line = (gchar **)g_malloc0(
                new_item->total_lines * sizeof(gchar *)
            );
            if(new_item->line == NULL)
                new_item->total_lines = 0;
          }
          else
          {
            new_item->line = NULL;
          }
          for(i = 0; i < new_item->total_lines; i++)
            new_item->line[i] = STRDUP(src_item->line[i]);
      }

      return(new_item);
}

/*
 *    Deletes the item and all its allocated resources.
 */
void EditorItemDelete(editor_item_struct *item)
{
      if(item == NULL)
          return;

      g_free(item->name);
      g_free(item->full_path);

      g_free(item->header_name);
      g_free(item->header_section_number);
      g_free(item->header_version);
      g_free(item->header_author);
      g_free(item->header_catagory);

      g_free(item->section_name);

      strlistfree(item->line, item->total_lines);

      g_free(item);
}


/*
 *    Selects the given branch on the editor's layout ctree.
 *
 *    Expands the parent branches if any and as needed.
 *
 *    Will call expand, select, and unselect callbacks.
 */
void EditorBranchSelect(
      editor_struct *editor, GtkCTreeNode *branch  
)
{
      GtkCTreeNode *parent;
      GtkCTreeRow *branch_row;
      GtkCTree *ctree;


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

      if(!editor->initialized)
          return;

      ctree = (GtkCTree *)editor->layout_ctree;
      if(ctree == NULL)
          return; 

      /* Get parent branch of given branch */
      branch_row = GTK_CTREE_ROW(branch);
      parent = ((branch_row == NULL) ?
          NULL : branch_row->parent
      );
      /* Get row of parent branch (if it is not NULL) */
      branch_row = ((parent == NULL) ?
          NULL : GTK_CTREE_ROW(parent)
      );
      /* Is parent branch expanded? */
      if((branch_row == NULL) ? 0 : !(branch_row->expanded))
      {
          /* Expand all parent branches */
          while(parent != NULL)
          {
            /* Expand parent branch (this will generate an expand
             * signal which will be handled).
             */
            gtk_ctree_expand(ctree, parent);

            /* Get parent of parent branch */
            branch_row = GTK_CTREE_ROW(parent);
            parent = ((branch_row == NULL) ?
                NULL : branch_row->parent
            );
          }
      }

/*    gtk_ctree_node_moveto(ctree, branch, 0, 0, 0); */

      /* Select the branch, this will call the unselect and then
       * select callbacks */
      gtk_ctree_select(ctree, branch);
}


/*
 *    Deletes all layout trunk branches on the specified editor.
 */
void EditorLayoutTrunkDeleteAll(editor_struct *editor)
{
      gint i, total;
      GtkCTreeNode **list;
      GtkCTree *ctree;

      if(editor == NULL)
          return;

      ctree = (GtkCTree *)editor->layout_ctree;
      if(ctree == NULL)
          return;

      /* We need to create a tempory list of layout trunks since the one
       * on the editor will be reduced each time we call
       * gtk_ctree_remove_node() on a layout trunk
       */
      total = editor->total_layout_trunks;
      if(total > 0)
          list = (GtkCTreeNode **)g_malloc0(
            total * sizeof(GtkCTreeNode *)
          );
      else
          list = NULL;
      if(list != NULL)
          memcpy(list, editor->layout_trunk, total * sizeof(GtkCTreeNode *));
      else
          total = 0;


      /* Remove each layout trunk branch node using our local
       * coppied list
       */
      for(i = 0; i < total; i++)
      {
          if(list[i] != NULL)
            gtk_ctree_remove_node(ctree, list[i]);
      }

      /* Delete both the list of layout trunks on the editor and
       * our local one. Note that the layout trunks list should have
       * been deleted by the destroy notify callback when
       * gtk_ctree_remove_node() was called on it
       */
      g_free(editor->layout_trunk);
      editor->layout_trunk = NULL;
      editor->total_layout_trunks = 0;

      g_free(list);
}


/*
 *    Sets the data and destroy function for the given GtkCTreeNode 
 *    branch.
 */
void EditorBranchSetData(
      GtkCTree *ctree, GtkCTreeNode *branch,
      editor_item_struct *item, GtkDestroyNotify destroy
)
{
      if((ctree == NULL) || (branch == NULL))
          return;

      gtk_ctree_node_set_row_data_full(
          ctree, branch,
          item, destroy
      );
}

/*
 *    Returns the user set data for the given GtkCTreeNode branch.
 */
editor_item_struct *EditorBranchGetData(
      GtkCTree *ctree, GtkCTreeNode *branch
)
{
      if((ctree == NULL) || (branch == NULL))
          return(NULL);

      return(EDITOR_ITEM(gtk_ctree_node_get_row_data(
            ctree, branch
      )));
}


/*
 *    Sets the given branch node's item data to the value of
 *    has_changes and the branch node's subsequent parents
 *    (including and espessially the toplevel (trunk) branch node's
 *    item data.
 */
void EditorItemSetToplevelHasChanges(
      editor_struct *editor, GtkCTreeNode *branch, gboolean has_changes
)
{
      editor_item_struct *item;
      GtkCTreeNode *node;
      GtkCTree *ctree;

      if(editor == NULL)
          return;

      ctree = GTK_CTREE(editor->layout_ctree);

      /* Get toplevel node starting from selected branch node */
      for(
          node = branch;
          node != NULL;
          node = GTK_CTREE_ROW(node)->parent
      )
      {
          /* Get and set this branch node's item data */
          item = EditorBranchGetData(ctree, node);
          if(item != NULL)
            item->has_changes = has_changes;
      }
}


/*
 *    Returns the pointer to the first branch node that is toplevel
 *    on the editor's layout ctree. This is basically getting the
 *    pointer to the branch of the first row since it's gauranteed
 *    to be a toplevel trunk branch and the first one.
 *
 *    Can return NULL on error or if there are no branches.
 */
GtkCTreeNode *EditorItemGetFirstToplevel(editor_struct *editor)
{
      GtkCTree *ctree;


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

      ctree = (GtkCTree *)editor->layout_ctree;
      if(ctree == NULL)
          return(NULL);

      /* Return the first branch on the ctree */
      return(gtk_ctree_node_nth(ctree, 0));
}

/*
 *    Returns the pointer to the parent branch node of the given branch,
 *    can return NULL if branch is a toplevel trunk or the given branch
 *    itself is NULL.
 */
GtkCTreeNode *EditorItemGetParent(
      editor_struct *editor, GtkCTreeNode *branch
)
{
      GtkCTreeRow *row;


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

      row = GTK_CTREE_ROW(branch);
      if(row == NULL)
      {
          /* Discontinuity, row data is NULL. Need to return
           * NULL on error.
           */
          return(NULL);
      }

      return(row->parent);
}

/*
 *    Returns the pointer to the toplevel trunk branch for the given
 *    branch node. If given branch node itself is a toplevel trunk
 *    branch then the pointer to the given branch will be returned.
 *
 *    Can return NULL on error.
 */
GtkCTreeNode *EditorItemGetToplevel(
      editor_struct *editor, GtkCTreeNode *branch
)
{
      GtkCTreeNode *parent;


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

      while(branch != NULL)
      {
          parent = EditorItemGetParent(editor, branch);
          if(parent == NULL)
            return(branch);
          else
            branch = parent;
      }

      return(NULL);
}


/*
 *    Marks editor as busy.
 */
void EditorSetBusy(editor_struct *editor)
{ 
      GtkWidget *w;
      GdkCursor *cur;
      medit_core_struct *core_ptr;


      if(editor == NULL)
          return;

      core_ptr = (medit_core_struct *)editor->core_ptr;
      if(core_ptr == NULL)
          return;

      w = editor->toplevel;
      if(w == NULL)
          return; 
  
      cur = core_ptr->cursors_list.busy;
      if(cur == NULL)
          return;

      if(GTK_WIDGET_NO_WINDOW(w))
          return;

      gdk_window_set_cursor(w->window, cur);
      gdk_flush();
}  

/*
 *    Marks editor as ready (opposite affect of EditorSetBusy()).
 */
void EditorSetReady(editor_struct *editor)
{           
      GtkWidget *w;
  
      if(editor == NULL)
          return;
   
      w = editor->toplevel;
      if(w == NULL)
          return;
 
      if(GTK_WIDGET_NO_WINDOW(w))
          return;
 
      gdk_window_set_cursor(w->window, NULL);
      gdk_flush();
}


/*
 *    Creates the menu bar for the editor, this function should be
 *    called by EditorNew().
 *
 *    Given parent is assumed to be a vbox.
 */
static void EditorCreateMenuBar(editor_struct *editor, GtkWidget *parent)
{
      GtkWidget *menu_bar, *parent2, *menu, *w, *fw;
      gint accel_key;
      GtkAccelGroup *accel_group;
      guint accel_mods;
      gpointer client_data = editor;
      gpointer old_client_data;
      guint8 **icon;
      gchar *label = NULL;
      void (*func_cb)(GtkWidget *w, gpointer);


      /* Create menu bar */
      menu_bar = GUIMenuBarCreate(&accel_group);
      editor->menu_bar = menu_bar;
      gtk_widget_show(menu_bar);

#define DO_ADD_MENU_ITEM_LABEL            \
{ \
 w = GUIMenuItemCreate( \
  menu, GUI_MENU_ITEM_TYPE_LABEL, accel_group, \
  icon, label, accel_key, accel_mods, (void **)&fw, \
  client_data, func_cb \
 ); \
}

#define DO_ADD_MENU_ITEM_SUBMENU    \
{ \
 w = GUIMenuItemCreate( \
  menu, GUI_MENU_ITEM_TYPE_SUBMENU, accel_group, \
  icon, label, accel_key, accel_mods, (void **)&fw, \
  client_data, func_cb \
 ); \
 if(w != NULL) \
  GUIMenuItemSetSubMenu(w, submenu); \
}

#define DO_ADD_MENU_ITEM_CHECK            \
{ \
 w = GUIMenuItemCreate( \
  menu, GUI_MENU_ITEM_TYPE_CHECK, accel_group, \
  icon, label, accel_key, accel_mods, (void **)&fw, \
  client_data, func_cb \
 ); \
}

#define DO_ADD_MENU_SEP       \
{ \
 w = GUIMenuItemCreate( \
  menu, GUI_MENU_ITEM_TYPE_SEPARATOR, NULL, \
  NULL, NULL, 0, 0, NULL, \
  NULL, NULL \
 ); \
}

      /* Create file menu */
      menu = GUIMenuCreate();
      if(menu != NULL)
      {
          icon = (guint8 **)icon_new_20x20_xpm;
          label = "New";
          accel_key = 'n';
          accel_mods = GDK_CONTROL_MASK;
          func_cb = EditorManualNewCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->new_mi = w;

          icon = (guint8 **)icon_new_20x20_xpm;
          label = "New From Template...";
          accel_key = 't';
          accel_mods = GDK_CONTROL_MASK;
          func_cb = EditorManualNewFromTemplateCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->new_from_template_mi = w;

          icon = (guint8 **)icon_open_20x20_xpm;
          label = "Open...";
          accel_key = 'o';
          accel_mods = GDK_CONTROL_MASK;
          func_cb = EditorManualOpenCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->open_mi = w;

          icon = (guint8 **)icon_save_20x20_xpm;
          label = "Save";
          accel_key = 's';
          accel_mods = GDK_CONTROL_MASK;
          func_cb = EditorManualSaveCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->save_mi = w;

          icon = (guint8 **)icon_save_as_20x20_xpm;
          label = "Save As...";
          accel_key = 'a';
          accel_mods = GDK_CONTROL_MASK;
          func_cb = EditorManualSaveAsCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->save_as_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_close_20x20_xpm;
          label = "Close Manual";
          accel_key = 'e';
          accel_mods = GDK_CONTROL_MASK;
          func_cb = EditorManualCloseCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->close_manual_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_revert_20x20_xpm;
          label = "Revert";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualRevertCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->revert_mi = w;

          DO_ADD_MENU_SEP

          /* This closes the editor, not the selected manual page */
          icon = (guint8 **)icon_close_20x20_xpm;
          label = "Close";
/*          accel_key = GDK_F4; */
          accel_key = 'w';
          accel_mods = GDK_CONTROL_MASK;
          func_cb = EditorCloseMCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->close_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_exit_20x20_xpm;
          label = "Exit";
          accel_key = 'q';
          accel_mods = GDK_CONTROL_MASK;
          func_cb = EditorCloseAllMCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->exit_mi = w;
      }
      editor->file_mh = GUIMenuAddToMenuBar(
          menu_bar, menu,
          "File",
          GUI_MENU_BAR_ALIGN_LEFT
      );


      /* Create edit menu */
      menu = GUIMenuCreate();
      if(menu != NULL)
      {
          icon = (guint8 **)icon_undo_20x20_xpm;
          label = "Undo";
          accel_key = 'z';
          accel_mods = GDK_CONTROL_MASK;
          func_cb = EditorUndoCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->undo_mi = w;
          editor->undo_milabel = fw;

          icon = (guint8 **)icon_redo_20x20_xpm;
          label = "Redo";
          accel_key = 'r';
          accel_mods = GDK_CONTROL_MASK;
          func_cb = EditorRedoCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->redo_mi = w;
          editor->redo_milabel = fw;

          DO_ADD_MENU_SEP 

          icon = (guint8 **)icon_cut_20x20_xpm;
          label = "Cut";
          accel_key = 'x';
          accel_mods = GDK_CONTROL_MASK;
          func_cb = EditorCutCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->cut_mi = w;

          icon = (guint8 **)icon_copy_20x20_xpm;
          label = "Copy";
          accel_key = 'c';    
          accel_mods = GDK_CONTROL_MASK;
          func_cb = EditorCopyCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->copy_mi = w;

          icon = (guint8 **)icon_paste_20x20_xpm;
          label = "Paste";
          accel_key = 'v';
          accel_mods = GDK_CONTROL_MASK;
          func_cb = EditorPasteCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->paste_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_clipboard_20x20_xpm;
          label = "Clipboard...";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorClipboardBrowserCB;
          DO_ADD_MENU_ITEM_LABEL

          DO_ADD_MENU_SEP 

          icon = NULL;
          label = "Select All";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorSelectAllCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->select_all_mi = w;

          icon = NULL;
          label = "Unselect All";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorUnselectAllCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->unselect_all_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_search_20x20_xpm;
          label = "Find In Pages...";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorMapFIPCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->find_in_pages_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_options_20x20_xpm;
          label = "Preferences...";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorPreferencesCB;
          DO_ADD_MENU_ITEM_LABEL
      }
      editor->edit_mh = GUIMenuAddToMenuBar(
          menu_bar, menu,
          "Edit",
          GUI_MENU_BAR_ALIGN_LEFT
      );

      /* View menu */
      menu = GUIMenuCreate();
      if(menu != NULL)
      {
          icon = (guint8 **)mp_viewer_20x20_xpm;
          label = "Preview";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualPreviewCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->preview_mi = w;

          DO_ADD_MENU_SEP

          icon = NULL;
          label = "Syntax Highlighting";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualSyntaxHighlightToggleCB;
          DO_ADD_MENU_ITEM_CHECK
          editor->syntax_highlight_cmi = w;
      }
      editor->view_mh = GUIMenuAddToMenuBar(
          menu_bar, menu,
          "View",
          GUI_MENU_BAR_ALIGN_LEFT
      );

      /* Layout menu */   
      menu = GUIMenuCreate();
      if(menu != NULL)
      {
          icon = (guint8 **)icon_add_20x20_xpm;
          label = "Add Header";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualAddHeaderCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->add_header_mi = w;  

          icon = (guint8 **)icon_add_20x20_xpm; 
          label = "Add Section";
          accel_key = 0;            
          accel_mods = 0;               
          func_cb = EditorManualAddSectionCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->add_section_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_remove_20x20_xpm;
          label = "Remove";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualRemoveSectionCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->remove_mi = w;

          DO_ADD_MENU_SEP
          
          icon = (guint8 **)icon_properties2_20x20_xpm;
          label = "Properties...";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualPropertiesCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->properties_mi = w;
      }
      editor->layout_mh = GUIMenuAddToMenuBar(   
          menu_bar, menu,
          "Layout",
          GUI_MENU_BAR_ALIGN_LEFT
      );

      /* Format menu */
      menu = GUIMenuCreate();
      if(menu != NULL)
      {
          icon = (guint8 **)icon_paragraphl_20x20_xpm;
          label = "Paragraph Left";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtParagraphLeftCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->fmt_pl_mi = w;

          icon = (guint8 **)icon_paragraphr_20x20_xpm;
          label = "Paragraph Right";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtParagraphRightCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->fmt_pr_mi = w;

          icon = (guint8 **)icon_paragraphi_20x20_xpm;
          label = "Paragraph Indented";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtParagraphIndentedCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->fmt_pi_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_listitems_20x20_xpm;
          label = "List Item";
          accel_key = 0; 
          accel_mods = 0;
          func_cb = EditorFmtListItemCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->fmt_li_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_bold_20x20_xpm;
          label = "Bold";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtBoldCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->fmt_b_mi = w;

          icon = (guint8 **)icon_underline_20x20_xpm;
          label = "Underline";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtUnderlineCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->fmt_u_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_break_20x20_xpm;
          label = "Line Break";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtLineBreakCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->fmt_br_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_amp_20x20_xpm;
          label = "Ampersand";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtAmpersandCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->fmt_amp_mi = w;

          icon = (guint8 **)icon_lessthan_20x20_xpm;
          label = "Less Than";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtLessThanCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->fmt_lt_mi = w;

          icon = (guint8 **)icon_greaterthan_20x20_xpm;
          label = "Greater Than";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtGreaterThanCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->fmt_gt_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_strip_tags_20x20_xpm;
          label = "Strip Tags";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorStripTagsCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->fmt_strip_tags_mi = w;
      }
      editor->fmt_mh = GUIMenuAddToMenuBar(   
          menu_bar, menu,
          "Tags",
          GUI_MENU_BAR_ALIGN_LEFT
      );

      /* Create windows menu */
      menu = GUIMenuCreate();
      if(menu != NULL)
      {
          old_client_data = client_data;
          client_data = editor->core_ptr;

          icon = (guint8 **)manedit_20x20_xpm;
          label = "New Editor";  
          accel_key = 0;
          accel_mods = 0;
          func_cb = MEditEditorNewCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->windows_new_editor = w;

          icon = (guint8 **)mp_viewer_20x20_xpm;
          label = "New Viewer";
          accel_key = 0;
          accel_mods = 0;
          func_cb = MEditViewerNewCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->windows_new_viewer = w;

          client_data = old_client_data;
      }
      editor->windows_mh = GUIMenuAddToMenuBar(
          menu_bar, menu,
          "Windows",
          GUI_MENU_BAR_ALIGN_LEFT
      );

      /* Help menu */
      menu = MEditCreateHelpMenu(
          (medit_core_struct *)editor->core_ptr,
          accel_group
      );
      GUIMenuAddToMenuBar(
          menu_bar, menu,
          "Help",
          GUI_MENU_BAR_ALIGN_RIGHT
      );


#undef DO_ADD_MENU_ITEM_LABEL
#undef DO_ADD_MENU_ITEM_SUBMENU
#undef DO_ADD_MENU_ITEM_CHECK
#undef DO_ADD_MENU_SEP


      /* Handle for menu bar */
      w = gtk_handle_box_new();
      editor->menu_bar_dock = w;
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
      gtk_widget_show(w);
      parent2 = w;

      gtk_container_add(GTK_CONTAINER(parent2), menu_bar);

      /* Attach accel group to toplevel window */
      if((editor->toplevel != NULL) &&
         (accel_group != NULL)
      )
      {
          gtk_window_add_accel_group(
            GTK_WINDOW(editor->toplevel),
            (GtkAccelGroup *)accel_group
          );
      }
}

/*
 *    Creates the tool bar for the editor, this function should be
 *    called by EditorNew().
 *
 *    Given parent is assumed to be a vbox.
 */
static void EditorCreateToolBar(editor_struct *editor, GtkWidget *parent)
{
      gboolean show_tooltips = TRUE;
      GtkWidget *w, *fw, *menu, *parent2, *parent3;
      gpointer combo_rtn;
      gint  bw = 25,
            bh = 25,
            mbw = 80,
            mbh = 25,
            sw = 5,
            sh = -1;
      gint accel_key;
      gpointer accel_group;
      guint accel_mods;
      const gchar *label;
      guint8 **icon;
      gpointer mclient_data;
      void (*func_cb)(GtkWidget *w, gpointer);



#define DO_ADD_MENU_ITEM_LABEL  \
{ \
 w = GUIMenuItemCreate( \
  menu, GUI_MENU_ITEM_TYPE_LABEL, accel_group, \
  icon, label, accel_key, accel_mods, (void **)&fw, \
  mclient_data, func_cb \
 ); \
}       
#define DO_ADD_MENU_ITEM_SUBMENU        \
{ \
 w = GUIMenuItemCreate( \
  menu, GUI_MENU_ITEM_TYPE_SUBMENU, accel_group, \
  icon, label, accel_key, accel_mods, (void **)&fw, \
  mclient_data, func_cb \
 ); \
 if(w != NULL) \
  GUIMenuItemSetSubMenu(w, submenu); \
}
#define DO_ADD_MENU_ITEM_CHECK  \
{ \
 w = GUIMenuItemCreate( \
  menu, GUI_MENU_ITEM_TYPE_CHECK, accel_group, \
  icon, label, accel_key, accel_mods, (void **)&fw, \
  mclient_data, func_cb \
 ); \
}
#define DO_ADD_MENU_SEP \
{ \
 w = GUIMenuItemCreate( \
  menu, GUI_MENU_ITEM_TYPE_SEPARATOR, NULL, \
  NULL, NULL, 0, 0, NULL, \
  NULL, NULL \
 ); \
}


      /* Handle for tool bar hbox */
      w = gtk_handle_box_new();
      editor->tool_bar_dock = w;
      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);
      editor->tool_bar = w;
      gtk_container_border_width(GTK_CONTAINER(w), 2);
      gtk_container_add(GTK_CONTAINER(parent2), w);
      gtk_widget_show(w);
      parent3 = w;

      /* New menu button */
      w = (GtkWidget *)GUIButtonPixmapLabelV(
          (guint8 **)icon_new_20x20_xpm, "New", NULL
      );
      editor->new_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_after(
          GTK_OBJECT(w), "pressed",
          GTK_SIGNAL_FUNC(EditorButtonMenuMapCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_NEW_MENU_BTN);
      gtk_widget_show(w);

      /* New menu button menu */
      menu = (GtkWidget *)GUIMenuCreate();
      editor->new_btn_new_menu = menu;
      accel_group = NULL;
      mclient_data = (void *)editor;
      if(menu != NULL)
      {
          icon = (guint8 **)icon_new_20x20_xpm;
          label = "New";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualNewCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->new_btn_new_mi = w;

          icon = (guint8 **)icon_new_20x20_xpm;
          label = "New From Template...";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualNewFromTemplateCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->new_btn_new_from_template_mi = w;
      }
      /* Need to attach basic "hide" signal to menu so we know when
       * it is unmapped.
       */
      gtk_signal_connect(
          GTK_OBJECT(menu), "hide",
          GTK_SIGNAL_FUNC(EditorMenuHideCB),
          (gpointer)editor
      );


      /* Open */
      w = (GtkWidget *)GUIButtonPixmapLabelV(
          (guint8 **)icon_open_20x20_xpm, "Open", NULL
      );
      editor->open_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(EditorManualOpenCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_OPEN);
      gtk_widget_show(w);

      /* Save */
      w = (GtkWidget *)GUIButtonPixmapLabelV(
          (guint8 **)icon_save_20x20_xpm, "Save", NULL
      );
      editor->save_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(EditorManualSaveCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_SAVE);
      gtk_widget_show(w);

      /* Save as */
/*
      w = (GtkWidget *)GUIButtonPixmapLabelV(
          (guint8 **)icon_save_as_20x20_xpm, "Save As", NULL
      );
      editor->save_as_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(EditorManualSaveAsCB),
          (gpointer)editor
      );
      if(show_tooltips)   
          GUISetWidgetTip(w, EDITOR_TT_SAVE_AS);
      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);
 */
      /* Close manual page */
/*
      w = (GtkWidget *)GUIButtonPixmapLabelV(
          (guint8 **)icon_close_20x20_xpm, "Close", NULL
      );
      editor->close_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(EditorManualCloseCB),
          (gpointer)editor
      );
      if(show_tooltips)   
          GUISetWidgetTip(w, EDITOR_TT_CLOSE_MANUAL);
      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);

      /* Undo */
      w = (GtkWidget *)GUIButtonPixmapLabelV(
          (guint8 **)icon_undo_20x20_xpm, "Undo", NULL
      );
      editor->undo_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(EditorUndoCB),
          (gpointer)editor
      );
      if(show_tooltips)  
          GUISetWidgetTip(w, EDITOR_TT_UNDO);
      gtk_widget_show(w);

      /* Redo */
      w = (GtkWidget *)GUIButtonPixmapLabelV(
          (guint8 **)icon_redo_20x20_xpm, "Redo", NULL
      );
      editor->redo_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(EditorRedoCB),
          (gpointer)editor
      );
      if(show_tooltips)  
          GUISetWidgetTip(w, EDITOR_TT_REDO);
      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);

      /* Cut */
      w = (GtkWidget *)GUIButtonPixmapLabelV(
          (guint8 **)icon_cut_20x20_xpm, "Cut", NULL
      );
      editor->cut_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(EditorCutCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_CUT);
      gtk_widget_show(w);

      /* Copy */
      w = (GtkWidget *)GUIButtonPixmapLabelV(
          (guint8 **)icon_copy_20x20_xpm, "Copy", NULL
      );
      editor->copy_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(EditorCopyCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_COPY); 
      gtk_widget_show(w);

      /* Paste */
      w = (GtkWidget *)GUIButtonPixmapLabelV(
          (guint8 **)icon_paste_20x20_xpm, "Paste", NULL
      );
      editor->paste_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(EditorPasteCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_PASTE);
      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);

      /* Add header */
      w = (GtkWidget *)GUIButtonPixmapLabelV(
          (guint8 **)icon_manpage_heading_20x20_xpm, "Header", NULL
      );
      editor->add_header_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(EditorManualAddHeaderCB),
          (gpointer)editor
      );
      if(show_tooltips)  
          GUISetWidgetTip(w, EDITOR_TT_NEW_HEADER);
      gtk_widget_show(w);

      /* Add section */
      w = (GtkWidget *)GUIButtonPixmapLabelV(
          (guint8 **)icon_manpage_section_20x20_xpm, "Section", NULL
      );
      editor->add_section_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(EditorManualAddSectionCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_NEW_SECTION);
      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);

      /* Remove */
      w = (GtkWidget *)GUIButtonPixmapLabelV(
          (guint8 **)icon_remove_20x20_xpm, "Remove", NULL
      );
      editor->remove_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(EditorManualRemoveSectionCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_REMOVE);
      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);

      /* Properties */
/*
      w = (GtkWidget *)GUIButtonPixmapLabelV(
          (guint8 **)icon_properties2_20x20_xpm, "Properties", NULL
      );
      editor->properties_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(EditorManualPropertiesCB),
          (gpointer)editor
      );
      if(show_tooltips)  
          GUISetWidgetTip(w, EDITOR_TT_PROPERTIES);
      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);

      /* Preview */
      w = (GtkWidget *)GUIButtonPixmapLabelV(
          (guint8 **)mp_viewer_20x20_xpm, "Preview", NULL
      );
      editor->preview_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(EditorManualPreviewCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_PREVIEW);
      gtk_widget_show(w);


      /* ********************************************************** */
      /* Handle for format bar hbox */
      w = gtk_handle_box_new();
      editor->fmt_bar_dock = w;
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
      gtk_widget_show(w);
      parent2 = w;

      /* Format bar hbox inside handle */
      w = gtk_hbox_new(FALSE, 0);
      editor->fmt_bar = w;
      gtk_container_add(GTK_CONTAINER(parent2), w);
      gtk_container_border_width(GTK_CONTAINER(w), 2);
      gtk_widget_show(w);
      parent3 = w;

      /* Paragraph left */
      w = (GtkWidget *)GUIButtonPixmap(
          (guint8 **)icon_paragraphl_20x20_xpm
      );
      editor->fmt_pl_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(EditorFmtParagraphLeftCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_FMT_LP);
      gtk_widget_show(w);

      /* Paragraph right */
      w = (GtkWidget *)GUIButtonPixmap(
          (guint8 **)icon_paragraphr_20x20_xpm
      );
      editor->fmt_pr_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(EditorFmtParagraphRightCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_FMT_RP);
      gtk_widget_show(w);

      /* Paragraph indented */
      w = (GtkWidget *)GUIButtonPixmap(
          (guint8 **)icon_paragraphi_20x20_xpm
      );
      editor->fmt_pi_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(EditorFmtParagraphIndentedCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_FMT_IP);
      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);

      /* List item */
      w = (GtkWidget *)GUIButtonPixmap(
          (guint8 **)icon_listitems_20x20_xpm
      );
      editor->fmt_li_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(EditorFmtListItemCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_FMT_LIST);
      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);

      /* Bold */
      w = (GtkWidget *)GUIButtonPixmap(
          (guint8 **)icon_bold_20x20_xpm
      );
      editor->fmt_b_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(EditorFmtBoldCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_FMT_BOLD);
      gtk_widget_show(w);

      /* Underlined */
      w = (GtkWidget *)GUIButtonPixmap(
          (guint8 **)icon_underline_20x20_xpm
      );
      editor->fmt_u_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(EditorFmtUnderlineCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_FMT_UNDERLINE);
      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);

      /* Break */
      w = (GtkWidget *)GUIButtonPixmap(
          (guint8 **)icon_break_20x20_xpm
      );
      editor->fmt_br_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(EditorFmtLineBreakCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_FMT_BREAK);
      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);

      /* Ampersand */
      w = (GtkWidget *)GUIButtonPixmap(
          (guint8 **)icon_amp_20x20_xpm
      );
      editor->fmt_amp_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(EditorFmtAmpersandCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_FMT_AMP);
      gtk_widget_show(w);

      /* Less than */
      w = (GtkWidget *)GUIButtonPixmap(
          (guint8 **)icon_lessthan_20x20_xpm
      );
      editor->fmt_lt_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(EditorFmtLessThanCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_FMT_LT);
      gtk_widget_show(w);

      /* Greater than */
      w = (GtkWidget *)GUIButtonPixmap(
          (guint8 **)icon_greaterthan_20x20_xpm
      );
      editor->fmt_gt_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(EditorFmtGreaterThanCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_FMT_GT);
      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);

      /* Strip tags */
      w = (GtkWidget *)GUIButtonPixmap(
          (guint8 **)icon_strip_tags_20x20_xpm
      );
      editor->fmt_strip_tags_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(EditorStripTagsCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_FMT_STRIP_TAGS);
      gtk_widget_show(w);


      /* ********************************************************** */

      /* Handle for find bar hbox */
      w = gtk_handle_box_new();
      editor->find_bar_dock = w;
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
      gtk_widget_show(w);
      parent2 = w;

      /* Find bar hbox inside handle */
      w = gtk_hbox_new(FALSE, 0);
      editor->find_bar = w;
      gtk_container_add(GTK_CONTAINER(parent2), w);
      gtk_container_border_width(GTK_CONTAINER(w), 2);
      gtk_widget_show(w);
      parent3 = w;

      /* Find menu button */
      w = (GtkWidget *)GUIButtonPixmapLabelH(
          (guint8 **)icon_search_20x20_xpm, "Find:", NULL
      );
      editor->find_btn = w;
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
      gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NONE);
      gtk_widget_set_usize(w, mbw, mbh);
      gtk_signal_connect_after(
          GTK_OBJECT(w), "pressed",
          GTK_SIGNAL_FUNC(EditorButtonMenuMapCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_FIND_MB); 
      gtk_widget_show(w);

      /* Find menu button menu */
      menu = (GtkWidget *)GUIMenuCreate();
      editor->find_bar_find_menu = menu; 
      accel_group = NULL;
      mclient_data = (void *)editor;
      if(menu != NULL)
      {
          icon = (guint8 **)icon_search_20x20_xpm;
          label = "in Pages...";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorMapFIPCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->find_bar_find_in_pages_mi = w;
      }
      /* Need to attach basic "hide" signal to menu so we know when
       * it is unmapped.
       */
      gtk_signal_connect(
          GTK_OBJECT(menu), "hide",
          GTK_SIGNAL_FUNC(EditorMenuHideCB),
          (gpointer)editor
      );

      /* Find combo */
      w = (GtkWidget *)GUIComboCreate(
          NULL,         /* Label */
          NULL,         /* Initial text value */
          NULL,         /* Initial glist of items */
          20,                 /* Max items */
          &combo_rtn,         /* Combo widget return */
          editor,
          EditorFindBarFindActivateCB,
          NULL
      );
      editor->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);
      if(show_tooltips)
          GUISetWidgetTip(GTK_COMBO(combo_rtn)->entry, EDITOR_TT_FIND);
      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);

      /* Replace menu button */
      w = (GtkWidget *)GUIButtonPixmapLabelH(
          (guint8 **)icon_replace_20x20_xpm, "Replace:", NULL
      );
      editor->replace_btn = w;
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
      gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NONE);
      gtk_widget_set_usize(w, mbw, mbh);
      gtk_signal_connect_after(
          GTK_OBJECT(w), "pressed",
          GTK_SIGNAL_FUNC(EditorButtonMenuMapCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_REPLACE_MB);
      gtk_widget_show(w);

      /* Replace menu button menu */
      menu = (GtkWidget *)GUIMenuCreate();
      editor->find_bar_replace_menu = menu;
      accel_group = NULL;
      mclient_data = (void *)editor;
      if(menu != NULL)
      {
          icon = (guint8 **)icon_replace_all_20x20_xpm;
          label = "through Entire Page";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFindBarReplaceEntirePageCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->find_bar_replace_entire_page_mi = w;
      }
      /* Need to attach basic "hide" signal to menu so we know when
       * it is unmapped.
       */
      gtk_signal_connect(
          GTK_OBJECT(menu), "hide",
          GTK_SIGNAL_FUNC(EditorMenuHideCB),
          (gpointer)editor
      );

      /* Replace combo */
      w = (GtkWidget *)GUIComboCreate(
          NULL,         /* Label */
          NULL,               /* Initial text value */
          NULL,               /* Initial glist of items */
          20,                 /* Max items */
          &combo_rtn,         /* Combo widget return */
          (void *)editor,
          EditorFindBarReplaceActivateCB,
          NULL
      );
      editor->replace_combo = (GtkWidget *)combo_rtn;
      gtk_combo_set_case_sensitive(
          (GtkCombo *)combo_rtn,
          TRUE
      );
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
      if(show_tooltips)
          GUISetWidgetTip(GTK_COMBO(combo_rtn)->entry, EDITOR_TT_REPLACE);
      gtk_widget_show(w);

      /* Replace all */
      w = (GtkWidget *)GUIButtonPixmap(
          (guint8 **)icon_replace_all_20x20_xpm
      );
      editor->replace_all_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(EditorFindBarReplaceAllCB),
          (gpointer)editor
      );
      if(show_tooltips)
          GUISetWidgetTip(w, EDITOR_TT_REPLACE_ALL);
      gtk_widget_show(w);




#undef DO_ADD_MENU_ITEM_LABEL
#undef DO_ADD_MENU_ITEM_SUBMENU
#undef DO_ADD_MENU_ITEM_CHECK
#undef DO_ADD_MENU_SEP
}

/*
 *    Creates the status bar for the editor, this function should be
 *    called by EditorNew().
 *
 *    Given parent is assumed to be a vbox.
 */
static void EditorCreateStatusBar(
      editor_struct *editor, GtkWidget *parent
)
{
      GtkWidget *w, *parent2, *parent3;
      GtkAdjustment *adj;
      gboolean show_tooltips = TRUE;


      /* Main hbox for status bar and window map buttons */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
      gtk_widget_show(w);
      parent = w;

      /* Handle for status bar */
      w = gtk_handle_box_new();
      editor->status_bar_dock = w;
      gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, 0);
      gtk_widget_show(w);
      parent2 = w;

      /* Toplevel hbox inside dock */
      w = gtk_hbox_new(FALSE, 0);
      editor->status_bar_toplevel = w;
      gtk_container_add(GTK_CONTAINER(parent2), w);
      gtk_widget_show(w);
      parent2 = w;

      /* Main frame in toplevel */
      w = gtk_frame_new(NULL);
      gtk_widget_set_usize(w, -1, 25);
      gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_OUT);
      gtk_container_border_width(GTK_CONTAINER(w), 0);
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 0);
      gtk_widget_show(w);
      parent2 = w;

      /* Table in main frame */
      w = gtk_table_new(1, 3, FALSE);
      gtk_container_add(GTK_CONTAINER(parent2), w);
      gtk_widget_show(w);
      parent2 = w;


      /* Progress bar */
      adj = (GtkAdjustment *)gtk_adjustment_new(0, 1, 100, 0, 0, 0);
      w = gtk_progress_bar_new_with_adjustment(adj);
      editor->status_bar_progress = w;
      gtk_widget_set_usize(w, 100, -1);
      gtk_progress_bar_set_orientation(
          GTK_PROGRESS_BAR(w), GTK_PROGRESS_LEFT_TO_RIGHT
      );
      gtk_progress_bar_set_bar_style(
          GTK_PROGRESS_BAR(w), GTK_PROGRESS_CONTINUOUS
      );
      gtk_progress_set_activity_mode(
          GTK_PROGRESS(w), FALSE
      );
      gtk_table_attach(
          GTK_TABLE(parent2), w,
          0, 1, 0, 1,
          0,
          GTK_SHRINK | GTK_FILL,
          0, 0
      );
      gtk_widget_show(w);


      /* Label */
      w = gtk_frame_new(NULL);
      gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_IN);
      gtk_container_border_width(GTK_CONTAINER(w), 1);
      gtk_table_attach(
          GTK_TABLE(parent2), w,
          1, 2, 0, 1,
          GTK_SHRINK | GTK_EXPAND | GTK_FILL,
          GTK_SHRINK | GTK_FILL,
          0, 0
      );
      gtk_widget_show(w);
      parent3 = w;

      w = gtk_hbox_new(FALSE, 0);
      gtk_container_add(GTK_CONTAINER(parent3), w);
      gtk_widget_show(w);
      parent3 = w;

      w = gtk_label_new("");
      editor->status_bar_label = w;
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
      gtk_widget_show(w);


      /* Cursor position label */
      w = gtk_frame_new(NULL);
      gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_IN);
      gtk_container_border_width(GTK_CONTAINER(w), 1);
      gtk_table_attach(
          GTK_TABLE(parent2), w,
          2, 3, 0, 1,
          GTK_SHRINK | GTK_FILL,
          GTK_SHRINK | GTK_FILL,
          0, 0
      );
      gtk_widget_show(w);
      parent3 = w;

      w = gtk_hbox_new(FALSE, 0);
      gtk_container_add(GTK_CONTAINER(parent3), w);
      gtk_widget_show(w);
      parent3 = w;

      w = gtk_label_new("");
      editor->status_bar_cursor_label = w;
      gtk_widget_set_usize(w, 100, -1);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
      gtk_widget_show(w);



      /* Handle bar for window map buttons */
      w = gtk_handle_box_new();
/*    editor->window_map_dock = w; */
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
      gtk_widget_show(w);
      parent2 = w;

      /* Main frame in toplevel */
      w = gtk_frame_new(NULL);
      gtk_widget_set_usize(w, -1, 25);
      gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_OUT);
      gtk_container_border_width(GTK_CONTAINER(w), 0);
      gtk_container_add(GTK_CONTAINER(parent2), w);
      gtk_widget_show(w);
      parent2 = w;

      /* Hbox for window map buttons */
      w = gtk_hbox_new(FALSE, 0);
      gtk_container_add(GTK_CONTAINER(parent2), w); 
      gtk_widget_show(w);
      parent2 = w;

      /* Window map buttons */
      w = (GtkWidget *)GUIButtonPixmap(
          (guint8 **)manedit_16x16_xpm
      );
      gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NONE);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
      gtk_widget_set_usize(w, 25, -1);
      gtk_signal_connect(
          GTK_OBJECT(w), "clicked",
          GTK_SIGNAL_FUNC(MEditEditorNewCB),
          (gpointer)editor->core_ptr
      );
      if(show_tooltips)
          GUISetWidgetTip(w, MEDIT_SB_TT_NEW_EDITOR);
      gtk_widget_show(w);

      w = (GtkWidget *)GUIButtonPixmap(
          (guint8 **)mp_viewer_16x16_xpm
      );
      gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NONE);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
      gtk_widget_set_usize(w, 25, -1);
      gtk_signal_connect(
          GTK_OBJECT(w), "clicked",
          GTK_SIGNAL_FUNC(MEditViewerNewCB),
          (gpointer)editor->core_ptr
      );
      if(show_tooltips)
          GUISetWidgetTip(w, MEDIT_SB_TT_NEW_VIEWER);
      gtk_widget_show(w);
}

/*
 *    Creates a new editor structure with its values reset and widgets
 *    built or NULL on error.
 */
editor_struct *EditorNew(void *core_ptr)
{
      gint i;
      GtkWidget *w, *fw, *menu, *submenu;
      GtkWidget *parent, *parent2, *parent3, *parent4, *parent5;
      GtkWidget *scroll_parent;
      GdkColormap *colormap;
      GtkStyle *style_ptr;
      GtkCList *clist;
      gint header_label_width;
      gpointer entry_rtn;
      guint accel_key, accel_mods;
      gpointer accel_group;
      const gchar *label;
      guint8 **icon;
      gpointer mclient_data;
      void (*func_cb)(GtkWidget *w, gpointer);
      gchar *title[1];
      medit_cursors_list_struct *cursors_list = NULL;
      medit_styles_list_struct *styles_list = NULL;
      pref_struct *pref = NULL;
      const GtkTargetEntry dnd_tar_types[] = {
{"text/plain",                          0,      MEDIT_DND_TYPE_INFO_TEXT_PLAIN},
{"text/uri-list",                       0,      MEDIT_DND_TYPE_INFO_TEXT_URI_LIST},
{"STRING",                              0,      MEDIT_DND_TYPE_INFO_STRING},
{MEDIT_DND_TYPE_NAME_EDITOR_BRANCH_CMD,   GTK_TARGET_SAME_APP,
                                    MEDIT_DND_TYPE_INFO_EDITOR_BRANCH_CMD},
{MEDIT_DND_TYPE_NAME_VIEWER_BRANCH_CMD,   GTK_TARGET_SAME_APP,
                              MEDIT_DND_TYPE_INFO_VIEWER_BRANCH_CMD}
      };
      const GtkTargetEntry dnd_src_types[] = {
{MEDIT_DND_TYPE_NAME_EDITOR_BRANCH_CMD,   GTK_TARGET_SAME_APP,
                              MEDIT_DND_TYPE_INFO_EDITOR_BRANCH_CMD}
      };
      editor_struct *editor = (editor_struct *)g_malloc0(
          sizeof(editor_struct)
      );
      if(editor == NULL)
          return(NULL);


      /* Get pointers to resources on core structure */
      if(core_ptr != NULL)
      {
          cursors_list = &((medit_core_struct *)core_ptr)->cursors_list;
          styles_list = &((medit_core_struct *)core_ptr)->styles_list;
          pref = ((medit_core_struct *)core_ptr)->pref;
      }


      /* Reset values */
      editor->initialized = TRUE;
      editor->map_state = FALSE;
      editor->processing = FALSE;
      editor->syntax_highlighting = PrefParmGetValueB(
          ((medit_core_struct *)core_ptr)->pref,
          MEDIT_PREF_PARM_EDITOR_ENABLE_SYNHL
      );

      editor->core_ptr = core_ptr;
      editor->viewer_num = -1;

      editor->synhl_timeout_cb_id = (guint)(-1);
      editor->synhl_timeout_cb_cursor_pos = -1;
      editor->synhl_timeout_cb_start_pos = -1;
      editor->synhl_timeout_cb_end_pos = -1;

      editor->last_open_path = NULL;
      editor->last_save_as_path = NULL;



#define DO_ADD_MENU_ITEM_LABEL      \
{ \
 w = GUIMenuItemCreate( \
  menu, GUI_MENU_ITEM_TYPE_LABEL, accel_group, \
  icon, label, accel_key, accel_mods, (void **)&fw, \
  mclient_data, func_cb \
 ); \
}
#define DO_ADD_MENU_ITEM_SUBMENU    \
{ \
 w = GUIMenuItemCreate( \
  menu, GUI_MENU_ITEM_TYPE_SUBMENU, accel_group, \
  icon, label, accel_key, accel_mods, (void **)&fw, \
  mclient_data, func_cb \
 ); \
 if(w != NULL) \
  GUIMenuItemSetSubMenu(w, submenu); \
}
#define DO_ADD_MENU_ITEM_CHECK  \
{ \
 w = GUIMenuItemCreate( \
  menu, GUI_MENU_ITEM_TYPE_CHECK, accel_group, \
  icon, label, accel_key, accel_mods, (void **)&fw, \
  mclient_data, func_cb \
 ); \
}
#define DO_ADD_MENU_SEP \
{ \
 w = GUIMenuItemCreate( \
  menu, GUI_MENU_ITEM_TYPE_SEPARATOR, NULL, \
  NULL, NULL, 0, 0, NULL, \
  NULL, NULL \
 ); \
}

      /* Toplevel */
      w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
      editor->toplevel = w;
      gtk_widget_set_events(w,
          GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK
      );
      gtk_signal_connect(  
          GTK_OBJECT(w), "key_press_event",
          GTK_SIGNAL_FUNC(EditorKeyEventCB),
          (gpointer)editor
      );
      gtk_signal_connect(   
          GTK_OBJECT(w), "key_release_event",
          GTK_SIGNAL_FUNC(EditorKeyEventCB),
          (gpointer)editor
      );
      gtk_widget_realize(w);
      GUISetWMIcon(w->window, (guint8 **)manedit_48x48_xpm);
      if(PrefParmGetValueB(pref, MEDIT_PREF_PARM_RECORD_WIN_POS))
      {
          /* TRUE implies pref is also valid */
          gtk_widget_set_usize(
            w,
            MAX(pref->last_editor_width, 256),
            MAX(pref->last_editor_height, 256)
          );
      }
      else
      {
          gtk_widget_set_usize(
            w,
            MEDIT_DEF_WIDTH, MEDIT_DEF_HEIGHT
          );
      }
      gtk_window_set_policy(
          GTK_WINDOW(w), 
          TRUE, TRUE, FALSE
      );
      if((pref != NULL) && !GTK_WIDGET_NO_WINDOW(w))
      {
          GdkGeometry geometry;

          geometry.min_width = 100;
          geometry.min_height = 70;

          geometry.base_width = 0;
          geometry.base_height = 0;

          geometry.width_inc = 1;
          geometry.height_inc = 1;
/*
          geometry.min_aspect = 1.3;
          geometry.max_aspect = 1.3;
 */
          gdk_window_set_geometry_hints(
            w->window,
            &geometry,
            GDK_HINT_MIN_SIZE |
            GDK_HINT_BASE_SIZE |
            /* GDK_HINT_ASPECT | */
            GDK_HINT_RESIZE_INC
          );
      }
      gtk_signal_connect(
          GTK_OBJECT(w), "destroy",
          GTK_SIGNAL_FUNC(EditorDestroyCB),
          (gpointer)editor
      );
      gtk_signal_connect(
          GTK_OBJECT(w), "delete_event",
          GTK_SIGNAL_FUNC(EditorCloseCB),
          (gpointer)editor
      );
      parent = w;

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


      /* Menu bar */
      EditorCreateMenuBar(editor, editor->main_vbox);

      /* Tool bar */
      EditorCreateToolBar(editor, editor->main_vbox);


      /* Paned */
      w = gtk_hpaned_new();
      gtk_paned_set_handle_size(GTK_PANED(w), MEDIT_DEF_PANED_HANDLE_SIZE);
      gtk_paned_set_gutter_size(GTK_PANED(w), MEDIT_DEF_PANED_GUTTER_SIZE);
      gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, 0);
      gtk_paned_set_position(GTK_PANED(w), 200);
      gtk_widget_show(w);
      parent2 = w;


      /* Vbox for layout ctree */
      w = gtk_vbox_new(FALSE, 0);
      gtk_paned_add1(GTK_PANED(parent2), w);
      gtk_widget_show(w);
      parent3 = w;

      /* Layout ctree */
      w = gtk_scrolled_window_new(NULL, NULL);
      gtk_scrolled_window_set_policy(
          GTK_SCROLLED_WINDOW(w),
          GTK_POLICY_AUTOMATIC,
          GTK_POLICY_AUTOMATIC
      );
      gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, 0);
      gtk_widget_show(w);
      scroll_parent = w;

      title[0] = "Layout";
      w = gtk_ctree_new_with_titles(
          1, 0, title
      );
      clist = (GtkCList *)w;
      editor->layout_ctree = w;
      gtk_signal_connect_after(
          GTK_OBJECT(w), "button_press_event",
          GTK_SIGNAL_FUNC(EditorMenuMapCB),
          (gpointer)editor
      );
      gtk_clist_column_titles_passive(clist);
      gtk_clist_column_titles_hide(clist);
      gtk_clist_set_row_height(clist, MEDIT_LIST_ROW_SPACING);
      gtk_clist_set_shadow_type(clist, GTK_SHADOW_IN);
      gtk_container_add(GTK_CONTAINER(scroll_parent), w);
      gtk_signal_connect(
          GTK_OBJECT(w), "tree_select_row",
          GTK_SIGNAL_FUNC(EditorLayoutCTreeSelectCB),
          (gpointer)editor
      );
      gtk_signal_connect(
          GTK_OBJECT(w), "tree_unselect_row",
          GTK_SIGNAL_FUNC(EditorLayoutCTreeUnselectCB),
          (gpointer)editor
      );
      gtk_signal_connect(
          GTK_OBJECT(w), "tree_expand",
          GTK_SIGNAL_FUNC(EditorLayoutCTreeExpandCB),
          (gpointer)editor
      );
      gtk_signal_connect(
          GTK_OBJECT(w), "tree_collapse",
          GTK_SIGNAL_FUNC(EditorLayoutCTreeExpandCB),
          (gpointer)editor
      );
      /* Set up DND for the layout ctree */
      GUIDNDSetSrc(
          w,
          dnd_src_types,
          sizeof(dnd_src_types) / sizeof(GtkTargetEntry),
          GDK_ACTION_COPY | GDK_ACTION_MOVE,  /* Actions */
          GDK_BUTTON1_MASK,               /* Buttons */
          NULL,
          EditorDNDDataRequestCB,
          EditorDNDDataDeleteCB,
          NULL,
          editor
      );
      GUIDNDSetTar(
          w,
          dnd_tar_types,
          sizeof(dnd_tar_types) / sizeof(GtkTargetEntry),
          GDK_ACTION_COPY | GDK_ACTION_MOVE,  /* Actions */
          GDK_ACTION_MOVE,                    /* Default action if same */
          GDK_ACTION_COPY,                    /* Default action */
          EditorDNDDataRecievedCB,
          editor
      );
      gtk_widget_show(w);


      /* Layout ctree right click menu */
      menu = (GtkWidget *)GUIMenuCreate();
      editor->layout_menu = menu;
      accel_group = NULL;
      mclient_data = (void *)editor;

      if(menu != NULL)
      {
          icon = NULL;
          label = "Expand/Collapse";
          accel_key = 0; 
          accel_mods = 0;
          func_cb = EditorLayoutCTreeDoExpandCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->layout_menu_expand_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)mp_viewer_20x20_xpm;
          label = "Preview";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualPreviewCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->layout_menu_preview_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_add_20x20_xpm;
          label = "New Header";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualAddHeaderCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->layout_menu_add_header_mi = w;

          icon = (guint8 **)icon_add_20x20_xpm;
          label = "New Section";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualAddSectionCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->layout_menu_add_section_mi = w;

          icon = (guint8 **)icon_remove_20x20_xpm;
          label = "Remove";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualRemoveSectionCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->layout_menu_remove_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_properties2_20x20_xpm;
          label = "Properties...";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualPropertiesCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->layout_menu_properties_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_new_20x20_xpm;
          label = "New";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualNewCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->layout_menu_new_manual_mi = w;

          icon = (guint8 **)icon_new_20x20_xpm;
          label = "New From Template...";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualNewFromTemplateCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->layout_menu_new_from_template_mi = w;

          icon = (guint8 **)icon_open_20x20_xpm;
          label = "Open...";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualOpenCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->layout_menu_open_mi = w;

          icon = (guint8 **)icon_save_20x20_xpm;
          label = "Save";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualSaveCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->layout_menu_save_mi = w;

          icon = (guint8 **)icon_save_as_20x20_xpm;
          label = "Save As...";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualSaveAsCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->layout_menu_save_as_mi = w;

          DO_ADD_MENU_SEP
      
          icon = (guint8 **)icon_close_20x20_xpm;
          label = "Close Manual";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualCloseCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->layout_menu_close_manual_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_revert_20x20_xpm;
          label = "Revert";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorManualRevertCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->layout_menu_revert_mi = w;
      }


      /* ********************************************************** */
      /* Right panel side vbox */
      w = gtk_vbox_new(FALSE, 0);
      gtk_paned_add2(GTK_PANED(parent2), w);
      gtk_widget_show(w);
      parent2 = w;


      /* File editing panel */
      i = EditorItemTypeFile;

      w = gtk_vbox_new(FALSE, 0);
      editor->edit_panel_vbox[i] = w;
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 5);
      parent3 = w;




      /* Header editing panel */
      i = EditorItemTypeHeader;

      w = gtk_vbox_new(FALSE, 0);
      editor->edit_panel_vbox[i] = w;
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 5);
      parent3 = w;


      /* Begin creating header prompts */
      header_label_width = 100;

      /* Header name entry */
      w = gtk_hbox_new(FALSE, 2);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
      gtk_widget_show(w);
      parent4 = w;
      /* Label alignment and label */
      w = gtk_alignment_new(1.0, 0.5, 0.0, 0.0);
      gtk_widget_set_usize(w, header_label_width, -1);
      gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 0);
      gtk_widget_show(w);
      parent5 = w;
      w = gtk_label_new("Name:");
      gtk_container_add(GTK_CONTAINER(parent5), w);
      gtk_widget_show(w);
      /* Entry */
      w = gtk_entry_new_with_max_length(256);
      editor->header_name_entry = w;
      gtk_box_pack_start(GTK_BOX(parent4), w, TRUE, TRUE, 0);
      gtk_widget_show(w);

      /* Header section number entry */
      w = gtk_hbox_new(FALSE, 2);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
      gtk_widget_show(w);
      parent4 = w;
      /* Label alignment and label */
      w = gtk_alignment_new(1.0, 0.5, 0.0, 0.0);
      gtk_widget_set_usize(w, header_label_width, -1);
      gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 0);
      gtk_widget_show(w);
      parent5 = w;
      w = gtk_label_new("Section Number:");
      gtk_container_add(GTK_CONTAINER(parent5), w);
      gtk_widget_show(w);
      /* Entry */
      w = gtk_entry_new_with_max_length(256);
      editor->header_section_number_entry = w;
      gtk_box_pack_start(GTK_BOX(parent4), w, TRUE, TRUE, 0);
      gtk_widget_show(w);

      /* Header version entry */
      w = gtk_hbox_new(FALSE, 2);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
      gtk_widget_show(w);
      parent4 = w;
      /* Label alignment and label */
      w = gtk_alignment_new(1.0, 0.5, 0.0, 0.0);
      gtk_widget_set_usize(w, header_label_width, -1);
      gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 0);
      gtk_widget_show(w);
      parent5 = w;
      w = gtk_label_new("Version:");
      gtk_container_add(GTK_CONTAINER(parent5), w);
      gtk_widget_show(w);
      /* Entry */
      w = gtk_entry_new_with_max_length(256);
      editor->header_version_entry = w;
      gtk_box_pack_start(GTK_BOX(parent4), w, TRUE, TRUE, 0);
      gtk_widget_show(w);

      /* Header author entry */
      w = gtk_hbox_new(FALSE, 2);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
      gtk_widget_show(w);
      parent4 = w;
      /* Label alignment and label */
      w = gtk_alignment_new(1.0, 0.5, 0.0, 0.0);
      gtk_widget_set_usize(w, header_label_width, -1);
      gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 0);
      gtk_widget_show(w);
      parent5 = w;
      w = gtk_label_new("Author:");
      gtk_container_add(GTK_CONTAINER(parent5), w);
      gtk_widget_show(w);
      /* Entry */
      w = gtk_entry_new_with_max_length(256);
      editor->header_author_entry = w;
      gtk_box_pack_start(GTK_BOX(parent4), w, TRUE, TRUE, 0);
      gtk_widget_show(w);

      /* Header category entry */
      w = gtk_hbox_new(FALSE, 2);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
      gtk_widget_show(w);
      parent4 = w;
      /* Label alignment and label */
      w = gtk_alignment_new(1.0, 0.5, 0.0, 0.0);
      gtk_widget_set_usize(w, header_label_width, -1);
      gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 0);
      gtk_widget_show(w);
      parent5 = w;
      w = gtk_label_new("Category:");
      gtk_container_add(GTK_CONTAINER(parent5), w);
      gtk_widget_show(w);
      /* Entry */
      w = gtk_entry_new_with_max_length(256);
      editor->header_catagory_entry = w;
      gtk_box_pack_start(GTK_BOX(parent4), w, TRUE, TRUE, 0);
      gtk_widget_show(w);

      /* Separator (add 5 pixel extra vertical padding on each side) */
      w = gtk_hseparator_new();
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 5);
      gtk_widget_show(w);

      /* Vbox to hold a separator and widgets for text */
      w = gtk_vbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, 0);
      gtk_widget_show(w);
      parent4 = w;

      /* Hbox for comments label */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 2);
      gtk_widget_show(w);
      parent5 = w;

      w = gtk_label_new("Comments:");
      gtk_box_pack_start(GTK_BOX(parent5), w, FALSE, FALSE, 2);
      gtk_widget_show(w);


      /* Hbox for table */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent4), w, TRUE, TRUE, 0);
      gtk_widget_show(w);
      parent5 = 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(parent5), w, TRUE, TRUE, 2);
      gtk_widget_show(w);
      parent5 = w;

      w = gtk_text_new(NULL, NULL);
      editor->header_text = w;
      /* 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(EditorMenuMapCB),
          (gpointer)editor
      );
      gtk_signal_connect_after(
          GTK_OBJECT(w), "key_press_event",
          GTK_SIGNAL_FUNC(EditorTextKeyEventCB),
          (gpointer)editor
      );
      gtk_text_set_editable(GTK_TEXT(w), TRUE);
      gtk_text_set_word_wrap(GTK_TEXT(w), TRUE);
      gtk_table_attach(
          GTK_TABLE(parent5), 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(EditorTextChangeCB),
          (gpointer)editor
      );
      gtk_signal_connect(
          GTK_OBJECT(w), "insert_text",
          GTK_SIGNAL_FUNC(EditorTextInsertCB),
          (gpointer)editor
      );
      gtk_signal_connect(
          GTK_OBJECT(w), "delete_text",
          GTK_SIGNAL_FUNC(EditorTextDeleteCB),
          (gpointer)editor
      );
      gtk_widget_realize(w);
      if(cursors_list != NULL)
          gdk_window_set_cursor(w->window, cursors_list->text);
      gtk_widget_show(w);

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




      /* Section editing panel */
      i = EditorItemTypeSection;

      w = gtk_vbox_new(FALSE, 0);  
      editor->edit_panel_vbox[i] = w;
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 0);
      parent3 = w;


      /* Section name entry */
      w = (GtkWidget *)GUIPromptBar(
          NULL, "Section:", NULL, &entry_rtn
      );
      editor->section_name_entry = (GtkWidget *)entry_rtn;
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
      gtk_widget_show(w);


      /* Text box */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, 2);
      gtk_widget_show(w);
      parent4 = w;

      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(parent4), w, TRUE, TRUE, 2);
      gtk_widget_show(w);
      parent4 = w; 

      w = gtk_text_new(NULL, NULL);
      editor->section_text = w;
      /* 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(EditorMenuMapCB),
          (gpointer)editor
      );
      gtk_signal_connect_after(
          GTK_OBJECT(w), "key_press_event",
          GTK_SIGNAL_FUNC(EditorTextKeyEventCB),
          (gpointer)editor
      );
      gtk_text_set_editable(GTK_TEXT(w), TRUE);
      gtk_text_set_word_wrap(GTK_TEXT(w), TRUE);
      gtk_table_attach(
          GTK_TABLE(parent4), 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(EditorTextChangeCB),
          (gpointer)editor
      );
      gtk_signal_connect(
          GTK_OBJECT(w), "insert_text",
          GTK_SIGNAL_FUNC(EditorTextInsertCB),
          (gpointer)editor
      );
      gtk_signal_connect(
          GTK_OBJECT(w), "delete_text",
          GTK_SIGNAL_FUNC(EditorTextDeleteCB),
          (gpointer)editor
      );
      gtk_widget_realize(w);
      if(cursors_list != NULL)
          gdk_window_set_cursor(w->window, cursors_list->text);

      /* Create a new style for the GtkText, because we may want to
       * adjust the style later on.
       */
      if(GTK_WIDGET_NO_WINDOW(w))
          colormap = NULL;
      else
          colormap = gdk_window_get_colormap(w->window);
      style_ptr = gtk_widget_get_style(w);
      style_ptr = ((style_ptr == NULL) ?
          NULL : gtk_style_copy(style_ptr)
      );
      if(style_ptr != NULL)
      {
          GtkStyle *style_src_ptr;

          /* Set base color */
          style_src_ptr = styles_list->edit_text_background;
          if((style_src_ptr != NULL) && (colormap != NULL))
          {
            style_ptr->base[GTK_STATE_NORMAL] =
                style_src_ptr->base[GTK_STATE_NORMAL];
            gdk_color_alloc(
                colormap,
                &style_ptr->base[GTK_STATE_NORMAL]
            );
          }

          style_src_ptr = styles_list->edit_text_standard;
          if(style_src_ptr != NULL)
          {
            if(style_ptr->font != NULL)
                gdk_font_unref(style_ptr->font);
            style_ptr->font = style_src_ptr->font;
            if(style_ptr->font != NULL)
                gdk_font_ref(style_ptr->font);
          }

          gtk_widget_set_style(w, style_ptr);
      }
      gtk_widget_show(w);

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


      /* ************************************************************ */

      /* Editing panels right click tags submenu */
      submenu = menu = (GtkWidget *)GUIMenuCreate();
      editor->edit_panel_fmt_sub_menu = submenu;
      accel_group = NULL;
      mclient_data = (void *)editor;

      if(menu != NULL)
      {
          icon = (guint8 **)icon_paragraphl_20x20_xpm;
          label = "Paragraph Left";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtParagraphLeftCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_fmt_pl_mi = w;

          icon = (guint8 **)icon_paragraphr_20x20_xpm;
          label = "Paragraph Right";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtParagraphRightCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_fmt_pr_mi = w;
          
          icon = (guint8 **)icon_paragraphi_20x20_xpm;
          label = "Paragraph Indented";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtParagraphIndentedCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_fmt_pi_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_listitems_20x20_xpm;
          label = "List Item";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtListItemCB; 
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_fmt_li_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_bold_20x20_xpm;
          label = "Bold";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtBoldCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_fmt_b_mi = w;

          icon = (guint8 **)icon_underline_20x20_xpm;
          label = "Underline";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtUnderlineCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_fmt_u_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_break_20x20_xpm;
          label = "Line Break"; 
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtLineBreakCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_fmt_br_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_amp_20x20_xpm;
          label = "Ampersand";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtAmpersandCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_fmt_amp_mi = w;

          icon = (guint8 **)icon_lessthan_20x20_xpm;
          label = "Less Than";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtLessThanCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_fmt_lt_mi = w;

          icon = (guint8 **)icon_greaterthan_20x20_xpm;
          label = "Greater Than";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorFmtGreaterThanCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_fmt_gt_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_strip_tags_20x20_xpm;
          label = "Strip Tags";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorStripTagsCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_fmt_strip_tags_mi = w;
      }


      /* Editing panels right click menu */
      menu = (GtkWidget *)GUIMenuCreate();
      editor->edit_panel_menu = menu;
      accel_group = NULL;
      mclient_data = (void *)editor;

      if(menu != NULL)
      {
          icon = (guint8 **)icon_undo_20x20_xpm;
          label = "Undo";
          accel_key = GDK_BackSpace;
          accel_mods = GDK_CONTROL_MASK;
          func_cb = EditorUndoCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_undo_mi = w;
          editor->edit_panel_undo_milabel = fw;

          icon = (guint8 **)icon_redo_20x20_xpm;
          label = "Redo"; 
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorRedoCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_redo_mi = w;
          editor->edit_panel_redo_milabel = fw;

          DO_ADD_MENU_SEP 

          /* Format sub menu */
          icon = NULL;
          label = "Tags";
          accel_key = 0; 
          accel_mods = 0;
          func_cb = NULL;
          /* Variable submenu already set */
          DO_ADD_MENU_ITEM_SUBMENU

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_cut_20x20_xpm;
          label = "Cut";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorCutCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_cut_mi = w;

          icon = (guint8 **)icon_copy_20x20_xpm;
          label = "Copy";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorCopyCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_copy_mi = w;

          icon = (guint8 **)icon_paste_20x20_xpm;
          label = "Paste";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorPasteCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_paste_mi = w;

          DO_ADD_MENU_SEP

          icon = (guint8 **)icon_clipboard_20x20_xpm;
          label = "Clipboard Browser...";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorClipboardBrowserCB;
          DO_ADD_MENU_ITEM_LABEL

          DO_ADD_MENU_SEP

          icon = NULL;
          label = "Select All";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorSelectAllCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_select_all_mi = w;

          icon = NULL;
          label = "Unselect All";
          accel_key = 0;
          accel_mods = 0;
          func_cb = EditorUnselectAllCB;
          DO_ADD_MENU_ITEM_LABEL
          editor->edit_panel_unselect_all_mi = w;
      }





      /* Create status bar */
      EditorCreateStatusBar(editor, editor->main_vbox);

      /* Create editor Find In Page dialog */
      editor->fip_dialog = EditorFIPNew(
          core_ptr, (void *)editor
      );


#undef DO_ADD_MENU_ITEM_LABEL
#undef DO_ADD_MENU_ITEM_SUBMENU
#undef DO_ADD_MENU_ITEM_CHECK
#undef DO_ADD_MENU_SEP

      /* Reset values to defaults */
      EditorReset(editor, FALSE);

      /* Update menus */
      EditorUpdateMenus(editor);

      return(editor);
}

/*
 *    Updates all menus on editor.
 */
void EditorUpdateMenus(editor_struct *editor)
{
      static gboolean reenterant = FALSE;
      GtkWidget *w, *menu;
      medit_core_struct *core_ptr;
      gboolean sensitivity, state, sel_manual_has_changes;
      GtkCTreeRow *branch_row;
      editor_item_struct *item;
      gchar *sel_file_name = NULL;
      gint toolbar_btn_layout = 2;

      if(editor == NULL)
          return;

      core_ptr = MEDIT_CORE(editor->core_ptr);
      if(core_ptr == 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   {     \
 GUIMenuItemSetCheck(w, state, TRUE);           \
}

#define SET_BUTTON_LAYOUT     {           \
 if(w != NULL) {                    \
  switch(toolbar_btn_layout) {                  \
   case 2:                          \
    GUIButtonChangeLayout(w, 1, 1);       \
    gtk_widget_set_usize(w, 60, 50);            \
    break;                          \
   case 1:                          \
    GUIButtonChangeLayout(w, 1, 0);       \
    gtk_widget_set_usize(w, 30, 30);            \
    break;                          \
   default:                         \
    GUIButtonChangeLayout(w, 0, 1);       \
    gtk_widget_set_usize(w, -1, 30);            \
    break;                          \
  }                                 \
 }                                  \
}

      /* Check if the selected branch's manual page (if any) has
       * changes
       *
       * If none is selected then sel_manual_has_changes will be
       * FALSE
       */
      sel_manual_has_changes = FALSE;
      if(editor->selected_branch != NULL)
      {
          GtkCTreeNode *node, *next_node;
          GtkCTree *ctree = GTK_CTREE(editor->layout_ctree);

          /* Get toplevel node starting from selected branch node */
          for(
            node = editor->selected_branch;
            node != NULL;
            
          )
          {
            next_node = GTK_CTREE_ROW(node)->parent;
            if(next_node != NULL)
                node = next_node;
            else
                break;
          }
          if(node != NULL)
          {
            item = EditorBranchGetData(ctree, node);
            if((item != NULL) ?
                (item->type == EditorItemTypeFile) : FALSE
            )
            {
                if(item->has_changes)
                  sel_manual_has_changes = TRUE;

                /* Here's a good time to get the name */
                sel_file_name = item->name;
            }
          }
      }

      /* Get tool bar button display type */
      if(PrefParmGetValueB(
          core_ptr->pref, MEDIT_PREF_PARM_TOOLBAR_PT
      ))
          toolbar_btn_layout = 2;
      else if(PrefParmGetValueB(
          core_ptr->pref, MEDIT_PREF_PARM_TOOLBAR_P
      ))
          toolbar_btn_layout = 1;
      else
          toolbar_btn_layout = 0;


      /* Update title */
      w = editor->toplevel;
      if(w != NULL)
      {
          if(sel_file_name == NULL)
          {
            gtk_window_set_title(GTK_WINDOW(w), PROG_NAME);
          }
          else
          {
            gchar *title = g_strdup_printf(
                "%s: %s%s",
                PROG_NAME, sel_file_name,
                (sel_manual_has_changes) ? " (*)" : ""
            );
            gtk_window_set_title(GTK_WINDOW(w), title);
            g_free(title);
          }
      }


      /* File menu */
      menu = editor->file_mh;
      if(menu != NULL)
      {
          w = editor->open_mi;
          sensitivity = !FileBrowserIsQuery();
          SET_WIDGET_SENSITIVITY

          w = editor->save_mi;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          if(sensitivity)
            sensitivity = !FileBrowserIsQuery();
          SET_WIDGET_SENSITIVITY

          w = editor->save_as_mi;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          if(sensitivity)
            sensitivity = !FileBrowserIsQuery();
          SET_WIDGET_SENSITIVITY

          /* Revert enable only if entire manual has changes */
          w = editor->revert_mi;
          sensitivity = sel_manual_has_changes;
          SET_WIDGET_SENSITIVITY

          w = editor->close_manual_mi;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          if(sensitivity) 
            sensitivity = !FileBrowserIsQuery();
          SET_WIDGET_SENSITIVITY
      }

      /* Edit menu */
      menu = editor->edit_mh;
      if(menu != NULL)
      {
          editor_undo_common_struct *u_common;

          w = editor->undo_mi;
          sensitivity = ((editor->total_undos > 0) ?
            TRUE : FALSE
          );
          SET_WIDGET_SENSITIVITY

          w = editor->undo_milabel;
          if(w != NULL)
          {
            if(editor->total_undos > 0)
            {
                u_common = (editor_undo_common_struct *)editor->undo[0];
                if((u_common != NULL) ?
                  (u_common->comment != NULL) : FALSE
                )       
                {
                  gchar *buf = g_strdup_printf(
                      "Undo %s (%i)",
                      u_common->comment, editor->total_undos
                  );
                  gtk_label_set_text(GTK_LABEL(w), buf);
                  g_free(buf);
                }
            }
            else
            {
                gtk_label_set_text(GTK_LABEL(w), "Undo");
            }
          }


          w = editor->redo_mi;
          sensitivity = ((editor->total_redos > 0) ?
            TRUE : FALSE
          );
          SET_WIDGET_SENSITIVITY

          w = editor->redo_milabel;
          if(w != NULL)
          {
            if(editor->total_redos > 0)
            {
                u_common = (editor_undo_common_struct *)editor->redo[0];
                if((u_common != NULL) ?
                  (u_common->comment != NULL) : FALSE
                )
                {
                  gchar *buf = g_strdup_printf(
                      "Redo %s (%i)",
                      u_common->comment, editor->total_redos
                  );
                  gtk_label_set_text(GTK_LABEL(w), buf);
                  g_free(buf);
                }
            }
            else
            {
                gtk_label_set_text(GTK_LABEL(w), "Redo");
            }
          }

          w = editor->cut_mi;
          sensitivity = ((editor->selected_branch != NULL) ?
            TRUE : FALSE
          );
          SET_WIDGET_SENSITIVITY

          w = editor->copy_mi;
          sensitivity = ((editor->selected_branch != NULL) ?
            TRUE : FALSE
          );          
          SET_WIDGET_SENSITIVITY

          w = editor->paste_mi;
          sensitivity = ((editor->selected_branch != NULL) ?
            TRUE : FALSE
          );          
          SET_WIDGET_SENSITIVITY

          w = editor->select_all_mi;
          sensitivity = ((editor->selected_branch != NULL) ?
            TRUE : FALSE
          );
          SET_WIDGET_SENSITIVITY

          w = editor->unselect_all_mi;
          sensitivity = ((editor->selected_branch != NULL) ?
            TRUE : FALSE
          );
          SET_WIDGET_SENSITIVITY

          w = editor->find_in_pages_mi;
          sensitivity = ((editor->total_layout_trunks > 0) ?
            TRUE : FALSE
          );
          SET_WIDGET_SENSITIVITY
      }

      /* View menu */
      menu = editor->view_mh;
      if(menu != NULL)
      {
          w = editor->preview_mi;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          SET_WIDGET_SENSITIVITY

          w = editor->syntax_highlight_cmi;
          state = editor->syntax_highlighting;
          SET_CHECK_MENU_ITEM_STATE
      }


      /* Layout menu */
      menu = editor->layout_mh;
      if(menu != NULL)
      {
          /* Show or hide menu depending on if a branch is selected */
          if(editor->selected_branch == NULL)
            gtk_widget_hide(menu);
          else
            gtk_widget_show(menu);
      }

      /* Format menu */
      menu = editor->fmt_mh;
      if(menu != NULL)
      {
          item = EditorBranchGetData(
            (GtkCTree *)editor->layout_ctree,
            editor->selected_branch
          );
          sensitivity = ((item == NULL) ?
            FALSE : (item->type == EditorItemTypeSection)
          );

          /* Show or hide menu depending on if a branch is selected */
          if((item == NULL) ?
            0 : (item->type == EditorItemTypeSection)
          )
            gtk_widget_show(menu);
          else
            gtk_widget_hide(menu);
      }


      /* Right click menus */

      /* Layout ctree menu */
      menu = editor->layout_menu;
      if(menu != NULL)
      {
          if(editor->selected_branch != NULL)
            branch_row = GTK_CTREE_ROW(editor->selected_branch);
          else
            branch_row = NULL;
          sensitivity = ((branch_row == NULL) ?
            FALSE : !branch_row->is_leaf
          );
          w = editor->layout_menu_expand_mi;
          SET_WIDGET_SENSITIVITY

          w = editor->layout_menu_preview_mi;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          SET_WIDGET_SENSITIVITY

          w = editor->layout_menu_add_header_mi;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          SET_WIDGET_SENSITIVITY

          w = editor->layout_menu_add_section_mi;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          SET_WIDGET_SENSITIVITY

          w = editor->layout_menu_remove_mi;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          SET_WIDGET_SENSITIVITY

          w = editor->layout_menu_properties_mi;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          SET_WIDGET_SENSITIVITY

          w = editor->layout_menu_open_mi;
          sensitivity = !FileBrowserIsQuery();
          SET_WIDGET_SENSITIVITY

          w = editor->layout_menu_save_mi;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          if(sensitivity)
            sensitivity = !FileBrowserIsQuery();
          SET_WIDGET_SENSITIVITY

          w = editor->layout_menu_save_as_mi;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          if(sensitivity)
            sensitivity = !FileBrowserIsQuery();
          SET_WIDGET_SENSITIVITY

          /* Revert enable only if entire manual has changes */
          w = editor->layout_menu_revert_mi;
          sensitivity = sel_manual_has_changes;
          SET_WIDGET_SENSITIVITY

          w = editor->layout_menu_close_manual_mi;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          if(sensitivity)
            sensitivity = !FileBrowserIsQuery();
          SET_WIDGET_SENSITIVITY
      }


      /* Editor panel widgets menu */
      menu = editor->edit_panel_menu;
      if(menu != NULL)
      {
          editor_undo_common_struct *u_common;

          w = editor->edit_panel_undo_mi;
          sensitivity = ((editor->total_undos > 0) ?
            TRUE : FALSE
          );
          SET_WIDGET_SENSITIVITY

          w = editor->edit_panel_undo_milabel;
          if(w != NULL)
          {
            if(editor->total_undos > 0)
            {
                u_common = (editor_undo_common_struct *)editor->undo[0];
                if((u_common != NULL) ?
                  (u_common->comment != NULL) : FALSE
                )
                {
                  gchar *buf = g_strdup_printf(
                      "Undo %s (%i)",
                      u_common->comment, editor->total_undos
                  );
                  gtk_label_set_text(GTK_LABEL(w), buf);
                  g_free(buf);
                }
            }
            else
            {
                gtk_label_set_text(GTK_LABEL(w), "Undo");
            }
          }


          w = editor->edit_panel_redo_mi;
          sensitivity = ((editor->total_redos > 0) ?
            TRUE : FALSE
          );
          SET_WIDGET_SENSITIVITY

          w = editor->edit_panel_redo_milabel;
          if(w != NULL)
          {
            if(editor->total_redos > 0)
            {
                u_common = (editor_undo_common_struct *)editor->redo[0];
                if((u_common != NULL) ?
                  (u_common->comment != NULL) : FALSE
                )
                {
                  gchar *buf = g_strdup_printf(
                      "Redo %s (%i)",
                      u_common->comment, editor->total_redos
                  );
                  gtk_label_set_text(GTK_LABEL(w), buf);
                  g_free(buf);
                }
            }
            else
            {
                gtk_label_set_text(GTK_LABEL(w), "Redo");
            }
          }

          w = editor->edit_panel_cut_mi;
          sensitivity = ((editor->selected_branch != NULL) ?
            TRUE : FALSE
          );
          SET_WIDGET_SENSITIVITY

          w = editor->edit_panel_copy_mi;
          sensitivity = ((editor->selected_branch != NULL) ?
            TRUE : FALSE
          );
          SET_WIDGET_SENSITIVITY

          w = editor->edit_panel_paste_mi;
          sensitivity = ((editor->selected_branch != NULL) ?
            TRUE : FALSE
          );
          SET_WIDGET_SENSITIVITY

          w = editor->edit_panel_select_all_mi;
          sensitivity = ((editor->selected_branch != NULL) ?
            TRUE : FALSE
          );
          SET_WIDGET_SENSITIVITY

          w = editor->edit_panel_unselect_all_mi;
          sensitivity = ((editor->selected_branch != NULL) ?
            TRUE : FALSE
          );
          SET_WIDGET_SENSITIVITY
      }
      /* Edit panel format submenu */
      menu = editor->edit_panel_fmt_sub_menu;
      if(menu != NULL)
      {
          item = EditorBranchGetData(
            (GtkCTree *)editor->layout_ctree,
            editor->selected_branch
          );
          sensitivity = ((item == NULL) ?
            FALSE : (item->type == EditorItemTypeSection)
          );

          w = editor->edit_panel_fmt_pl_mi;
          SET_WIDGET_SENSITIVITY

          w = editor->edit_panel_fmt_pr_mi;
          SET_WIDGET_SENSITIVITY

          w = editor->edit_panel_fmt_pi_mi;
          SET_WIDGET_SENSITIVITY

          w = editor->edit_panel_fmt_li_mi;
          SET_WIDGET_SENSITIVITY

          w = editor->edit_panel_fmt_b_mi;
          SET_WIDGET_SENSITIVITY

          w = editor->edit_panel_fmt_u_mi;
          SET_WIDGET_SENSITIVITY

          w = editor->edit_panel_fmt_br_mi;
          SET_WIDGET_SENSITIVITY

          w = editor->edit_panel_fmt_amp_mi;
          SET_WIDGET_SENSITIVITY

          w = editor->edit_panel_fmt_lt_mi;
          SET_WIDGET_SENSITIVITY

          w = editor->edit_panel_fmt_gt_mi;
          SET_WIDGET_SENSITIVITY

          w = editor->edit_panel_fmt_strip_tags_mi;
          SET_WIDGET_SENSITIVITY
      }


      /* Tool bar buttons */
      w = editor->tool_bar;
      if(w != NULL)
      {
          w = editor->new_btn;
          SET_BUTTON_LAYOUT

          w = editor->open_btn;
          sensitivity = !FileBrowserIsQuery();
          SET_WIDGET_SENSITIVITY
          SET_BUTTON_LAYOUT

          w = editor->save_btn;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          if(sensitivity)
            sensitivity = !FileBrowserIsQuery();
          SET_WIDGET_SENSITIVITY
          SET_BUTTON_LAYOUT

          w = editor->save_as_btn;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          if(sensitivity)
            sensitivity = !FileBrowserIsQuery();
          SET_WIDGET_SENSITIVITY
          SET_BUTTON_LAYOUT

          w = editor->close_btn;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          if(sensitivity)
            sensitivity = !FileBrowserIsQuery();
          SET_WIDGET_SENSITIVITY
          SET_BUTTON_LAYOUT


          w = editor->undo_btn;
          sensitivity = ((editor->total_undos > 0) ?
            TRUE : FALSE
          );
          SET_WIDGET_SENSITIVITY
          SET_BUTTON_LAYOUT

          w = editor->redo_btn;
          sensitivity = ((editor->total_redos > 0) ?
            TRUE : FALSE
          );
          SET_WIDGET_SENSITIVITY
          SET_BUTTON_LAYOUT


          w = editor->cut_btn;
          SET_BUTTON_LAYOUT

          w = editor->copy_btn;
          SET_BUTTON_LAYOUT

          w = editor->paste_btn;
          SET_BUTTON_LAYOUT


          w = editor->add_header_btn;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          SET_WIDGET_SENSITIVITY
          SET_BUTTON_LAYOUT

          w = editor->add_section_btn;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          SET_WIDGET_SENSITIVITY
          SET_BUTTON_LAYOUT

          w = editor->remove_btn;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          SET_WIDGET_SENSITIVITY
          SET_BUTTON_LAYOUT

          w = editor->properties_btn;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          SET_WIDGET_SENSITIVITY 
          SET_BUTTON_LAYOUT

          w = editor->preview_btn;
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );
          SET_WIDGET_SENSITIVITY
          SET_BUTTON_LAYOUT
      }

      /* Format bar buttons */
      w = editor->fmt_bar;
      if(w != NULL)
      {
          item = EditorBranchGetData(
            (GtkCTree *)editor->layout_ctree,
            editor->selected_branch
          );
          sensitivity = ((item == NULL) ?
            FALSE : (item->type == EditorItemTypeSection)
          );

          w = editor->fmt_pl_btn;
          SET_WIDGET_SENSITIVITY

          w = editor->fmt_pr_btn;
          SET_WIDGET_SENSITIVITY

          w = editor->fmt_pi_btn;
          SET_WIDGET_SENSITIVITY

          w = editor->fmt_li_btn;
          SET_WIDGET_SENSITIVITY

          w = editor->fmt_b_btn;
          SET_WIDGET_SENSITIVITY

          w = editor->fmt_u_btn;
          SET_WIDGET_SENSITIVITY

          w = editor->fmt_br_btn;
          SET_WIDGET_SENSITIVITY

          w = editor->fmt_amp_btn;
          SET_WIDGET_SENSITIVITY

          w = editor->fmt_lt_btn;
          SET_WIDGET_SENSITIVITY

          w = editor->fmt_gt_btn;
          SET_WIDGET_SENSITIVITY

          w = editor->fmt_strip_tags_btn;
          SET_WIDGET_SENSITIVITY
      }

      /* Find bar */
      w = editor->find_bar;
      if(w != NULL)
      {
          sensitivity = ((editor->selected_branch == NULL) ?
            FALSE : TRUE
          );

          w = editor->find_combo;
          SET_WIDGET_SENSITIVITY

          w = editor->replace_combo; 
          SET_WIDGET_SENSITIVITY

          w = editor->replace_all_btn;
          SET_WIDGET_SENSITIVITY
      }
      /* Find bar find button menu */
      w = editor->find_bar_find_menu;
      if(w != NULL)
      {
          w = editor->find_bar_find_in_pages_mi;
          sensitivity = ((editor->total_layout_trunks > 0) ?
            TRUE : FALSE
          );
          SET_WIDGET_SENSITIVITY
      }
      /* Find bar replace button menu */
      w = editor->find_bar_replace_menu;
      if(w != NULL)
      {
          w = editor->find_bar_replace_entire_page_mi;
          sensitivity = ((editor->total_layout_trunks > 0) ?
            TRUE : FALSE
          );
          SET_WIDGET_SENSITIVITY
      }

#undef SET_WIDGET_SENSITIVITY
#undef SET_CHECK_MENU_ITEM_STATE
#undef SET_BUTTON_LAYOUT

      reenterant = FALSE;
}



/*
 *    Updates the cursor position value on the status bar.
 */
void EditorSetStatusPosition(editor_struct *editor, gint row, gint column)
{
      gchar *buf;
      GtkWidget *w = (editor != NULL) ?
          editor->status_bar_cursor_label : NULL;
      if(w == NULL)
          return;

      buf = g_strdup_printf(
          "Line: %i / Col: %i",
          row + 1, column + 1
      );
      gtk_label_set_text(GTK_LABEL(w), buf);
      g_free(buf);

      while(gtk_events_pending() > 0)
          gtk_main_iteration();
}

/*
 *    Sets the status message for the editor.
 *
 *    Passing NULL clears the message.
 *
 *      Note that gtk_main_iteration() will be called when this function
 *      is called to update the label properly.
 */
void EditorSetStatusMessage(editor_struct *editor, const gchar *mesg)
{
      GtkWidget *w = (editor != NULL) ?
          editor->status_bar_label : NULL;
      if(w == NULL)
          return;

      gtk_label_set_text(
          GTK_LABEL(w),
          (mesg != NULL) ? mesg : ""
      );

      while(gtk_events_pending() > 0)
          gtk_main_iteration();
}

/*
 *    Sets the status of the progress bar on the editor.
 *
 *    Value must be from 0.0 to 1.0 inclusive.
 *
 *    Note that gtk_main_iteration() will be called when this function
 *    is called to update the progress bar properly.
 */
void EditorSetStatusProgress(editor_struct *editor, gfloat percent)
{
      gfloat p;
      GtkWidget *w = (editor != NULL) ?
          editor->status_bar_progress : NULL;
      if(w == NULL)
          return;

      /* Do activity? */
      if(percent < 0.0f)
      {
          GtkAdjustment *adj = GTK_PROGRESS(w)->adjustment;

          percent = gtk_progress_get_value(GTK_PROGRESS(w)) + 1;

          if(percent > adj->upper)
            percent = adj->lower;

          gtk_progress_set_activity_mode(
            GTK_PROGRESS(w), TRUE
          );
          gtk_progress_set_value(GTK_PROGRESS(w), percent);

          while(gtk_events_pending() > 0)
            gtk_main_iteration();
      }

      if(percent > 1.0f)
          percent = 1.0f;

      gtk_progress_set_activity_mode(
          GTK_PROGRESS(w), FALSE
      );
      gtk_progress_set_format_string(
          GTK_PROGRESS(w), "%p%%"
      );
      gtk_progress_set_show_text(
          GTK_PROGRESS(w), (percent > 0.0f) ? TRUE : FALSE
      );

      p = editor->status_bar_progress_pos_last;
      if(p > percent)
          p = percent;

      while(TRUE)
      {
          if(p > percent)
            p = percent;

          gtk_progress_bar_update(
            GTK_PROGRESS_BAR(w), p
          );

          while(gtk_events_pending() > 0)
            gtk_main_iteration();

          if(p < percent)
            p += 0.05f;
          else
            break;
      }

      editor->status_bar_progress_pos_last = percent;
}

/*
 *    Records positions and sizes of editor's widgets onto its
 *    core structure's preferences structure.
 */
void EditorRecordPositions(editor_struct *editor)
{
      GtkWidget *w;
      pref_struct *pref;
      medit_core_struct *core_ptr;

      if(editor == NULL)
          return;

      if(editor->processing)
          return;

      core_ptr = (medit_core_struct *)editor->core_ptr;
      if(core_ptr == NULL)
          return;

      pref = core_ptr->pref;
      if(pref == NULL)
          return;

      w = editor->toplevel;
      if(w != NULL)
      {
          GdkWindow *window = w->window;
          if(window != NULL)
          {
            gint x, y, width, height, depth;

            gdk_window_get_geometry(
                window, &x, &y, &width, &height, &depth
            );

            pref->last_editor_width = MAX(width, 0);
            pref->last_editor_height = MAX(height, 0);
          }

          if(editor->last_open_path != NULL)
          {
            g_free(pref->last_opened_manpage_path);
            pref->last_opened_manpage_path = STRDUP(
                editor->last_open_path
            );
          }
          if(editor->last_save_as_path != NULL)
          {
            g_free(pref->last_saved_manpage_path);
            pref->last_saved_manpage_path = STRDUP(
                editor->last_save_as_path
            );
          }
      }
}


/*
 *    Deletes the undo/redo list on the editor.
 */
void EditorResetUndos(editor_struct *editor)
{
      gint i;

      if(editor == NULL)
          return;

      /* Delete all undos and redos */
      for(i = 0; i < editor->total_undos; i++)
          EditorUndoDelete(editor, editor->undo[i]);
      g_free(editor->undo);
      editor->undo = NULL;
      editor->total_undos = 0;
  
      for(i = 0; i < editor->total_redos; i++)
          EditorUndoDelete(editor, editor->redo[i]);
      g_free(editor->redo);
      editor->redo = NULL;
      editor->total_redos = 0;
}

/*
 *    Resets all values to defaults on editor and deletes
 *    undo/redo list and all layout branches.
 */
void EditorReset(editor_struct *editor, gboolean need_unmap)
{
      static gboolean reenterant = FALSE;
      GtkWidget *w;
      pref_struct *pref;
      medit_core_struct *core_ptr;


      if(editor == NULL)
          return;

      if(!editor->initialized)
          return;

      if(editor->processing)
          return;

      core_ptr = (medit_core_struct *)editor->core_ptr;
      if(core_ptr == NULL)
          return;

      pref = core_ptr->pref;

      if(reenterant)
          return;
      else
          reenterant = TRUE;

      /* Unmap as needed */ 
      if(need_unmap)
      {   
          w = editor->toplevel;
          if(w != NULL)
            gtk_widget_hide(w);
          editor->map_state = FALSE;
      }

      /* Reset values */
      editor->processing = FALSE;
      editor->syntax_highlighting = PrefParmGetValueB(
          core_ptr->pref,
          MEDIT_PREF_PARM_EDITOR_ENABLE_SYNHL
      );
      editor->viewer_num = -1;
      editor->max_undos = 5;
      editor->status_bar_progress_pos_last = 0;

      /* Syntax highlight callback id */
      if(editor->synhl_timeout_cb_id != (guint)(-1))
      {
          gtk_timeout_remove(editor->synhl_timeout_cb_id);
          editor->synhl_timeout_cb_id = (guint)(-1);
      }
      editor->synhl_timeout_cb_cursor_pos = -1;
      editor->synhl_timeout_cb_start_pos = -1;
      editor->synhl_timeout_cb_end_pos = -1;

      /* Resize toplevel */
      w = editor->toplevel;
      if((w == NULL) ? 0 : !GTK_WIDGET_NO_WINDOW(w))
      {
        if(PrefParmGetValueB(pref, MEDIT_PREF_PARM_RECORD_WIN_POS))
        {
          /* TRUE implies pref is also valid */
          gtk_widget_set_usize(
            w, 
            MAX(pref->last_editor_width, 256),
            MAX(pref->last_editor_height, 256)
          );
        }
        else
        {
          gtk_widget_set_usize(
             w,  
            MEDIT_DEF_WIDTH, MEDIT_DEF_HEIGHT
          );
        }
      }

      /* Reset status messages */
      EditorSetStatusPosition(editor, 0, 0);
      EditorSetStatusMessage(editor, NULL);
      EditorSetStatusProgress(editor, 0.0);

      /* Delete all undos and redos */
      EditorResetUndos(editor);

      /* Delete all layout trunks on layout ctree, this will cause
       * any of our user set data to be properly deleted as
       * well.
       *
       * Currently selected branch pointer and layout trunks list will
       * updated properly when the destroy notify is called when the
       * branch node is destroyed.
       */
      EditorLayoutTrunkDeleteAll(editor);

      /* Remove layout trunks list, just in case */
      g_free(editor->layout_trunk);
      editor->layout_trunk = NULL;
      editor->total_layout_trunks = 0;

      /* Mark no branch is selected, just in case */
      editor->selected_branch = NULL;


      /* Reset column width on layout ctree */
      w = editor->layout_ctree;
      if(w != NULL)
          gtk_clist_set_column_width(GTK_CLIST(w), 0, 100);

      /* Get paths */
      if((pref != NULL) ?
          (pref->last_opened_manpage_path != NULL) : FALSE
      )
      {
          g_free(editor->last_open_path);
          editor->last_open_path = STRDUP(pref->last_opened_manpage_path);
      }
      if((pref != NULL) ? 
          (pref->last_saved_manpage_path != NULL) : FALSE
      )
      {
          g_free(editor->last_save_as_path);
          editor->last_save_as_path = STRDUP(pref->last_saved_manpage_path);
      }

      /* Reset title */
      w = editor->toplevel;
      if(w != NULL)
          gtk_window_set_title(GTK_WINDOW(w), PROG_NAME);


      /* Reset editor Find In Pages dialog */
      EditorFIPReset(editor->fip_dialog, need_unmap);

      reenterant = FALSE;
}

/*
 *    Maps editor as needed.
 */
void EditorMap(editor_struct *editor)
{
      GtkWidget *w;

      if(editor == NULL)
          return;

      if(!editor->initialized)
          return;

      w = editor->toplevel;
      if(w == NULL)
          return;

      if(!editor->map_state)
      {
          editor->map_state = TRUE;
          gtk_widget_show(w);
      }
}

/*
 *      Unmaps editor as needed.
 */
void EditorUnmap(editor_struct *editor)
{       
      GtkWidget *w;
      
      if(editor == NULL)
          return;
      
      if(!editor->initialized)
          return;
   
      w = editor->toplevel;
      if(w == NULL)
          return;
      
      if(editor->map_state)
      {
          editor->map_state = FALSE;
          gtk_widget_hide(w);
      }
}


/*
 *    Destroys the editor and all its widgets and allocated resources.
 *
 *    The editor structure itself will also be deleted.
 */
void EditorDelete(editor_struct *editor)
{
      gint i;
      GtkWidget *w;


      if(editor == NULL)
          return;

      if(editor->initialized)
      {
          /* Still processing? */
          if(editor->processing)
            return;

          /* Reset values to defaults, this will cause any loaded data
           * to be deleted.
           */
          EditorReset(editor, TRUE);


          /* Delete editor Find In Pages dialog */
          EditorFIPDelete(editor->fip_dialog);
          editor->fip_dialog = NULL;


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

          editor->file_mh = NULL;
          editor->new_mi = NULL;
          editor->new_from_template_mi = NULL;
          editor->open_mi = NULL;
          editor->save_mi = NULL;
          editor->save_as_mi = NULL;
          editor->revert_mi = NULL;
          editor->close_manual_mi = NULL;
          editor->close_mi = NULL;
          editor->exit_mi = NULL;

          editor->edit_mh = NULL;
          editor->undo_mi = NULL;
          editor->undo_milabel = NULL;
          editor->redo_mi = NULL;
          editor->redo_milabel = NULL;
          editor->cut_mi = NULL;
          editor->copy_mi = NULL;
          editor->paste_mi = NULL;
          editor->select_all_mi = NULL;
          editor->unselect_all_mi = NULL;
          editor->find_in_pages_mi = NULL;

          editor->view_mh = NULL;
          editor->preview_mi = NULL;
          editor->syntax_highlight_cmi = NULL;

          editor->layout_mh = NULL;
          editor->add_header_mi = NULL;
          editor->add_section_mi = NULL;
          editor->remove_mi = NULL;
          editor->properties_mi = NULL;

          editor->fmt_mh = NULL;
          editor->fmt_pl_mi = NULL;
          editor->fmt_pr_mi = NULL;
          editor->fmt_pi_mi = NULL;
          editor->fmt_li_mi = NULL;
          editor->fmt_b_mi = NULL;
          editor->fmt_u_mi = NULL;
          editor->fmt_br_mi = NULL;
          editor->fmt_amp_mi = NULL;
          editor->fmt_lt_mi = NULL;
          editor->fmt_gt_mi = NULL;
          editor->fmt_strip_tags_mi = NULL;

          editor->windows_mh = NULL;
          editor->windows_new_editor = NULL;
          editor->windows_new_viewer = NULL;

          w = editor->menu_bar;
          editor->menu_bar = NULL;    
          DO_DESTROY_WIDGET

          w = editor->menu_bar_dock;
          editor->menu_bar_dock = NULL;
          DO_DESTROY_WIDGET


          editor->new_btn = NULL;
          editor->open_btn = NULL;
          editor->save_btn = NULL;
          editor->save_as_btn = NULL;
          editor->close_btn = NULL;

          editor->undo_btn = NULL;
          editor->redo_btn = NULL;

          editor->cut_btn = NULL;
          editor->copy_btn = NULL;
          editor->paste_btn = NULL;

          editor->add_header_btn = NULL;
          editor->add_section_btn = NULL;
          editor->remove_btn = NULL;

          editor->preview_btn = NULL;

          w = editor->new_btn_new_menu;
          editor->new_btn_new_menu = NULL;
          editor->new_btn_new_mi = NULL;
          editor->new_btn_new_from_template_mi = NULL;
          DO_DESTROY_WIDGET

          w = editor->tool_bar;   
          editor->tool_bar = NULL;
          DO_DESTROY_WIDGET

          w = editor->tool_bar_dock;
          editor->tool_bar_dock = NULL;
          DO_DESTROY_WIDGET


          editor->fmt_pl_btn = NULL;
          editor->fmt_pr_btn = NULL;
          editor->fmt_pi_btn = NULL;
          editor->fmt_li_btn = NULL;
          editor->fmt_b_btn = NULL;
          editor->fmt_u_btn = NULL;
          editor->fmt_br_btn = NULL;
          editor->fmt_amp_btn = NULL;
          editor->fmt_lt_btn = NULL;
          editor->fmt_gt_btn = NULL;
          editor->fmt_strip_tags_btn = NULL;

          w = editor->fmt_bar;
          editor->fmt_bar = NULL;
          DO_DESTROY_WIDGET

          w = editor->fmt_bar_dock;
          editor->fmt_bar_dock = NULL;
          DO_DESTROY_WIDGET


          editor->find_combo = NULL;
          editor->find_btn = NULL;
          editor->replace_combo = NULL;
          editor->replace_btn = NULL;
          editor->replace_all_btn = NULL;

          editor->find_bar_find_in_pages_mi = NULL;

          w = editor->find_bar_find_menu;
          editor->find_bar_find_menu = NULL;
          DO_DESTROY_WIDGET

          w = editor->find_bar;
          editor->find_bar = NULL;   
          DO_DESTROY_WIDGET

          w = editor->find_bar_dock;
          editor->find_bar_dock = NULL;
          DO_DESTROY_WIDGET


          w = editor->layout_menu;
          editor->layout_menu = NULL;
          editor->layout_menu_expand_mi = NULL;
          editor->layout_menu_preview_mi = NULL;
          editor->layout_menu_add_header_mi = NULL;
          editor->layout_menu_add_section_mi = NULL;
          editor->layout_menu_remove_mi = NULL;
          editor->layout_menu_properties_mi = NULL;
          editor->layout_menu_new_manual_mi = NULL;
          editor->layout_menu_new_from_template_mi = NULL;
          editor->layout_menu_open_mi = NULL;
          editor->layout_menu_save_mi = NULL;
          editor->layout_menu_save_as_mi = NULL;
          editor->layout_menu_revert_mi = NULL;
          editor->layout_menu_close_manual_mi = NULL;

          editor->edit_panel_fmt_sub_menu = NULL;
          editor->edit_panel_fmt_pl_mi = NULL;
          editor->edit_panel_fmt_pr_mi = NULL;
          editor->edit_panel_fmt_pi_mi = NULL;
          editor->edit_panel_fmt_li_mi = NULL;
          editor->edit_panel_fmt_b_mi = NULL;
          editor->edit_panel_fmt_u_mi = NULL;
          editor->edit_panel_fmt_br_mi = NULL;
          editor->edit_panel_fmt_amp_mi = NULL;
          editor->edit_panel_fmt_lt_mi = NULL;
          editor->edit_panel_fmt_gt_mi = NULL;
          editor->edit_panel_fmt_strip_tags_mi = NULL;
          DO_DESTROY_WIDGET

          w = editor->edit_panel_menu;
          editor->edit_panel_menu = NULL;
          editor->edit_panel_undo_mi = NULL;
          editor->edit_panel_undo_milabel = NULL;
          editor->edit_panel_redo_mi = NULL;
          editor->edit_panel_redo_milabel = NULL;
          editor->edit_panel_cut_mi = NULL;
          editor->edit_panel_copy_mi = NULL;
          editor->edit_panel_paste_mi = NULL;
          editor->edit_panel_select_all_mi = NULL;
          editor->edit_panel_unselect_all_mi = NULL;
          DO_DESTROY_WIDGET


          w = editor->layout_ctree;
          editor->layout_ctree = NULL;
          DO_DESTROY_WIDGET

          editor->header_name_entry = NULL;
          editor->header_section_number_entry = NULL;
          editor->header_version_entry = NULL;
          editor->header_author_entry = NULL;
          editor->header_catagory_entry = NULL;
          editor->header_text = NULL;

          editor->section_name_entry = NULL;
          editor->section_text = NULL;

          for(i = 0; i < MEDIT_EDIT_PANEL_MAX; i++)
          {
            w = editor->edit_panel_vbox[i];
            editor->edit_panel_vbox[i] = NULL;
            DO_DESTROY_WIDGET
          }


          w = editor->status_bar_toplevel;
          editor->status_bar_toplevel = NULL;
          editor->status_bar_progress = NULL;
          editor->status_bar_label = NULL;
          editor->status_bar_cursor_label = NULL;
          DO_DESTROY_WIDGET

          w = editor->status_bar_dock;
          editor->status_bar_dock = NULL;
          DO_DESTROY_WIDGET


          w = editor->main_vbox;
          editor->main_vbox = NULL;
          DO_DESTROY_WIDGET

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

#undef DO_DESTROY_WIDGET
      }


      /* Delete file paths */
      g_free(editor->last_open_path);
      editor->last_open_path = NULL;

      g_free(editor->last_save_as_path);
      editor->last_save_as_path = NULL;

      g_free(editor);
}

Generated by  Doxygen 1.6.0   Back to index