1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
|
/*****************************************************************************/
/* */
/* STDMSG.H */
/* */
/* (C) 1993-95 Ullrich von Bassewitz */
/* Zwehrenbuehlstrasse 33 */
/* D-72070 Tuebingen */
/* EMail: uz@ibb.schwaben.com */
/* */
/*****************************************************************************/
// $Id$
//
// $Log$
//
//
#include <stdarg.h>
#include "msgid.h"
#include "keydef.h"
#include "splitmsg.h"
#include "syserror.h"
#include "progutil.h"
#include "stdmsg.h"
/*****************************************************************************/
/* Message constants */
/*****************************************************************************/
static const u16 msErrorHdr = MSGBASE_STDMSG + 0;
static const u16 msInformationHdr = MSGBASE_STDMSG + 1;
static const u16 msFatalErrorHdr = MSGBASE_STDMSG + 2;
static const u16 msConfirm = MSGBASE_STDMSG + 10;
static const u16 msAbort = MSGBASE_STDMSG + 11;
static const u16 msIgnore = MSGBASE_STDMSG + 12;
static const u16 msRetry = MSGBASE_STDMSG + 13;
static const u16 msEnd = MSGBASE_STDMSG + 14;
static const u16 msPleaseWait = MSGBASE_STDMSG + 15;
/*****************************************************************************/
/* Explicit template instantiation */
/*****************************************************************************/
#ifdef EXPLICIT_TEMPLATES
template class ListNode<String>;
#endif
/*****************************************************************************/
/* */
/*****************************************************************************/
Window* MsgWindow (const String& Msg, const String& Header, u16 Palette)
// Create a window from the given data and return it. There are a few chars
// in Msg that have a special meaning:
//
// ~ toggle the attribute between atTextNormal and atTextHigh
// | begin a new line
// ^ begin a new centered line
// Note: The calling function has to free the returned window.
{
Rect Bounds;
ListNode<String>* Node;
ListNode<String>* N;
// Get the length of the window header
int HeaderLen = Header.Len ();
// Split up the text for the lines
Node = SplitLine (Msg, Bounds, HeaderLen);
// Correct the size of the window
if (Bounds.B.X < HeaderLen) {
Bounds.B.X = HeaderLen;
}
Bounds.B.X += 4; // + Space + Frame
Bounds.B.Y += 2; // + Frame
// Center the message window inside the screen
Rect ScreenSize (Background->OuterBounds ());
Bounds.Center (ScreenSize, cfCenterAll);
// Open the window but keep it hidden
Window* Win = new Window (Bounds, wfFramed | wfCanMove, Palette);
// Set the window options so that the window will remain centered even
// if the video mode changes
Win->SetOption (cfCenterAll);
// Write the Msg into the window
N = Node;
u16 Y = 0;
do {
Win->CWrite (1, Y, *(N->Contents ()));
N = N->Next ();
Y++;
} while (N != Node);
// Release the line list
ReleaseLines (Node);
// Set the window header and make it active (this will also show
// the window)
if (HeaderLen > 0) {
Win->SetHeader (Header);
}
Win->Activate ();
// Return the created window
return Win;
}
Window* PleaseWaitWindow ()
// Pops up a centered, activated, cyan window with a message like
// "Please wait..." in the current language
// The caller must dispose the window.
{
return MsgWindow (LoadMsg (msPleaseWait), "", paCyan);
}
static String KeyMsg (Key K, unsigned MsgNum)
// Return the name of key K surrounded by '~' and with the message with
// number MsgNum added
{
return GetKeyName3 (K) + LoadMsg (MsgNum);
}
unsigned ResponseWindow (const String& Msg, const String& Header, u16 Palette,
unsigned ResponseFlags)
// Show a window via MsgWindow with the given Msg, Header, Palette. Ask
// the user for a response. Allowed responses are coded in ResponseFlags.
// The status line is updated to show the valid responses.
{
// ResponseFlags cannot be empty
PRECONDITION (ResponseFlags != 0);
// Build a statusline according to the flags set in ResponseFlags
String StatusText;
if (ResponseFlags & reConfirm) StatusText += KeyMsg (kbEnter, msConfirm);
if (ResponseFlags & reAbort) StatusText += KeyMsg (vkAbort, msAbort);
if (ResponseFlags & reIgnore) StatusText += KeyMsg (kbMetaI, msIgnore);
if (ResponseFlags & reRetry) StatusText += KeyMsg (kbMetaR, msRetry);
if (ResponseFlags & reEnd) StatusText += KeyMsg (vkAbort, msEnd);
// Create the window
Window* Win = MsgWindow (Msg, Header, Palette);
// Show the new status line
PushStatusLine (StatusText);
// Now get the users response
unsigned Result = 0;
while (Result == 0) {
Key K = KbdGet ();
switch (K) {
case kbEnter:
case vkAccept:
if (ResponseFlags & reConfirm) {
Result = reConfirm;
} else if (ResponseFlags & reEnd) {
Result = reEnd;
}
break;
case vkAbort:
if (ResponseFlags & reAbort) {
Result = reAbort;
} else if (ResponseFlags & reEnd) {
Result = reEnd;
}
break;
case kbMetaI:
if (ResponseFlags & reIgnore) {
Result = reIgnore;
}
break;
case kbMetaR:
if (ResponseFlags & reRetry) {
Result = reRetry;
}
break;
case vkResize:
Win->MoveResize ();
break;
}
}
// Delete the window and restore the old statusline
delete Win;
PopStatusLine ();
return Result;
}
void ErrorMsg (const String& Msg)
// Shows an error window. Returns when the window is closed (by vkAbort).
{
ResponseWindow (Msg, // Formatted message
LoadMsg (msErrorHdr), // window header
paRed, // palette
reAbort); // valid responses
}
void ErrorMsg (u16 MsgNo, ...)
// Shows an error window. Returns when the window is closed (by vkAbort).
{
va_list ap;
va_start (ap, MsgNo);
ResponseWindow (String (LoadMsg (MsgNo), ap), // Formatted message
LoadMsg (msErrorHdr), // window header
paRed, // palette
reAbort); // valid responses
va_end (ap);
}
void SysErrorMsg (int ErrorCode)
// Display an appropriate error message for the system error code errno. Errno
// _must_ be a valid error code from ::errno!
{
ErrorMsg (GetSysErrorMsg (ErrorCode));
}
void InformationMsg (const String& Msg)
// Shows an information window. Returns when the window is closed (by vkAbort).
{
ResponseWindow (Msg, // Formatted message
LoadMsg (msInformationHdr), // window header
paGray, // palette
reEnd); // valid responses
}
void FatalErrorMsg (const String& Msg)
// Shows an error window. Returns when the window is closed (by vkAbort).
{
ResponseWindow (Msg, // Formatted message
LoadMsg (msFatalErrorHdr), // window header
paError, // palette
reAbort); // valid responses
}
|