/*~PKG**********************************************************************
* Package Name: xm_main.c
* Synopsis: Implements a simple text editor using the Motif toolkit.
* Features Supported: Not much.
* References: Xt Programming and Apps by Doug Young.
* Xm Programming Reference and Guide by OSF.
* Xt Programming Reference and Guide by O'Reilly.
* Usage: Bind this with a couple of other support objs.
* Known Bugs/Deficiencies:
* Modification History: 11/01/90 twl original
*/
/**************************************************************************
* Header files included. */
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <Xm/Xm.h>
#include <Xm/Text.h>
#include <Xm/RowColumn.h>
#include <Xm/PushBG.h>
#include <Xm/FileSB.h>
#include <Xm/SelectioB.h>
#include "xm_callbacks.h"
/**************************************************************************
* Constants and variables local to this package. */
/* These widgets are the popup menu items, externalized here so that
* functions within this package can have access (for the setting/unsetting
* of selectability. */
static Widget CopyMenuItem;
static Widget CutMenuItem;
static Widget PasteMenuItem;
static Widget PasteFileMenuItem;
static Widget WriteFileMenuItem;
static void ExitApp();
/* The actions table for declaring new translations. */
static
XtActionsRec actionTable[] =
{
{ "exit", ExitApp },
};
/**************************************************************************
* Procedure: ExitApp
* Synopsis: Action procedure for exiting application
* Assumptions: None.
* Features Supported:
* Known Bugs/Deficiencies: We're not interested in checking state of the editor before going down.
* Regardless of the circumstances, down we go.
* Modification History: 11/01/90 twl original
** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void
ExitApp( Widget parent, XEvent *event, String *actionArgs, Cardinal argNdx )
{
XtCloseDisplay( XtDisplay( parent ) );
exit( 0 );
}
/**************************************************************************
* Procedure: DisplayTextEditMenu
* Synopsis: Event handler to display the text body popup menu.
* Assumptions: The parent is a Text Widget.
* Features Supported:
* Known Bugs/Deficiencies: External resources should be considered.
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void
DisplayTextEditMenu( textBody, popupMenu, xEvent )
Widget textBody; /* Owner of the event handler */
Widget popupMenu; /* Data passed by the registering procedure */
XEvent *xEvent; /* Passed to all event handlers */
{
Arg argList[25]; /* Resource argument list */
int argNdx; /* Index into resource list */
int menuButton; /* MENU button assigned to popup */
char *selectedText; /* The text selected for the widget invoking
/* We're assuming that the owning widget of this event handler is of
* type XmCText. If not, get out. */
if ( !XmIsText( textBody ) )
{
printf( "DisplayTextEditMenu: Not Text\n" );
exit( 1 );
}
/* We're also assuming that the the data passed by the event handler
* is a popup menu widget. If not, get out. */
if ( !XmIsRowColumn( popupMenu ) )
{
printf( "DisplayTextEditMenu: Not RowColumn\n" );
exit( 1 );
}
/* Check to see if the button that caused this event is the menu
* button. If not, get out. */
argNdx = 0;
XtSetArg( argList[argNdx], XmNwhichButton, &menuButton ); argNdx++;
XtGetValues( popupMenu, argList, argNdx );
if ( xEvent->xbutton.button != menuButton )
{
return;
}
/* We need to set the selectability of the menu items here. For most menu
* items, that involves checking to see if any text has been selected. */
selectedText = XmTextGetSelection( textBody );
/* The Copy menu item. */
if ( selectedText != NULL )
{
XtSetSensitive( CopyMenuItem, TRUE );
}
else
{
XtSetSensitive( CopyMenuItem, FALSE );
}
/* The Cut menu item. */
if ( selectedText != NULL )
{
XtSetSensitive( CutMenuItem, TRUE );
}
else
{
XtSetSensitive( CutMenuItem, FALSE );
}
/* The Paste menu item. See if there's something in the clipboard,
* and set sensitivity accordingly. */
if ( selectedText == NULL )
{
if ( ClipboardIsEmpty( textBody ) )
{
XtSetSensitive( PasteMenuItem, FALSE );
}
else
{
XtSetSensitive( PasteMenuItem, TRUE );
}
}
else
{
XtSetSensitive( PasteMenuItem, FALSE );
}
/* The PasteFile menu item. Let's say that we can only paste from a file
* if no text has been selected. */
if ( selectedText == NULL )
{
XtSetSensitive( PasteFileMenuItem, TRUE );
}
else
{
XtSetSensitive( PasteFileMenuItem, FALSE );
}
/* The WriteFile menu item. */
if ( selectedText != NULL )
{
XtSetSensitive( WriteFileMenuItem, TRUE );
}
else
{
XtSetSensitive( WriteFileMenuItem, FALSE );
}
XmMenuPosition( popupMenu, xEvent );
XtManageChild( popupMenu );
}
/*~PROC********************************************************************
* Procedure: CreateTextEditPopup
* Synopsis: Creates the Popup menu displayed over the text edit area.
* Callbacks are also defined here.
* Assumptions:
* Features Supported:
* Known Bugs/Deficiencies: External resources should perhaps be considered.
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static Widget
CreateTextEditPopup( Widget parent )
{
Widget textPopup; /* Created popup returned */
Arg argList[25]; /* Resource argument list */
int argNdx; /* Index into argument list */
Widget fileDialog; /* File selection dialog box */
Widget promptDialog; /* Text input prompt */
/* We assume a text edit widget as parent. If not, get out. */
if ( !XmIsText( parent ) )
{
printf( "CreateTextEditPopup: Not Text\n" );
exit( 1 );
}
/* Create the popup menu. We'll tell Xt to manage it at the time that
* it needs to be displayed. */
textPopup = XmCreatePopupMenu( parent, "textPopup", NULL, 0 );
/* Add the menu items (buttons). */
argNdx = 0;
XtSetArg( argList[argNdx], XmNlabelString, XmStringCreateLtoR( "Copy", XmSTRING_DEFAULT_CHARSET ) ); argNdx++;
CopyMenuItem = XmCreatePushButtonGadget( textPopup, "copyMenuItem", argList, argNdx );
XtManageChild( CopyMenuItem );
argNdx = 0;
XtSetArg( argList[argNdx], XmNlabelString, XmStringCreateLtoR( "Cut", XmSTRING_DEFAULT_CHARSET ) ); argNdx++;
CutMenuItem = XmCreatePushButtonGadget( textPopup, "cutMenuItem", argList, argNdx );
XtManageChild( CutMenuItem );
argNdx = 0;
XtSetArg( argList[argNdx], XmNlabelString, XmStringCreateLtoR( "Paste", XmSTRING_DEFAULT_CHARSET ) ); argNdx++;
PasteMenuItem = XmCreatePushButtonGadget( textPopup, "pasteMenuItem", argList, argNdx );
XtManageChild( PasteMenuItem );
argNdx = 0;
XtSetArg( argList[argNdx], XmNlabelString, XmStringCreateLtoR( "Paste From File...", XmSTRING_DEFAULT_CHARSET ) ); argNdx++;
PasteFileMenuItem = XmCreatePushButtonGadget( textPopup, "pasteFileMenuItem", argList, argNdx );
XtManageChild( PasteFileMenuItem );
argNdx = 0;
XtSetArg( argList[argNdx], XmNlabelString, XmStringCreateLtoR( "Write To File...", XmSTRING_DEFAULT_CHARSET ) ); argNdx++;
WriteFileMenuItem = XmCreatePushButtonGadget( textPopup, "writeFileMenuItem", argList, argNdx );
XtManageChild( WriteFileMenuItem );
/* Add the File Selection dialog, to be invoked by PasteFileMenu button. */
argNdx = 0;
XtSetArg( argList[argNdx], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL ); argNdx++;
XtSetArg( argList[argNdx], XmNdialogTitle, XmStringCreateLtoR( "Paste From File", XmSTRING_DEFAULT_CHARSET ) ); argNdx++;
XtSetArg( argList[argNdx], XmNselectionLabelString, XmStringCreateLtoR( "Directory", XmSTRING_DEFAULT_CHARSET ) ); argNdx++ ;
XtSetArg( argList[argNdx], XmNautoUnmanage, True ); argNdx++;
fileDialog = XmCreateFileSelectionDialog( parent, "fileDialog", argList, argNdx );
/* Add a selection dialog, to be invoked by the WriteFileMenu button. */
argNdx = 0;
XtSetArg( argList[argNdx], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL ); argNdx++;
XtSetArg( argList[argNdx], XmNdialogTitle, XmStringCreateLtoR( "Write To File", XmSTRING_DEFAULT_CHARSET ) ); argNdx++;
XtSetArg( argList[argNdx], XmNselectionLabelString, XmStringCreateLtoR( "File", XmSTRING_DEFAULT_CHARSET ) ); argNdx++ ;
XtSetArg( argList[argNdx], XmNtextColumns, 32 ); argNdx++;
promptDialog = XmCreatePromptDialog( parent, "promptDialog", argList, argNdx );
/* Add callbacks for the menu buttons. */
XtAddCallback( CopyMenuItem, XmNactivateCallback, CopyCB, parent );
XtAddCallback( CutMenuItem, XmNactivateCallback, CutCB, parent );
XtAddCallback( PasteMenuItem, XmNactivateCallback, PasteCB, parent );
XtAddCallback( PasteFileMenuItem, XmNactivateCallback, PasteFileCB, fileDialog );
XtAddCallback( WriteFileMenuItem, XmNactivateCallback, WriteFileCB, promptDialog );
/* Add callbacks for the dialog box buttons. */
XtAddCallback( fileDialog, XmNokCallback, FileDialogOKCB, parent );
XtAddCallback( fileDialog, XmNcancelCallback, UnMapDialogCB, fileDialog );
XtAddCallback( fileDialog, XmNhelpCallback, UnMapDialogCB, fileDialog );
XtAddCallback( promptDialog, XmNokCallback, PromptDialogOKCB, parent );
XtAddCallback( promptDialog, XmNcancelCallback, UnMapDialogCB, promptDialog );
XtAddCallback( promptDialog, XmNhelpCallback, UnMapDialogCB, promptDialog );
return( textPopup );
}
/*~PROC********************************************************************
* Procedure: main
* Synopsis: Initializes the Intrinsics, creates all of the higher-level widgets
* necessary to make the application happen, and enters the main loop.
* Assumptions:
* Usage: Command-line arguments are ignored (for now).
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
main( int argc, char *argv[] )
{
Widget topShell; /* Top level shell created by the Intrinsics */
Widget textEdit; /* Main edit Text Widget */
Widget textMenu; /* Popup menu associated with the text editor */
Arg argList[25]; /* Resource argument list */
int argNdx; /* Index into resource list */
/* Initialize the Intrinsics. */
topShell = XtInitialize( argv[0], "Editor", NULL, 0, &argc, argv );
/* Create the scrolled Text Widget */
argNdx = 0;
XtSetArg(argList[argNdx], XmNscrollVertical, True ); argNdx++;
XtSetArg(argList[argNdx], XmNscrollHorizontal, True ); argNdx++;
XtSetArg(argList[argNdx], XmNeditMode, XmMULTI_LINE_EDIT ); argNdx++;
textEdit = XmCreateScrolledText( topShell, "textEdit", argList, argNdx );
XtManageChild( textEdit );
/* Create the context-sensitive popup menu for this Widget */
textMenu = CreateTextEditPopup( textEdit );
/* Add the event handler to the Text Widget, invoking the popup menu. */
XtAddEventHandler( textEdit, ButtonPressMask, FALSE, DisplayTextEditMenu, textMenu );
/* Register new actions to be associated with our app. */
XtAddActions( actionTable, XtNumber( actionTable ) );
/* Map the editor, and enter the event dispatch loop. */
XtRealizeWidget( topShell );
XtMainLoop();
}