home *** CD-ROM | disk | FTP | other *** search
- /* SOURCE FILE *****************************************************
- * WTCLFILE.C - WTAPI Sample Client Application file I/O functions
- *******************************************************************
- * Copyright (C) 1993 WordPerfect Corp., All Rights Reserved
- *******************************************************************/
- #include "wtclient.h"
-
- #include <Xm/Xm.h>
- #include <Xm/FileSB.h>
- #include <Xm/MessageB.h>
- #include <Xm/Text.h>
- #include <stdio.h>
- #include <string.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- /*----------------------------------------------------------
- External Variables
- ------------------------------------------------------------*/
- extern Widget Client;
- extern XmFontList FontList;
-
- /*----------------------------------------------------------
- External Functions
- ------------------------------------------------------------*/
- void SetNewBuffer(char *, char *);
- char *GetBuffer();
- XmString StringCreate(unsigned char *);
- void NormalCursor(Widget);
- void WaitCursor(Widget);
-
- /*----------------------------------------------------------
- Internal Variables
- ------------------------------------------------------------*/
- BOOL Dirty = FALSE; /* TRUE if the file is changed */
- char FileName[128] = "\0"; /* current file name */
- static Widget msgDialog, fileSelect;
- static BOOL MsgBoxRet = FALSE;
- static BOOL FileSelRet = FALSE;
- static char PathName[128] = "\0"; /* path to use for file selection */
- static char OpenDlgTitle[] = "Open File"; /* title of File open dialog */
- static char SaveDlgTitle[] = "Save File"; /* title of File saveas dialog */
- static char Untitled[] = "(untitled)"; /* default filename */
- static char *EditBuffer; /* editing buffer */
-
- /*----------------------------------------------------------
- Internal Functions
- ------------------------------------------------------------*/
- BOOL MsgBox(MSGBOX, Widget parent, char *, char *);
- static BOOL QuerySaveFile(Widget);
- static BOOL GetFileName(Widget, char *);
- static BOOL SaveFile(Widget);
-
- /*COMMENT***************************************************
- ;FileMenuProc
- Title: Handle File menu actions
- In: parent - widget to be used as parent for subdialogs
- file - File action to be performed
- Out: none
- Xin: Untitled, OpenDlgTitle, SaveDlgTitle
- Xout: Dirty, FileName, EditBuffer
- Return: NULL
- Notes:
- ***********************************************************/
- void FileMenuProc(Widget parent, CL_FILE file)
- {
- char str[256];
- struct stat statbuf;
- int fd;
-
- switch (file) {
- case CL_FILE_NEW: /* New */
- if (!QuerySaveFile(parent)) { /* get rid of the old one? */
- return; /* no */
- }
- Dirty = FALSE; /* edit buffer is clean */
- FileName[0] = 0; /* no file name */
- str[0] = 0;
- SetNewBuffer(str, Untitled); /* clear out buffer */
- break;
- case CL_FILE_OPEN: /* Open */
- /*
- * Ask to save current buffer if changed.
- */
- if (!QuerySaveFile(parent)) {
- return;
- }
- /*
- * Get the name of the file to open. Use stat() to make sure
- * it is accessible and to determine its size.
- */
- if (!GetFileName(parent, OpenDlgTitle)) {
- return;
- }
- if (stat(FileName, &statbuf) < 0) {
- sprintf(str, "Unable to stat: %s.", FileName);
- MsgBox(MB_OK, parent, "WTClient", str);
- return;
- }
- /*
- * Allocate space to read in the file.
- */
- EditBuffer = (char *)calloc(1, statbuf.st_size + 1);
- if (!EditBuffer) {
- MsgBox(MB_OK, parent, "WTClient", "Not enough memory.");
- return;
- }
- /*
- * Open file and read contents into EditBuffer.
- */
- fd = open(FileName, O_RDONLY, 0);
- if (fd < 0) {
- sprintf(str, "Unable to open: %s.", FileName);
- MsgBox(MB_OK, parent, "WTClient", str);
- return;
- }
- if (read(fd, EditBuffer, statbuf.st_size) != statbuf.st_size) {
- sprintf(str, "Error reading: %s.", FileName);
- MsgBox(MB_OK, parent, "WTClient", str);
- }
- close(fd);
- /*
- * Set up a new buffer and window title.
- */
- SetNewBuffer(EditBuffer, FileName);
- free(EditBuffer);
- break;
- case CL_FILE_SAVE: /* Save */
- if (FileName[0]){ /* is there a filename? */
- if (Dirty) { /* does it need saving? */
- SaveFile(parent); /* then save it */
- }
- break;
- }
- /* else fall through, use SaveAs to get filename */
- case CL_FILE_SAVE_AS: /* Save As */
- if (!GetFileName(parent, SaveDlgTitle)) {
- return; /* User canceled */
- }
- /* If successful, update the window title, save the file */
- sprintf(str, "WTClient - %s", FileName);
- XtVaSetValues(Client, XtNtitle, str, NULL);
- SaveFile(parent);
- break;
- case CL_FILE_PRINT: /* Print */
- MsgBox(MB_OK, parent, "WTClient - Print","Command not implemented");
- break;
- case CL_FILE_EXIT: /* Exit */
- QuerySaveFile(parent);
- while ( !XtIsTopLevelShell(parent) &&
- !XtIsApplicationShell(parent) &&
- XtParent(parent) )
- {
- parent = XtParent(parent);
- }
- XtDestroyWidget(parent);
- break;
- default: /* unrecognized action */
- break; /* do nothing */
- }
- } /* FileMenuProc */
-
- /*COMMENT***************************************************
- ;SaveFile
- Title: Save current file
- In: parent - widget to be used as parent for subdialogs
- Out: none
- Xin: none
- Xout: none
- Return: none
- Notes: This saves the current contents of the Edit buffer, and changes
- Dirty to indicate that the buffer has not been changed since the
- last save.
- ***********************************************************/
- static BOOL SaveFile(Widget parent)
- {
- BOOL success;
- char str[256];
- int fd;
- int len;
-
- WaitCursor(parent);
- /*
- * Open file for write. Create it if it doesn't exist and truncate it
- * if it does.
- */
- fd = open(FileName, O_WRONLY | O_CREAT | O_TRUNC, 0666);
- if (fd < 0) {
- sprintf(str, "Cannot write: %s", FileName);
- MsgBox(MB_OK, parent, "WTClient", str);
- NormalCursor(parent);
- return FALSE;
- }
- /*
- * Write text to file.
- */
- EditBuffer = GetBuffer();
- len = strlen(EditBuffer);
- if (write(fd, EditBuffer, len) != len) {
- sprintf(str, "Error writing: %s", FileName);
- NormalCursor(parent);
- MsgBox(MB_OK, parent, "WTClient", str);
- success = FALSE;
- } else {
- success = TRUE; /* Indicates the file was saved */
- Dirty = FALSE; /* Indicates changes have been saved */
- }
- XtFree(EditBuffer); /* GetBuffer() uses XmTextGetString(), we must free */
- close(fd);
- NormalCursor(parent);
- return (success);
- } /* SaveFile */
-
- /*COMMENT***************************************************
- ;QuerySaveFile
- Title: Called when some action might lose current contents of the edit buffer.
- In: parent - widget to be used as parent for subdialogs
- Out: none
- Xin: none
- Xout: none
- Return: TRUE - file saved (if desired), FALSE - file not saved
- Notes:
- ***********************************************************/
- static BOOL QuerySaveFile(Widget parent)
- {
- BOOL response;
- char str[256];
-
- if (Dirty) {
- if (!FileName[0]) {
- sprintf(str, "Save current changes: %s", Untitled);
- } else {
- sprintf(str, "Save current changes: %s", FileName);
- }
- response = MsgBox(MB_YESNO, parent, "WTClient", str);
- if (response == TRUE) {
- /* Make sure there is a filename to save to */
- while (!FileName[0]) {
- if (!GetFileName(parent, SaveDlgTitle)) {
- return FALSE; /* User canceled */
- }
- }
- SaveFile(parent);
- } else {
- return TRUE; /* user does not want buffer saved */
- }
- }
- return TRUE;
- } /* QuerySaveFile */
-
- /*COMMENT***************************************************
- ;MsgBoxCB
- Title: MsgBox dialog callback
- In: cladata - 1 = Yes, 0 = No
- Out: none
- Return: none
- Xin: none
- Xout: none
- Notes:
- ***********************************************************/
- static void MsgBoxCB(Widget w, XtPointer cldata, XtPointer cbdata)
- {
- MsgBoxRet = ((int)cldata == 1);
- if (msgDialog) {
- XtDestroyWidget(msgDialog);
- }
- msgDialog = 0;
- } /* MsgBoxCB */
-
- /*COMMENT***************************************************
- ;MsgBox
- Title: Bring up an OK or Yes/No message dialog.
- In: type - type of message box
- parent - parent widget
- title - dialog title
- message - message/question for dialog
- Out: none
- Xin: none
- Xout: none
- Return: TRUE - Yes, FALSE - No
- Notes:
- ***********************************************************/
- BOOL MsgBox(MSGBOX type, Widget parent, char *title, char *message)
- {
- Arg args[14]; /* Args for XtSetArg() */
- Cardinal argcnt = 0; /* number of Args set */
- XmString titleStr, messageStr, yesStr, noStr;
- XEvent event;
-
- MsgBoxRet = False;
- titleStr = StringCreate(title);
- messageStr = StringCreate(message);
- if (type == MB_YESNO) {
- yesStr = StringCreate("Yes");
- noStr = StringCreate("No");
- } else {
- yesStr = StringCreate("OK");
- }
- argcnt = 0;
- XtSetArg(args[argcnt], XmNdialogTitle, titleStr); argcnt++;
- XtSetArg(args[argcnt], XmNmessageString, messageStr); argcnt++;
- XtSetArg(args[argcnt], XmNokLabelString, yesStr); argcnt++;
- XtSetArg(args[argcnt], XmNtextFontList, FontList); argcnt++;
- XtSetArg(args[argcnt], XmNbuttonFontList, FontList); argcnt++;
- XtSetArg(args[argcnt], XmNlabelFontList, FontList); argcnt++;
- XtSetArg(args[argcnt], XmNdialogStyle,
- XmDIALOG_PRIMARY_APPLICATION_MODAL); argcnt++;
- XtSetArg(args[argcnt], XmNmessageAlignment, XmALIGNMENT_CENTER); argcnt++;
- if (type == MB_YESNO) {
- XtSetArg(args[argcnt], XmNcancelLabelString, noStr); argcnt++;
- msgDialog = XmCreateQuestionDialog(parent, "quesDialog", args, argcnt);
- } else {
- msgDialog = XmCreateInformationDialog(parent, "infoDialog", args, argcnt);
- }
- XmStringFree(titleStr);
- XmStringFree(messageStr);
- XmStringFree(yesStr);
- if (type == MB_YESNO) {
- XmStringFree(noStr);
- XtAddCallback(msgDialog, XmNcancelCallback, MsgBoxCB, 0);
- } else {
- XtUnmanageChild(XmMessageBoxGetChild(msgDialog,XmDIALOG_CANCEL_BUTTON));
- }
- XtAddCallback(msgDialog, XmNokCallback, MsgBoxCB, (XtPointer) 1);
- XtUnmanageChild(XmMessageBoxGetChild(msgDialog, XmDIALOG_HELP_BUTTON));
- XtManageChild(msgDialog);
- /*
- * Process events until dialog is closed.
- */
- for (;;) {
- XtAppNextEvent(XtWidgetToApplicationContext(parent), &event);
- XtDispatchEvent(&event);
- if (!msgDialog) {
- break;
- }
- }
- return(MsgBoxRet);
- } /* MsgBox */
-
- /*COMMENT***************************************************
- ;FileSelectCB
- Title: Initialize the newly selected file.
- In: w - file selection box
- cldata - 1 = OK, 0 = Cancel
- Out: none
- Xin: none
- Xout: FileName, PathName, FileSelRet
- Return: none
- ***********************************************************/
- static void FileSelectCB(Widget w, XtPointer cldata, XtPointer cbdata)
- {
- Widget text; /* text child of FileSelectionBox */
- String path; /* pointer to path from text widget */
- char *p;
-
- FileSelRet = ((int)cldata == 1);
- if (FileSelRet) { /* OK */
- text = XmFileSelectionBoxGetChild(w, XmDIALOG_TEXT);
- path = XmTextGetString(text); /* Get user's specified path */
- if (!path || !*path || strcmp(path, "/") == 0) {
- return; /* leave dialog up to get valid file name */
- }
- strcpy(FileName, path);
- if (p = strrchr(path, '/')) { /* find last slash */
- *p = 0; /* truncate at last slash */
- }
- strcpy(PathName, path);
- XtFree(path);
- }
- XtDestroyWidget(fileSelect); /* Destroy file select dialog */
- fileSelect = 0;
- } /* FileSelectCB */
-
- /*COMMENT***************************************************
- ;GetFileName
- Title: Use file selection dialog to get path to desired file
- In: parent - widget to be used as parent for file selection dialog
- title - title for file selection dialog
- Out: none
- Xin: PathName
- Xout: FileSelRet
- Return: none
- Notes:
- ***********************************************************/
- static BOOL GetFileName(Widget parent, char *title)
- {
- Arg args[8]; /* Args for XtSetArg() */
- Cardinal argcnt = 0; /* number of Args set */
- XmString dirStr; /* for XmNdirectory */
- XmString dirmaskStr; /* for XmNdirMask */
- XmString titleStr; /* for XmNdialogTitle */
- XEvent event;
-
- FileSelRet = FALSE;
- argcnt = 0;
- /*
- * If the PathName is not empty use it for XmNdirectory, otherwise
- * default to the current directory.
- */
- if (*PathName) {
- dirStr = StringCreate(PathName);
- XtSetArg(args[argcnt], XmNdirectory, dirStr); argcnt++;
- } else {
- dirStr = 0;
- }
- dirmaskStr = StringCreate("*");
- titleStr = StringCreate(title);
- XtSetArg(args[argcnt], XmNdirMask, dirmaskStr); argcnt++;
- XtSetArg(args[argcnt], XmNdialogTitle, titleStr); argcnt++;
- XtSetArg(args[argcnt], XmNtextFontList, FontList); argcnt++;
- XtSetArg(args[argcnt], XmNbuttonFontList, FontList); argcnt++;
- XtSetArg(args[argcnt], XmNlabelFontList, FontList); argcnt++;
- fileSelect = XmCreateFileSelectionDialog(parent, "filesel", args, argcnt);
- if (dirStr) {
- XmStringFree(dirStr);
- }
- XmStringFree(dirmaskStr);
- XmStringFree(titleStr);
- XtAddCallback(fileSelect, XmNokCallback, FileSelectCB, (XtPointer)1);
- XtAddCallback(fileSelect, XmNcancelCallback, FileSelectCB, 0);
- XtManageChild(fileSelect);
- /*
- * Process events until dialog is closed.
- */
- for (;;) {
- XtAppNextEvent(XtWidgetToApplicationContext(parent), &event);
- XtDispatchEvent(&event);
- if (!fileSelect) {
- break;
- }
- }
- return(FileSelRet);
- } /* GetFileName */
-