home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
x
/
volume13
/
xcal
/
part04
/
xcal_memo.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-05-12
|
15KB
|
600 lines
#ifndef lint
static char *sccsid = "@(#)xcal_memo.c 1.11 (Hillside Systems) 1/16/91";
static char *copyright = "@(#)Copyright 1989,1990 Peter Collinson, Hillside Systems";
#endif /* lint */
/***
* module name:
xcal_memo.c
* function:
Deal with popup memo file
A single popup file is stored in a file called
memo on the Calendar directory
* history:
Written December 1990
Peter Collinson
Hillside Systems
* (C) Copyright: 1989,1990 Hillside Systems/Peter Collinson
For full permissions and copyright notice - see xcal.c
***/
#include <stdio.h>
#include <ctype.h>
#include <X11/Xos.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/Text.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/Paned.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Dialog.h>
#include "xcal.h"
static XtCallbackRec callbacks[] = {
{NULL,NULL},
{NULL,NULL}
};
#define ClearCallbacks() bzero((caddr_t)callbacks, sizeof (callbacks))
/*
* Structure for storing relavant data about the
* memo Edit
*/
typedef struct memoEdit
{
Widget m_button; /* widget of the control button */
Widget m_popup; /* widget of editor popup */
Widget m_quit; /* widget of quit button */
Widget m_save; /* widget of save button */
Boolean m_savesens; /* state of the save button */
Widget m_display; /* widget of display title area */
Widget m_text; /* the text area */
Widget m_today; /* today's data */
Widget m_weekly; /* widget of text image of weekly events */
Cardinal m_size; /* size of the buffer */
char *m_data; /* pointer to malloc'ed data buffer */
} MemoEdit;
static MemoEdit memo;
extern Boolean FoundCalendarDir; /* whether the Calendar directory exists */
static String memoContents;
extern void MemoHelp(); /* look in xcal_help.c */
/*
* Internal routines
*/
void MemoPopup();
static void CleanMemo();
static void MemoCheckExit();
static void MCheckDia();
static Boolean WriteMemoFile();
static int NewlineCount();
static String GetMemoFile();
static void SaveMemoEdits();
static void MemoTextChanged();
static void FinishMemoEditing();
static void YesCheck();
static void NoCheck();
/*
* Callback routine to display the memo file
*/
void
DoMemo(w, closure, call_data)
Widget w;
caddr_t closure;
caddr_t call_data;
{
static Arg args[1];
/*
* Make the button become a finish button
*/
memo.m_button = w;
callbacks[0].callback = FinishMemoEditing;
callbacks[0].closure = (caddr_t)&memo;
XtSetArg(args[0], XtNcallback, callbacks);
XtSetValues(w, args, 1);
MouseShow(w, False);
/*
* Get existing memo contents
* if the user is polling then re-read the file
*/
if (appResources.update && memoContents != NULL)
{ XtFree(memoContents);
memoContents = NULL;
}
if (memoContents == NULL)
memoContents = GetMemoFile();
/*
* Set up the popup widget for editing
*/
MemoPopup();
}
/*
* Get old contents from a memo file if any
*/
static String
GetMemoFile()
{
if (FoundCalendarDir && access(appResources.memoFile, F_OK) == 0)
return ReadCalendarFile(NULL, appResources.memoFile);
return NULL;
}
/*
* Do the biz to popup an edit style window
*/
void
MemoPopup()
{
Widget et, lw;
Widget frame;
Arg args[10];
Cardinal nargs;
String str;
MonthEntry *me;
Dimension charHeight;
char buf[32];
/*
* set up edit buffer
*/
if (memoContents)
memo.m_size = appResources.textbufsz + strlen(memoContents) + 1;
else
memo.m_size = appResources.textbufsz;
memo.m_data = XtMalloc(memo.m_size);
if (memoContents)
strcpy(memo.m_data, memoContents);
else
*memo.m_data = '\0';
memo.m_popup = XtCreatePopupShell("memo", topLevelShellWidgetClass, toplevel, NULL, 0);
/*
* The first title line
*/
et = XtCreateManagedWidget("memoPanel", panedWidgetClass, memo.m_popup, NULL, 0);
nargs = 0;
XtSetArg(args[nargs], XtNshowGrip, False); nargs++;
XtSetArg(args[nargs], XtNskipAdjust, True); nargs++;
XtSetArg(args[nargs], XtNdefaultDistance, 1); nargs++;
frame = XtCreateManagedWidget("title", formWidgetClass, et, args, nargs);
/*
* containing some buttons for controlling the world
*/
/*
* Take label "quit" from resources
*/
callbacks[0].callback = FinishMemoEditing;
callbacks[0].closure = (caddr_t)&memo;
nargs = 0;
XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
XtSetArg(args[nargs], XtNfromHoriz, NULL); nargs++;
XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
XtSetArg(args[nargs], XtNright, XtChainLeft); nargs++;
lw = memo.m_quit = XtCreateManagedWidget("quit", commandWidgetClass, frame, args, nargs);
/*
* If we are dealing with help then do it now
*/
if (appResources.giveHelp)
{ /*
* Take label "help" from resources
*/
callbacks[0].callback = MemoHelp;
callbacks[0].closure = (caddr_t)0;
nargs = 0;
XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
XtSetArg(args[nargs], XtNfromHoriz, lw); nargs++;
XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
XtSetArg(args[nargs], XtNright, XtChainLeft); nargs++;
lw = XtCreateManagedWidget("help", commandWidgetClass, frame, args, nargs);
}
/*
* The remaining bit here is a date label
*/
PlaceStr(buf, &today, appResources.memoYearIs2);
nargs = 0;
XtSetArg(args[nargs], XtNlabel, buf); nargs++;
XtSetArg(args[nargs], XtNborderWidth, 0); nargs++;
XtSetArg(args[nargs], XtNfromHoriz, lw); nargs++;
XtSetArg(args[nargs], XtNfromVert, NULL); nargs++;
XtSetArg(args[nargs], XtNvertDistance, 2); nargs++;
XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
XtSetArg(args[nargs], XtNright, XtChainRight); nargs++;
lw = memo.m_display = XtCreateManagedWidget("date", labelWidgetClass, frame, args, nargs);
/*
* Details for today
*/
me = GetMonthEntry(today.year, today.month);
nargs = 0;
str = me->me_have[today.day];
if (str == NULL)
str = "";
XtSetArg(args[nargs], XtNstring, str); nargs++;
XtSetArg(args[nargs], XtNdisplayCaret, False); nargs++;
XtSetArg(args[nargs], XtNeditType, XawtextRead); nargs++;
memo.m_today = XtCreateManagedWidget("display", asciiTextWidgetClass, et, args, nargs);
{ Dimension height;
XtSetArg(args[0], XtNheight, &height);
XtGetValues(memo.m_today, args, 1);
charHeight = height;
height = height*NewlineCount(str);
XtSetArg(args[0], XtNheight, height);
XtSetValues(memo.m_today, args, 1);
}
/*
* Weekly details - the data for today + an edit button
* The header to this is a form
*/
nargs = 0;
XtSetArg(args[nargs], XtNshowGrip, False); nargs++;
XtSetArg(args[nargs], XtNskipAdjust, True); nargs++;
XtSetArg(args[nargs], XtNdefaultDistance, 1); nargs++;
frame = XtCreateManagedWidget("weeklyMemo", formWidgetClass, et, args, nargs);
/*
* Take label "edit" from resources
*/
callbacks[0].callback = DoWeekly;
callbacks[0].closure = (caddr_t)&memo;
nargs = 0;
XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
XtSetArg(args[nargs], XtNfromHoriz, NULL); nargs++;
XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
XtSetArg(args[nargs], XtNright, XtChainLeft); nargs++;
lw = XtCreateManagedWidget("weeklyEdit", commandWidgetClass, frame, args, nargs);
/*
* Say this is a weekly commitment
*/
nargs = 0;
XtSetArg(args[nargs], XtNshowGrip, True); nargs++;
XtSetArg(args[nargs], XtNborderWidth, 0); nargs++;
XtSetArg(args[nargs], XtNfromHoriz, lw); nargs++;
XtSetArg(args[nargs], XtNfromVert, NULL); nargs++;
XtSetArg(args[nargs], XtNvertDistance, 2); nargs++;
XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
XtSetArg(args[nargs], XtNright, XtChainRight); nargs++;
lw = XtCreateManagedWidget("weeklyTitle", labelWidgetClass, frame, args, nargs);
/*
* Details for today
*/
nargs = 0;
str = GetWeeklyFile(today.wday);
if (str == NULL)
str = "";
XtSetArg(args[nargs], XtNstring, str); nargs++;
XtSetArg(args[nargs], XtNdisplayCaret, False); nargs++;
XtSetArg(args[nargs], XtNeditType, XawtextRead); nargs++;
if (charHeight)
XtSetArg(args[nargs], XtNheight, NewlineCount(str)*charHeight); nargs++;
memo.m_weekly = XtCreateManagedWidget("display", asciiTextWidgetClass, et, args, nargs);
/*
* Another form with some buttons
*/
nargs = 0;
XtSetArg(args[nargs], XtNshowGrip, False); nargs++;
XtSetArg(args[nargs], XtNskipAdjust, True); nargs++;
XtSetArg(args[nargs], XtNdefaultDistance, 1); nargs++;
frame = XtCreateManagedWidget("memoMiddle", formWidgetClass, et, args, nargs);
/*
* Take label "save" from resources
*/
callbacks[0].callback = SaveMemoEdits;
callbacks[0].closure = (caddr_t)&memo;
nargs = 0;
XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
XtSetArg(args[nargs], XtNfromHoriz, NULL); nargs++;
XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
XtSetArg(args[nargs], XtNright, XtChainLeft); nargs++;
XtSetArg(args[nargs], XtNsensitive, False); nargs++;
lw = memo.m_save = XtCreateManagedWidget("save", commandWidgetClass, frame, args, nargs);
memo.m_savesens = False;
/*
* Say this is a memo edit
*/
nargs = 0;
XtSetArg(args[nargs], XtNshowGrip, True); nargs++;
XtSetArg(args[nargs], XtNborderWidth, 0); nargs++;
XtSetArg(args[nargs], XtNfromHoriz, lw); nargs++;
XtSetArg(args[nargs], XtNfromVert, NULL); nargs++;
XtSetArg(args[nargs], XtNvertDistance, 2); nargs++;
XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
XtSetArg(args[nargs], XtNright, XtChainRight); nargs++;
lw = XtCreateManagedWidget("memoTitle", labelWidgetClass, frame, args, nargs);
/*
* The text widget is in the pane below
* The Scroll Attributes are controlled from the application
* defaults file
*/
callbacks[0].callback = MemoTextChanged;
callbacks[0].closure = (caddr_t)&memo;
nargs = 0;
XtSetArg(args[nargs], XtNstring, memo.m_data); nargs++;
XtSetArg(args[nargs], XtNeditType, XawtextEdit); nargs++;
XtSetArg(args[nargs], XtNlength, memo.m_size); nargs++;
XtSetArg(args[nargs], XtNuseStringInPlace, True); nargs++;
XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
memo.m_text = XtCreateManagedWidget("memoText", asciiTextWidgetClass, et, args, nargs);
XtPopup(memo.m_popup, XtGrabNone);
}
/*
* Count newlines in a string
*/
static int
NewlineCount(str)
String str;
{
register int sum = 0;
while (*str)
if (*str++ == '\n')
sum++;
/* Add one line - assume last line does NOT have an nl */
sum++;
/* ignore a final newline */
if (str[-1] == '\n')
sum--;
if (sum <= 0) sum = 1;
return(sum > appResources.maxDisplayLines ? appResources.maxDisplayLines : sum);
}
/*
* Entry point from outside when today's text changed
*/
void
UpdateMemo()
{
Arg args[1];
String str;
Cardinal nargs;
MonthEntry *me;
char buf[32];
/*
* if the button widget is zero then we are displaying nothing
*/
if (memo.m_button == 0)
return;
me = GetMonthEntry(today.year, today.month);
nargs = 0;
str = me->me_have[today.day];
if (str == NULL)
str = "";
XtSetArg(args[0], XtNstring, str); nargs++;
XtSetValues(memo.m_today, args, 1);
(void) sprintf(buf, "%d %s %d", today.day, appResources.mon[today.month], today.year);
XtSetArg(args[0], XtNlabel, buf);
XtSetValues(memo.m_display, args, 1);
str = GetWeeklyFile(today.wday);
if (str == NULL)
str = "";
XtSetArg(args[0], XtNstring, str);
XtSetValues(memo.m_weekly, args, 1);
}
/*
* Poll call from the alarm timeout
*/
void
MemoPoll()
{
int size;
Arg args[10];
int nargs;
if (memo.m_button == 0)
return;
if (memo.m_savesens == True)
return;
if (memoContents)
XtFree(memoContents);
memoContents = GetMemoFile();
if (memoContents)
{ if (strcmp(memoContents, memo.m_data) == 0)
return;
size = strlen(memoContents) + 1;
if (size > memo.m_size)
{ size += appResources.textbufsz;
XtFree(memo.m_data);
memo.m_data = XtMalloc(memo.m_size = size);
}
strcpy(memo.m_data, memoContents);
}
else
*memo.m_data = '\0';
nargs = 0;
XtSetArg(args[nargs], XtNstring, memo.m_data); nargs++;
XtSetArg(args[nargs], XtNlength, memo.m_size); nargs++;
XtSetArg(args[nargs], XtNuseStringInPlace, True); nargs++;
XtSetValues(memo.m_text, args, nargs);
}
/*
* Call backs for various buttons
*/
/* ARGSUSED */
static void
MemoTextChanged(w, closure, call_data)
Widget w;
caddr_t closure;
caddr_t call_data;
{
register MemoEdit *memo = (MemoEdit *)closure;
memo->m_savesens = True;
XtSetSensitive(memo->m_save, True);
}
/*
* Callback routines
*/
/* ARGSUSED */
static void
SaveMemoEdits(w, closure, call_data)
Widget w;
caddr_t closure;
caddr_t call_data;
{
MemoEdit *memo = (MemoEdit *)closure;
if (WriteMemoFile(memo) == False)
return;
if (memoContents)
{ XtFree(memoContents);
memoContents = XtNewString(memo->m_data);
}
memo->m_savesens = False;
XtSetSensitive(memo->m_save, False);
}
/*
* Write the memo file out
*/
static Boolean
WriteMemoFile(memo)
MemoEdit *memo;
{
Cardinal len = strlen(memo->m_data);
String fname;
int fd;
extern String MapStem;
if (len == 0)
{ unlink(appResources.memoFile);
return(True);
}
/*
* First let's see if we have
* to create the toplevel directory
*/
if (!NeedTop())
return (False);
fname = appResources.memoFile;
if ((fd = open(fname, O_WRONLY|O_TRUNC|O_CREAT, 0666)) < 0)
{ XBell(XtDisplay(toplevel), 0);
fprintf(stderr, "xcal: Could not open %s/%s for writing.\n", MapStem, fname);
perror("xcal: open");
fflush(stderr);
return(False);
}
if (write(fd, memo->m_data, len) != len)
{ XBell(XtDisplay(toplevel), 0);
fprintf(stderr, "xcal: Write error %s/%s file.\n", MapStem, fname);
perror("xcal: write");
fflush(stderr);
close(fd);
return(False);
}
close(fd);
return (True);
}
static void
FinishMemoEditing(w, closure, call_data)
Widget w;
caddr_t closure;
caddr_t call_data;
{
if (memo.m_savesens == True)
{ MemoCheckExit();
return;
}
CleanMemo();
}
static void
CleanMemo()
{
static Arg args[1];
callbacks[0].callback = DoMemo;
callbacks[0].closure = NULL;
XtSetArg(args[0], XtNcallback, callbacks);
XtSetValues(memo.m_button, args, 1);
MouseShow(memo.m_button, True);
XtPopdown(memo.m_popup);
XtDestroyWidget(memo.m_popup);
XtFree(memo.m_data);
bzero((char *)&memo, sizeof(MemoEdit));
}
static void
MemoCheckExit()
{
DialogPopup(memo.m_quit, MCheckDia, &memo);
}
static void
MCheckDia(pop, ed)
Widget pop;
MemoEdit *ed;
{
Widget dia;
/* Take "Save file?" from resources */
dia = XtCreateManagedWidget("check", dialogWidgetClass, pop, NULL, 0);
XawDialogAddButton(dia, "yes", YesCheck, ed);
XawDialogAddButton(dia, "no", NoCheck, ed);
}
/* ARGSUSED */
static void
YesCheck(w, closure, call_data)
Widget w;
caddr_t closure;
caddr_t call_data;
{
SaveMemoEdits(w, closure, call_data);
CleanMemo();
XtDestroyWidget(XtParent(XtParent(w)));
}
/* ARGSUSED */
static void
NoCheck(w, closure, call_data)
Widget w;
caddr_t closure;
caddr_t call_data;
{
CleanMemo();
XtDestroyWidget(XtParent(XtParent(w)));
}