1
0
Files
irix-657m-src/irix/cmd/netman/ui/lib/dialog.c++
2022-09-29 17:59:04 +03:00

524 lines
11 KiB
C++

/*
* Copyright 1992 Silicon Graphics, Inc. All rights reserved.
*
* DialogBox
*
* $Revision: 1.13 $
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <string.h>
#include <bstring.h>
#include <tu/tuCallBack.h>
#include <tuDialogBox.h>
#include <tu/tuTopLevel.h>
#include <tuBitmapTile.h>
#include <tuBitmaps.h>
#include <tu/tuRowColumn.h>
#include <tu/tuLabelButton.h>
#include <tu/tuDefaultButton.h>
#include <tu/tuPalette.h>
#include <tu/tuWindow.h>
#include <tu/tuAccelerator.h>
#include "dialog.h"
static const unsigned int maxMessageLength = 4096;
static const unsigned int maxTextLines = 16;
class DialogBoxCallBack : public tuCallBack
{
public:
DialogBoxCallBack(void (DialogBox::*method)(tuGadget *));
~DialogBoxCallBack();
virtual void doit(tuGadget*);
protected:
void (DialogBox::*method)(tuGadget *);
};
DialogBoxCallBack::DialogBoxCallBack(void (DialogBox::*m)(tuGadget *))
{
method = m;
}
DialogBoxCallBack::~DialogBoxCallBack()
{
}
void
DialogBoxCallBack::doit(tuGadget *g)
{
DialogBox *f = (DialogBox *) g->getTopLevel();
(f->*method)(g);
}
DialogBox::DialogBox(const char* instanceName, tuColorMap* cmap,
tuResourceDB* db, char* progName,
char* progClass, Window transientFor)
: tuDialogBox(instanceName, cmap, db, progName, progClass, transientFor)
{
initialize();
}
DialogBox::DialogBox(const char* instanceName,
tuTopLevel* othertoplevel,
tuBool transientForOtherTopLevel)
: tuDialogBox(instanceName, othertoplevel, transientForOtherTopLevel)
{
initialize();
}
DialogBox::~DialogBox(void)
{
if (text != 0)
delete text;
}
void
DialogBox::initialize(void)
{
dialogType = tuEmpty;
hitCode = tuNone;
mapping = False;
lineLength = 60;
wrapLength = 50;
text = 0;
textLength = 0;
breakChars = " \t\n/";
tuAccelerator *a = new tuAccelerator("Return");
a->setCallBack(new DialogBoxCallBack(&DialogBox::accelerator));
addAccelerator(a);
catchDeleteWindow(new DialogBoxCallBack(&DialogBox::callBack));
}
void
DialogBox::map(tuBool propagate)
{
tuButton *b;
tuBitmapTile *t = getBitmapTile();
if (mapping == True) {
tuDialogBox::map();
return;
}
mapping = True;
setText(text);
switch (dialogType) {
case tuEmpty:
setName("Dialog");
tuDialogBox::map(propagate);
break;
case tuInformation:
setName("Information");
t->setBitmap(tuInformationBitmap, tuBitmapWidth, tuBitmapHeight);
t->setBackground(tuPalette::getLightGrayBlue(getScreen()));
b = new tuDefaultButton(getButtonContainer(), "", "Continue");
b->setCallBack(new DialogBoxCallBack(&DialogBox::callBack));
b->map();
defaultGadget = b;
getButtonContainer()->updateLayout();
tuDialogBox::mapWithGadgetUnderMouse(b, propagate);
break;
case tuProgress:
setName("Progress");
t->setBitmap(tuProgressBitmap, tuBitmapWidth, tuBitmapHeight);
t->setBackground(tuPalette::getLightGrayCyan(getScreen()));
defaultGadget = 0;
getButtonContainer()->updateLayout();
tuDialogBox::mapWithGadgetUnderMouse(getButtonContainer(),
propagate);
break;
case tuQuestion:
setName("Question");
t->setBitmap(tuQuestionBitmap, tuBitmapWidth, tuBitmapHeight);
t->setBackground(tuPalette::getLightGrayGreen(getScreen()));
b = new tuDefaultButton(getButtonContainer(), "", "Yes");
b->setCallBack(new DialogBoxCallBack(&DialogBox::callBack));
b->map();
defaultGadget = b;
b = new tuLabelButton(getButtonContainer(), "", "No");
b->setCallBack(new DialogBoxCallBack(&DialogBox::callBack));
b->map();
b = new tuLabelButton(getButtonContainer(), "", "Cancel");
b->setCallBack(new DialogBoxCallBack(&DialogBox::callBack));
b->map();
getButtonContainer()->updateLayout();
tuDialogBox::mapWithGadgetUnderMouse(b, propagate);
//getWindow()->grabPointer();
break;
case tuWarning:
setName("Warning");
t->setBitmap(tuWarningBitmap, tuBitmapWidth, tuBitmapHeight);
t->setBackground(tuPalette::getLightGrayMagenta(getScreen()));
b = new tuDefaultButton(getButtonContainer(), "", "Continue");
b->setCallBack(new DialogBoxCallBack(&DialogBox::callBack));
b->map();
defaultGadget = b;
getButtonContainer()->updateLayout();
tuDialogBox::mapWithGadgetUnderMouse(b, propagate);
//getWindow()->grabPointer();
break;
case tuAction:
setName("Error");
t->setBitmap(tuActionBitmap, tuBitmapWidth, tuBitmapHeight);
t->setBackground(tuPalette::getLightGrayRed(getScreen()));
b = new tuDefaultButton(getButtonContainer(), "", "Continue");
b->setCallBack(new DialogBoxCallBack(&DialogBox::callBack));
b->map();
defaultGadget = b;
getButtonContainer()->updateLayout();
tuDialogBox::mapWithGadgetUnderMouse(b, propagate);
//getWindow()->grabPointer();
break;
}
mapping = False;
}
void
DialogBox::unmap(tuBool propagate)
{
tuDialogBox::unmap(propagate);
tuRowColumn *rc = getButtonContainer();
for (int i = rc->getNumExternalChildren() - 1; i > 0; i--)
rc->getExternalChild(i)->markDelete();
rc->grow(1, 1);
}
void
DialogBox::setName(const char *title)
{
char buf[1024];
if (instanceName == 0)
strcpy(buf, title);
else
sprintf(buf, "%s %s", instanceName, title);
tuDialogBox::setName(buf);
}
void
DialogBox::setText(const char *buf)
{
char *text[maxTextLines];
unsigned int line = 0;
for (char *p = (char *) buf; *p != '\0' && line < maxTextLines - 1; ) {
unsigned int len = strlen(p);
if (len < lineLength) {
text[line++] = p;
break;
}
// First look for a new line
char *brk;
char *b = strchr(p, '\n');
if (b != 0 && b - p < lineLength)
brk = b;
else {
// Find a line break character
brk = 0;
for (b = p + wrapLength; b < p + lineLength; brk = b++) {
b = strpbrk(b, breakChars);
if (b == 0)
break;
}
// If none found, extend the string longer
if (brk == 0) {
text[line++] = p;
break;
}
}
// Copy the text line
if (*brk == '/')
len = brk - p + 1;
else
len = brk - p;
text[line] = new char[len + 1];
bcopy(p, text[line], len);
text[line++][len] = '\0';
// Skip intervening space
for ( ; ; brk = b) {
b = strpbrk(brk + 1, breakChars);
if (b == 0 || *b == '\n' || b != brk + 1)
break;
}
p = brk + 1;
}
text[line] = 0;
tuDialogBox::setText(text);
}
void
DialogBox::setText(const char *list[])
{
tuDialogBox::setText(list);
}
enum tuDialogType
DialogBox::getDialogType(void)
{
return dialogType;
}
void
DialogBox::setDialogType(enum tuDialogType t)
{
dialogType = t;
}
void
DialogBox::setCallBack(tuCallBack *c)
{
if (callback != 0)
callback->markDelete();
callback = c;
}
void
DialogBox::setMultiMessage(tuBool m)
{
multiMessage = m;
if (multiMessage && textLength != 0)
text[0] = '\0';
}
void
DialogBox::accelerator(tuGadget *)
{
if (defaultGadget != 0)
callBack(defaultGadget);
}
void
DialogBox::callBack(tuGadget *g)
{
const char *s = g->getText();
if (s == 0)
s = "Cancel";
else if (strcmp(s, "Help") == 0) {
if (callback != 0)
callback->doit(this);
return;
}
switch (dialogType) {
case tuEmpty:
hitCode = tuNone;
break;
case tuInformation:
case tuProgress:
hitCode = tuOK;
break;
case tuWarning:
case tuAction:
hitCode = tuOK;
getWindow()->ungrabPointer();
break;
case tuQuestion:
if (strcmp(s, "Yes") == 0)
hitCode = tuYes;
else if (strcmp(s, "No") == 0)
hitCode = tuNo;
else if (strcmp(s, "Cancel") == 0)
hitCode = tuCancel;
getWindow()->ungrabPointer();
break;
}
unmap();
if (callback != 0)
callback->doit(this);
}
enum tuDialogHitCode
DialogBox::getHitCode(void)
{
return hitCode;
}
void
DialogBox::information(const char *format, ...)
{
char buf[4096];
char *p = buf;
// Print variable arguments
va_list ap;
va_start(ap, format);
p += vsprintf(buf, format, ap);
va_end(ap);
*p++ = '.';
*p = '\0';
makeMessage(buf);
dialogType = tuInformation;
}
void
DialogBox::progress(const char *format, ...)
{
char buf[4096];
char *p = buf;
// Print variable arguments
va_list ap;
va_start(ap, format);
p += vsprintf(buf, format, ap);
va_end(ap);
*p++ = '.';
*p = '\0';
makeMessage(buf);
dialogType = tuProgress;
}
void
DialogBox::question(const char *format, ...)
{
char buf[4096];
char *p = buf;
// Print variable arguments
va_list ap;
va_start(ap, format);
p += vsprintf(buf, format, ap);
va_end(ap);
*p++ = '?';
*p = '\0';
makeMessage(buf);
dialogType = tuQuestion;
}
void
DialogBox::warning(const char *format, ...)
{
char buf[4096];
char *p = buf;
// Print variable arguments
va_list ap;
va_start(ap, format);
p += vsprintf(buf, format, ap);
va_end(ap);
*p++ = '.';
*p = '\0';
makeMessage(buf);
dialogType = tuWarning;
}
void
DialogBox::warning(int err, const char *format, ...)
{
char buf[4096];
char *p = buf;
// Print variable arguments
va_list ap;
va_start(ap, format);
p += vsprintf(buf, format, ap);
va_end(ap);
// Add error message
if (err > 0 && err < sys_nerr) {
*p++ = ':';
*p++ = ' ';
*p++ = ' ';
p += sprintf(p, sys_errlist[err]);
}
*p++ = '.';
*p = '\0';
makeMessage(buf);
dialogType = tuWarning;
}
void
DialogBox::error(const char *format, ...)
{
char buf[4096];
char *p = buf;
// Print variable arguments
va_list ap;
va_start(ap, format);
p += vsprintf(buf, format, ap);
va_end(ap);
*p++ = '.';
*p = '\0';
makeMessage(buf);
dialogType = tuAction;
}
void
DialogBox::error(int err, const char *format, ...)
{
char buf[4096];
char *p = buf;
// Print variable arguments
va_list ap;
va_start(ap, format);
p += vsprintf(buf, format, ap);
va_end(ap);
// Add error message
if (err > 0 && err < sys_nerr) {
*p++ = ':';
*p++ = ' ';
*p++ = ' ';
p += sprintf(p, sys_errlist[err]);
}
*p++ = '.';
*p = '\0';
makeMessage(buf);
dialogType = tuAction;
}
void
DialogBox::makeMessage(char *buf)
{
unsigned int len = strlen(buf) + 1;
if (multiMessage && text != 0 && text[0] != '\0') {
unsigned int l = strlen(text);
if (textLength == 0 || len + l + 1 > textLength) {
char *t = new char[len + l + 1];
bcopy(text, t, l);
delete text;
text = t;
textLength = len + l + 1;
}
text[l++] = '\n';
bcopy(buf, &text[l], len);
} else {
if (len > textLength) {
delete text;
textLength = len;
text = new char[textLength];
}
bcopy(buf, text, len);
}
}