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

outputdialog.c

/*
    This file is part of the FElt finite element analysis package.
    Copyright (C) 1993-2000 Jason I. Gobat and Darren C. Atkinson

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/************************************************************************
 * File:    outputdialog.c                                  *
 *                                                    *
 * Description:   This file contains the public and private function and      *
 *          type definitions for the output dialog box.           *
 ************************************************************************/

# include <stdio.h>
# include <X11/Intrinsic.h>
# include <X11/StringDefs.h>
# include <X11/Shell.h>
# include <X11/Xaw/AsciiText.h>
# include <X11/Xaw/Command.h>
# include "Layout.h"
# include "OutputDialog.h"
# include "TabGroup.h"
# include "util.h"

# if NeedVarargsPrototypes
# include <stdarg.h>
# define Va_start(a,b) va_start(a,b)
# else
# include <varargs.h>
# define Va_start(a,b) va_start(a)
# endif

# define MaxButtons 4
# define Waiting ((String) 1)


struct output_dialog {
    Widget     shell;
    Widget     layout;
    Widget     text;
    Widget     button [MaxButtons];
    Widget     dummy;
    Cardinal         num_buttons;
    XtCallbackProc callback;
    XtPointer        client_data;
    String     selected;
};


/* Resources */

static Pixel highlight;

static String layout_string = "\
vertical { \
    4 \
    horizontal { \
      4 \
      text <+inf -100% * +inf -100%> \
      4 \
    } \
    4 \
    horizontal { \
      4 \
      button1 4 button2 4 button3 4 button4 4 \
      4 \
    } \
    4 \
}";

static Arg color_args [ ] = {
    {XtNborderColor, (XtArgVal) &highlight},
};

static Arg layout_args [ ] = {
    {XtNlayout, (XtArgVal) NULL},
};

static Arg text_args [ ] = {
    {XtNeditType, (XtArgVal) XawtextRead},
    {XtNwrap,           (XtArgVal) XawtextWrapWord},
    {XtNscrollVertical, (XtArgVal) XawtextScrollWhenNeeded},
    {XtNborderWidth,    (XtArgVal) 0},
    {XtNwidth,          (XtArgVal) 1024},
};

static Arg command_args [ ] = {
    {XtNlabel, (XtArgVal) ""},
};


/* Translations */

static String command_table =
"<Key>Return:   AutoRepeat(off) set()\n\
 <KeyUp>Return: AutoRepeat(saved) notify() unset()\n\
 <Key>space:    AutoRepeat(off) set()\n\
 <KeyUp>space:  AutoRepeat(saved) notify() unset()\n\
 <Key>Escape:   OutputDialogDelete()";

static XtTranslations command_translations;


/************************************************************************
 * Function:      Delete                                          *
 *                                                    *
 * Description:   An action procedure which is called when the dialog is      *
 *          to be deleted; calls the callback of the dummy widget.      *
 ************************************************************************/

static void Delete (w, event, params, num_params)
    Widget    w;
    XEvent   *event;
    String   *params;
    Cardinal *num_params;
{
    while (XtClass (w) != transientShellWidgetClass)
      w = XtParent (w);

    w = XtNameToWidget (w, "layout.dummy");

    XtCallCallbacks (w, XtNcallback, NULL);
}


/************************************************************************
 * Function:      Notify                                          *
 *                                                    *
 * Description:   Notifies the user through a callback or selection.    *
 ************************************************************************/

static void Notify (w, client_data, call_data)
    Widget    w;
    XtPointer client_data;
    XtPointer call_data;
{
    OutputDialog outputd;
    String   label;


    outputd = (OutputDialog) client_data;

    label = strcmp (XtName (w), "dummy") ? GetLabelString (w) : NULL;

    if (outputd -> callback != NULL)
      outputd -> callback (w, outputd -> client_data, label);
    else
      outputd -> selected = label;
}


/************************************************************************
 * Function:      OutputDialogCreate                              *
 *                                                    *
 * Description:   Creates and returns a new output dialog box.  The     *
 *          dialog can be popped up using OutputDialogSelect()    *
 *          which forces the user to make a selection, or by using      *
 *          OutputialogPopUp() which will call a callback when a  *
 *          button is selected or the dialog is deleted.  The     *
 *          dialog can then be popped down using OutputDialog-    *
 *          Popdown().                                *
 ************************************************************************/

OutputDialog OutputDialogCreate (parent, name, buttons, num_buttons)
    Widget   parent;
    String   name;
    String  *buttons;
    Cardinal num_buttons;
{
    Arg                 args [1];
    Widget        group [MaxButtons + 1];
    char          buffer [32];
    Cardinal            i;
    OutputDialog  outputd;
    XFontStruct          *font;
    static XtAppContext app_context = NULL;
    static XtActionsRec actions [ ] = {{"OutputDialogDelete", Delete}};


    /* Perform one time initialization. */

    if (app_context == NULL) {
      app_context = XtWidgetToApplicationContext (parent);
      XtAppAddActions (app_context, actions, XtNumber (actions));
      AddAutoRepeatAction (app_context);
      command_translations = XtParseTranslationTable (command_table);
      layout_args [0].value = StringToLayout (parent, layout_string);
    }


    /* Create the output dialog and its widgets. */

    outputd = XtNew (struct output_dialog);

    outputd -> shell  = XtCreatePopupShell (name,
                  transientShellWidgetClass, parent,
                  NULL, 0);

    outputd -> layout = XtCreateManagedWidget ("layout",
                  layoutWidgetClass, outputd -> shell,
                  layout_args, XtNumber (layout_args));

    outputd -> text   = XtCreateManagedWidget ("text",
                  asciiTextWidgetClass, outputd -> layout,
                  text_args, XtNumber (text_args));

    outputd -> dummy  = XtCreateWidget ("dummy",
                  commandWidgetClass, outputd -> layout,
                  NULL, 0);


    XtSetArg (args [0], XtNfont, &font);
    XtGetValues (outputd -> text, args, 1);
    XtSetArg (args [0], XtNfont, font);
    XtSetValues (outputd -> dummy, args, 1);

    XtSetArg (args [0], XtNdisplayCaret, False); 
    XtSetValues (outputd -> text, args, 1);

    if (num_buttons > MaxButtons)
      num_buttons = MaxButtons;

    outputd -> num_buttons = num_buttons;

    for (i = 0; i < num_buttons; i ++) {
      sprintf (buffer, "button%u", i + 1);
      XtSetArg (command_args [0], XtNlabel, buttons [i]);
      outputd -> button [i] = XtCreateManagedWidget (XtNewString (buffer),
                        commandWidgetClass, outputd -> layout,
                        command_args, XtNumber (command_args));

      group [i] = outputd -> button [i];
    }


    /* Create a tab group for the output dialog. */

/*
    group [i] = outputd -> text;
    XtGetValues (outputd -> layout, color_args, XtNumber (color_args));
    CreateTabGroup (outputd -> shell, group, num_buttons + 1, highlight, True);
*/
    XtGetValues (outputd -> layout, color_args, XtNumber (color_args));
    CreateTabGroup (outputd -> shell, group, num_buttons, highlight, True);
    XtRealizeWidget (outputd -> shell);


    /* Add the translations to each widget. */

    AddDeleteWindowProtocol (outputd -> shell, "OutputDialogDelete()");

    for (i = 0; i < num_buttons; i ++)
      XtOverrideTranslations (outputd -> button [i], command_translations);


    /* Add the necessary callbacks. */

    XtAddCallback (outputd -> dummy, XtNcallback, Notify, outputd);

    for (i = 0; i < num_buttons; i ++)
      XtAddCallback (outputd -> button [i], XtNcallback, Notify, outputd);

    return outputd;
}


/************************************************************************
 * Function:      OutputDialogSelect                              *
 *                                                    *
 * Description:   Pops up the output dialog with the specified shell    *
 *          title, sets the input focus to the preferred button,  *
 *          and waits until a selection is made or the dialog is  *
 *          deleted; answer will point to the selection or NULL if      *
 *          the dialog was deleted.                         *
 ************************************************************************/

String OutputDialogSelect (outputd, title, preferred)
    OutputDialog outputd;
    String   title;
    String   preferred;
{
    XEvent   event;
    XtAppContext app_context;


    OutputDialogPopup (outputd, title, preferred, NULL, NULL);

    outputd -> selected = Waiting;
    app_context = XtWidgetToApplicationContext (outputd -> shell);

    while (outputd -> selected == Waiting) {
      XtAppNextEvent (app_context, &event);
      XtDispatchEvent (&event);
    }

    OutputDialogPopdown (outputd);

    return outputd -> selected;
}


/************************************************************************
 * Function:      OutputDialogPopup                         *
 *                                                    *
 * Description:   Pops up the output dialog with the specified shell    *
 *          title and sets the input focus to the preferred button.     *
 *          If the callback is not NULL then it will be called upon     *
 *          selection or deletion with the specified client data. *
 ************************************************************************/

void OutputDialogPopup (outputd, title, preferred, callback, client_data)
    OutputDialog   outputd;
    String     title;
    String     preferred;
    XtCallbackProc callback;
    XtPointer        client_data;
{
    Arg      args [2];
    Cardinal i;


    XtSetArg (args [0], XtNtitle,    title);
    XtSetArg (args [1], XtNiconName, title);
    XtSetValues (outputd -> shell, args, 2);

    outputd -> callback = callback;
    outputd -> client_data = client_data;

    for (i = 0; i < outputd -> num_buttons; i ++)
      if (!strcmp (GetLabelString (outputd -> button [i]), preferred))
          SetFocus (outputd -> button [i]);

    XtPopup (outputd -> shell, callback == NULL ? XtGrabExclusive : XtGrabNone);
}


/************************************************************************
 * Function:      OutputDialogPopdown                             *
 *                                                    *
 * Description:   Pops down the specified output dialog.                *
 ************************************************************************/

void OutputDialogPopdown (outputd)
    OutputDialog outputd;
{
    XtPopdown (outputd -> shell);
}


/************************************************************************
 * Function:      OutputDialogView                          *
 *                                                    *
 * Description:   ...                                       *
 ************************************************************************/

void OutputDialogView (outputd, file_name, max_lines, max_columns)
    OutputDialog outputd;
    String   file_name;
    Cardinal       max_lines;
    Cardinal       max_columns;
{
    Arg   args [4];
    Cardinal length;
    Cardinal num_lines;
    Cardinal num_columns;
    XFontStruct *font;
    Dimension width;
    Dimension height;
    FILE *fp;


    if ((fp = fopen (file_name, "r")) == NULL)
      return;
   
    num_lines = 0;
    num_columns = 0;
    
    while (fscanf (fp, " %*[^\n]%n%*[\n]", &length) != EOF) {
      if (length > num_columns)
          num_columns = length;
        
      num_lines ++;
    }
    
    fclose (fp);
    
    if (max_lines && num_lines > max_lines)
      num_lines = max_lines;

    if (max_columns && num_columns > max_columns)
      num_columns = max_columns;

    XtSetArg (args [0], XtNfont, &font);
    XtGetValues (outputd -> text, args, 1);
    
    width = font -> max_bounds.width;
    height = font -> max_bounds.ascent + font -> max_bounds.descent;

    XtSetArg (args [0], XtNtype,   XawAsciiFile);
    XtSetArg (args [1], XtNstring, file_name);
    XtSetArg (args [2], XtNwidth,  width * (num_columns + 1) + 22);
    XtSetArg (args [3], XtNheight, height * (num_lines + 1));
    XtSetValues (outputd -> text, args, 4);
}


/************************************************************************
 * Function:      OutputDialogPrintf                              *
 *                                                    *
 * Description: Uses OutputDialogVprintf() to simulate printf().  *
 ************************************************************************/

# if NeedVarargsPrototypes
void OutputDialogPrintf (OutputDialog outputd, String format, ...)
# else
void OutputDialogPrintf (outputd, format, va_alist)
    OutputDialog outputd;
    String   format;
    va_dcl
# endif
{
    va_list      ap;


    Va_start (ap, format);
    OutputDialogVprintf (outputd, format, ap);
    va_end (ap);
}


/************************************************************************
 * Function:      OutputDialogVprintf                             *
 *                                                    *
 * Description:   Acts like vprintf() only writes to the text widget.  We     *
 *          need to force the size of the text widget so that the *
 *          string can be seen.  Ideally, we would query the      *
 *          preferred geometry of the text widget, but alas this  *
 *          doesn't work as the text widget doesn't have a        *
 *          preferred size since it just assumes that we'll use its     *
 *          built-in scrollbars and thus happily conforms to      *
 *          whatever size it has (yes, I know that resize should  *
 *          work but it doesn't seem to and it doesn't affect the *
 *          preferred size).  So instead we use the dummy widget to     *
 *          determine the proper size.  This works since command  *
 *          (label) widgets return their preferred size and handle      *
 *          newlines correctly.  Ideally, we would want to use a  *
 *          label widget rather than a text widget, but alas, the *
 *          text widget allows cutting and pasting and more       *
 *          importantly allows a file to viewed efficiently.      *
 ************************************************************************/

void OutputDialogVprintf (outputd, format, ap)
    OutputDialog outputd;
    String   format;
    va_list  ap;
{
    Arg                args [4];
    char         buffer [2048];
    XtWidgetGeometry preferred;


    /* Set the label of the dummy widget to the desired string to that
       we can determine its preferred size.  The text widget doesn't
       seem to have a preferred size so we have to do it this way. */

    vsprintf (buffer, format, ap);
    SetLabelString (outputd -> dummy, buffer);
    XtQueryGeometry (outputd -> dummy, NULL, &preferred);

    XtSetArg (args [0], XtNtype,   XawAsciiString);
    XtSetArg (args [1], XtNstring, buffer);
    XtSetArg (args [2], XtNwidth,  preferred.width + 20);
    XtSetArg (args [3], XtNheight, preferred.height + 4);
    XtSetValues (outputd -> text, args, 4);
}


/************************************************************************
 * Function:      OutputDialogShell                         *
 *                                                    *
 * Description:   Returns the shell widget of an output dialog.         *
 ************************************************************************/

Widget OutputDialogShell (outputd)
    OutputDialog outputd;
{
    return outputd -> shell;
}

Generated by  Doxygen 1.6.0   Back to index