annotate CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/include/cursesf.h @ 69:33d812a61356

planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author jpayne
date Tue, 18 Mar 2025 17:55:14 -0400
parents
children
rev   line source
jpayne@69 1 // * This makes emacs happy -*-Mode: C++;-*-
jpayne@69 2 // vile:cppmode
jpayne@69 3 /****************************************************************************
jpayne@69 4 * Copyright 2019-2021,2022 Thomas E. Dickey *
jpayne@69 5 * Copyright 1998-2012,2014 Free Software Foundation, Inc. *
jpayne@69 6 * *
jpayne@69 7 * Permission is hereby granted, free of charge, to any person obtaining a *
jpayne@69 8 * copy of this software and associated documentation files (the *
jpayne@69 9 * "Software"), to deal in the Software without restriction, including *
jpayne@69 10 * without limitation the rights to use, copy, modify, merge, publish, *
jpayne@69 11 * distribute, distribute with modifications, sublicense, and/or sell *
jpayne@69 12 * copies of the Software, and to permit persons to whom the Software is *
jpayne@69 13 * furnished to do so, subject to the following conditions: *
jpayne@69 14 * *
jpayne@69 15 * The above copyright notice and this permission notice shall be included *
jpayne@69 16 * in all copies or substantial portions of the Software. *
jpayne@69 17 * *
jpayne@69 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
jpayne@69 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
jpayne@69 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
jpayne@69 21 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
jpayne@69 22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
jpayne@69 23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
jpayne@69 24 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
jpayne@69 25 * *
jpayne@69 26 * Except as contained in this notice, the name(s) of the above copyright *
jpayne@69 27 * holders shall not be used in advertising or otherwise to promote the *
jpayne@69 28 * sale, use or other dealings in this Software without prior written *
jpayne@69 29 * authorization. *
jpayne@69 30 ****************************************************************************/
jpayne@69 31
jpayne@69 32 /****************************************************************************
jpayne@69 33 * Author: Juergen Pfeifer, 1997 *
jpayne@69 34 ****************************************************************************/
jpayne@69 35
jpayne@69 36 // $Id: cursesf.h,v 1.39 2022/08/20 20:52:15 tom Exp $
jpayne@69 37
jpayne@69 38 #ifndef NCURSES_CURSESF_H_incl
jpayne@69 39 #define NCURSES_CURSESF_H_incl 1
jpayne@69 40
jpayne@69 41 #include <ncursesw/cursesp.h>
jpayne@69 42
jpayne@69 43 #ifndef __EXT_QNX
jpayne@69 44 #include <string.h>
jpayne@69 45 #endif
jpayne@69 46
jpayne@69 47 extern "C" {
jpayne@69 48 # include <ncursesw/form.h>
jpayne@69 49 }
jpayne@69 50 //
jpayne@69 51 // -------------------------------------------------------------------------
jpayne@69 52 // The abstract base class for builtin and user defined Fieldtypes.
jpayne@69 53 // -------------------------------------------------------------------------
jpayne@69 54 //
jpayne@69 55 class NCURSES_CXX_IMPEXP NCursesFormField; // forward declaration
jpayne@69 56
jpayne@69 57 // Class to represent builtin field types as well as C++ written new
jpayne@69 58 // fieldtypes (see classes UserDefineFieldType...
jpayne@69 59 class NCURSES_CXX_IMPEXP NCursesFieldType
jpayne@69 60 {
jpayne@69 61 friend class NCursesFormField;
jpayne@69 62
jpayne@69 63 protected:
jpayne@69 64 FIELDTYPE* fieldtype;
jpayne@69 65
jpayne@69 66 inline void OnError(int err) const THROW2(NCursesException const, NCursesFormException) {
jpayne@69 67 if (err!=E_OK)
jpayne@69 68 THROW(new NCursesFormException (err));
jpayne@69 69 }
jpayne@69 70
jpayne@69 71 NCursesFieldType(FIELDTYPE *f) : fieldtype(f) {
jpayne@69 72 }
jpayne@69 73
jpayne@69 74 virtual ~NCursesFieldType() {}
jpayne@69 75
jpayne@69 76 // Set the fields f fieldtype to this one.
jpayne@69 77 virtual void set(NCursesFormField& f) = 0;
jpayne@69 78
jpayne@69 79 public:
jpayne@69 80 NCursesFieldType()
jpayne@69 81 : fieldtype(STATIC_CAST(FIELDTYPE*)(0))
jpayne@69 82 {
jpayne@69 83 }
jpayne@69 84
jpayne@69 85 NCursesFieldType& operator=(const NCursesFieldType& rhs)
jpayne@69 86 {
jpayne@69 87 if (this != &rhs) {
jpayne@69 88 *this = rhs;
jpayne@69 89 }
jpayne@69 90 return *this;
jpayne@69 91 }
jpayne@69 92
jpayne@69 93 NCursesFieldType(const NCursesFieldType& rhs)
jpayne@69 94 : fieldtype(rhs.fieldtype)
jpayne@69 95 {
jpayne@69 96 }
jpayne@69 97
jpayne@69 98 };
jpayne@69 99
jpayne@69 100 //
jpayne@69 101 // -------------------------------------------------------------------------
jpayne@69 102 // The class representing a forms field, wrapping the lowlevel FIELD struct
jpayne@69 103 // -------------------------------------------------------------------------
jpayne@69 104 //
jpayne@69 105 class NCURSES_CXX_IMPEXP NCursesFormField
jpayne@69 106 {
jpayne@69 107 friend class NCursesForm;
jpayne@69 108
jpayne@69 109 protected:
jpayne@69 110 FIELD *field; // lowlevel structure
jpayne@69 111 NCursesFieldType* ftype; // Associated field type
jpayne@69 112
jpayne@69 113 // Error handler
jpayne@69 114 inline void OnError (int err) const THROW2(NCursesException const, NCursesFormException) {
jpayne@69 115 if (err != E_OK)
jpayne@69 116 THROW(new NCursesFormException (err));
jpayne@69 117 }
jpayne@69 118
jpayne@69 119 public:
jpayne@69 120 // Create a 'Null' field. Can be used to delimit a field list
jpayne@69 121 NCursesFormField()
jpayne@69 122 : field(STATIC_CAST(FIELD*)(0)),
jpayne@69 123 ftype(STATIC_CAST(NCursesFieldType*)(0))
jpayne@69 124 {
jpayne@69 125 }
jpayne@69 126
jpayne@69 127 // Create a new field
jpayne@69 128 NCursesFormField (int rows,
jpayne@69 129 int ncols,
jpayne@69 130 int first_row = 0,
jpayne@69 131 int first_col = 0,
jpayne@69 132 int offscreen_rows = 0,
jpayne@69 133 int additional_buffers = 0)
jpayne@69 134 : field(0),
jpayne@69 135 ftype(STATIC_CAST(NCursesFieldType*)(0))
jpayne@69 136 {
jpayne@69 137 field = ::new_field(rows, ncols, first_row, first_col,
jpayne@69 138 offscreen_rows, additional_buffers);
jpayne@69 139 if (!field)
jpayne@69 140 OnError(errno);
jpayne@69 141 }
jpayne@69 142
jpayne@69 143 NCursesFormField& operator=(const NCursesFormField& rhs)
jpayne@69 144 {
jpayne@69 145 if (this != &rhs) {
jpayne@69 146 *this = rhs;
jpayne@69 147 }
jpayne@69 148 return *this;
jpayne@69 149 }
jpayne@69 150
jpayne@69 151 NCursesFormField(const NCursesFormField& rhs)
jpayne@69 152 : field(rhs.field), ftype(rhs.ftype)
jpayne@69 153 {
jpayne@69 154 }
jpayne@69 155
jpayne@69 156 virtual ~NCursesFormField () THROWS(NCursesException);
jpayne@69 157
jpayne@69 158 // Duplicate the field at a new position
jpayne@69 159 inline NCursesFormField* dup(int first_row, int first_col)
jpayne@69 160 {
jpayne@69 161 NCursesFormField* f = new NCursesFormField();
jpayne@69 162 if (!f)
jpayne@69 163 OnError(E_SYSTEM_ERROR);
jpayne@69 164 else {
jpayne@69 165 f->ftype = ftype;
jpayne@69 166 f->field = ::dup_field(field,first_row,first_col);
jpayne@69 167 if (!f->field)
jpayne@69 168 OnError(errno);
jpayne@69 169 }
jpayne@69 170 return f;
jpayne@69 171 }
jpayne@69 172
jpayne@69 173 // Link the field to a new location
jpayne@69 174 inline NCursesFormField* link(int first_row, int first_col) {
jpayne@69 175 NCursesFormField* f = new NCursesFormField();
jpayne@69 176 if (!f)
jpayne@69 177 OnError(E_SYSTEM_ERROR);
jpayne@69 178 else {
jpayne@69 179 f->ftype = ftype;
jpayne@69 180 f->field = ::link_field(field,first_row,first_col);
jpayne@69 181 if (!f->field)
jpayne@69 182 OnError(errno);
jpayne@69 183 }
jpayne@69 184 return f;
jpayne@69 185 }
jpayne@69 186
jpayne@69 187 // Get the lowlevel field representation
jpayne@69 188 inline FIELD* get_field() const {
jpayne@69 189 return field;
jpayne@69 190 }
jpayne@69 191
jpayne@69 192 // Retrieve info about the field
jpayne@69 193 inline void info(int& rows, int& ncols,
jpayne@69 194 int& first_row, int& first_col,
jpayne@69 195 int& offscreen_rows, int& additional_buffers) const {
jpayne@69 196 OnError(::field_info(field, &rows, &ncols,
jpayne@69 197 &first_row, &first_col,
jpayne@69 198 &offscreen_rows, &additional_buffers));
jpayne@69 199 }
jpayne@69 200
jpayne@69 201 // Retrieve info about the fields dynamic properties.
jpayne@69 202 inline void dynamic_info(int& dynamic_rows, int& dynamic_cols,
jpayne@69 203 int& max_growth) const {
jpayne@69 204 OnError(::dynamic_field_info(field, &dynamic_rows, &dynamic_cols,
jpayne@69 205 &max_growth));
jpayne@69 206 }
jpayne@69 207
jpayne@69 208 // For a dynamic field you may set the maximum growth limit.
jpayne@69 209 // A zero means unlimited growth.
jpayne@69 210 inline void set_maximum_growth(int growth = 0) {
jpayne@69 211 OnError(::set_max_field(field,growth));
jpayne@69 212 }
jpayne@69 213
jpayne@69 214 // Move the field to a new position
jpayne@69 215 inline void move(int row, int col) {
jpayne@69 216 OnError(::move_field(field,row,col));
jpayne@69 217 }
jpayne@69 218
jpayne@69 219 // Mark the field to start a new page
jpayne@69 220 inline void new_page(bool pageFlag = FALSE) {
jpayne@69 221 OnError(::set_new_page(field,pageFlag));
jpayne@69 222 }
jpayne@69 223
jpayne@69 224 // Retrieve whether or not the field starts a new page.
jpayne@69 225 inline bool is_new_page() const {
jpayne@69 226 return ::new_page(field);
jpayne@69 227 }
jpayne@69 228
jpayne@69 229 // Set the justification for the field
jpayne@69 230 inline void set_justification(int just) {
jpayne@69 231 OnError(::set_field_just(field,just));
jpayne@69 232 }
jpayne@69 233
jpayne@69 234 // Retrieve the fields justification
jpayne@69 235 inline int justification() const {
jpayne@69 236 return ::field_just(field);
jpayne@69 237 }
jpayne@69 238 // Set the foreground attribute for the field
jpayne@69 239 inline void set_foreground(chtype foreground) {
jpayne@69 240 OnError(::set_field_fore(field,foreground));
jpayne@69 241 }
jpayne@69 242
jpayne@69 243 // Retrieve the fields foreground attribute
jpayne@69 244 inline chtype fore() const {
jpayne@69 245 return ::field_fore(field);
jpayne@69 246 }
jpayne@69 247
jpayne@69 248 // Set the background attribute for the field
jpayne@69 249 inline void set_background(chtype background) {
jpayne@69 250 OnError(::set_field_back(field,background));
jpayne@69 251 }
jpayne@69 252
jpayne@69 253 // Retrieve the fields background attribute
jpayne@69 254 inline chtype back() const {
jpayne@69 255 return ::field_back(field);
jpayne@69 256 }
jpayne@69 257
jpayne@69 258 // Set the padding character for the field
jpayne@69 259 inline void set_pad_character(int padding) {
jpayne@69 260 OnError(::set_field_pad(field, padding));
jpayne@69 261 }
jpayne@69 262
jpayne@69 263 // Retrieve the fields padding character
jpayne@69 264 inline int pad() const {
jpayne@69 265 return ::field_pad(field);
jpayne@69 266 }
jpayne@69 267
jpayne@69 268 // Switch on the fields options
jpayne@69 269 inline void options_on (Field_Options opts) {
jpayne@69 270 OnError (::field_opts_on (field, opts));
jpayne@69 271 }
jpayne@69 272
jpayne@69 273 // Switch off the fields options
jpayne@69 274 inline void options_off (Field_Options opts) {
jpayne@69 275 OnError (::field_opts_off (field, opts));
jpayne@69 276 }
jpayne@69 277
jpayne@69 278 // Retrieve the fields options
jpayne@69 279 inline Field_Options options () const {
jpayne@69 280 return ::field_opts (field);
jpayne@69 281 }
jpayne@69 282
jpayne@69 283 // Set the fields options
jpayne@69 284 inline void set_options (Field_Options opts) {
jpayne@69 285 OnError (::set_field_opts (field, opts));
jpayne@69 286 }
jpayne@69 287
jpayne@69 288 // Mark the field as changed
jpayne@69 289 inline void set_changed(bool changeFlag = TRUE) {
jpayne@69 290 OnError(::set_field_status(field,changeFlag));
jpayne@69 291 }
jpayne@69 292
jpayne@69 293 // Test whether or not the field is marked as changed
jpayne@69 294 inline bool changed() const {
jpayne@69 295 return ::field_status(field);
jpayne@69 296 }
jpayne@69 297
jpayne@69 298 // Return the index of the field in the field array of a form
jpayne@69 299 // or -1 if the field is not associated to a form
jpayne@69 300 inline int (index)() const {
jpayne@69 301 return ::field_index(field);
jpayne@69 302 }
jpayne@69 303
jpayne@69 304 // Store a value in a fields buffer. The default buffer is nr. 0
jpayne@69 305 inline void set_value(const char *val, int buffer = 0) {
jpayne@69 306 OnError(::set_field_buffer(field,buffer,val));
jpayne@69 307 }
jpayne@69 308
jpayne@69 309 // Retrieve the value of a fields buffer. The default buffer is nr. 0
jpayne@69 310 inline char* value(int buffer = 0) const {
jpayne@69 311 return ::field_buffer(field,buffer);
jpayne@69 312 }
jpayne@69 313
jpayne@69 314 // Set the validation type of the field.
jpayne@69 315 inline void set_fieldtype(NCursesFieldType& f) {
jpayne@69 316 ftype = &f;
jpayne@69 317 f.set(*this); // A good friend may do that...
jpayne@69 318 }
jpayne@69 319
jpayne@69 320 // Retrieve the validation type of the field.
jpayne@69 321 inline NCursesFieldType* fieldtype() const {
jpayne@69 322 return ftype;
jpayne@69 323 }
jpayne@69 324
jpayne@69 325 };
jpayne@69 326
jpayne@69 327 // This are the built-in hook functions in this C++ binding. In C++ we use
jpayne@69 328 // virtual member functions (see below On_..._Init and On_..._Termination)
jpayne@69 329 // to provide this functionality in an object oriented manner.
jpayne@69 330 extern "C" {
jpayne@69 331 void _nc_xx_frm_init(FORM *);
jpayne@69 332 void _nc_xx_frm_term(FORM *);
jpayne@69 333 void _nc_xx_fld_init(FORM *);
jpayne@69 334 void _nc_xx_fld_term(FORM *);
jpayne@69 335 }
jpayne@69 336
jpayne@69 337 //
jpayne@69 338 // -------------------------------------------------------------------------
jpayne@69 339 // The class representing a form, wrapping the lowlevel FORM struct
jpayne@69 340 // -------------------------------------------------------------------------
jpayne@69 341 //
jpayne@69 342 class NCURSES_CXX_IMPEXP NCursesForm : public NCursesPanel
jpayne@69 343 {
jpayne@69 344 protected:
jpayne@69 345 FORM* form; // the lowlevel structure
jpayne@69 346
jpayne@69 347 private:
jpayne@69 348 NCursesWindow* sub; // the subwindow object
jpayne@69 349 bool b_sub_owner; // is this our own subwindow?
jpayne@69 350 bool b_framed; // has the form a border?
jpayne@69 351 bool b_autoDelete; // Delete fields when deleting form?
jpayne@69 352
jpayne@69 353 NCursesFormField** my_fields; // The array of fields for this form
jpayne@69 354
jpayne@69 355 // This structure is used for the form's user data field to link the
jpayne@69 356 // FORM* to the C++ object and to provide extra space for a user pointer.
jpayne@69 357 typedef struct {
jpayne@69 358 void* m_user; // the pointer for the user's data
jpayne@69 359 const NCursesForm* m_back; // backward pointer to C++ object
jpayne@69 360 const FORM* m_owner;
jpayne@69 361 } UserHook;
jpayne@69 362
jpayne@69 363 // Get the backward pointer to the C++ object from a FORM
jpayne@69 364 static inline NCursesForm* getHook(const FORM *f) {
jpayne@69 365 UserHook* hook = reinterpret_cast<UserHook*>(::form_userptr(f));
jpayne@69 366 assert(hook != 0 && hook->m_owner==f);
jpayne@69 367 return const_cast<NCursesForm*>(hook->m_back);
jpayne@69 368 }
jpayne@69 369
jpayne@69 370 friend void _nc_xx_frm_init(FORM *);
jpayne@69 371 friend void _nc_xx_frm_term(FORM *);
jpayne@69 372 friend void _nc_xx_fld_init(FORM *);
jpayne@69 373 friend void _nc_xx_fld_term(FORM *);
jpayne@69 374
jpayne@69 375 // Calculate FIELD* array for the menu
jpayne@69 376 FIELD** mapFields(NCursesFormField* nfields[]);
jpayne@69 377
jpayne@69 378 protected:
jpayne@69 379 // internal routines
jpayne@69 380 inline void set_user(void *user) {
jpayne@69 381 UserHook* uptr = reinterpret_cast<UserHook*>(::form_userptr (form));
jpayne@69 382 assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==form);
jpayne@69 383 uptr->m_user = user;
jpayne@69 384 }
jpayne@69 385
jpayne@69 386 inline void *get_user() {
jpayne@69 387 UserHook* uptr = reinterpret_cast<UserHook*>(::form_userptr (form));
jpayne@69 388 assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==form);
jpayne@69 389 return uptr->m_user;
jpayne@69 390 }
jpayne@69 391
jpayne@69 392 void InitForm (NCursesFormField* Fields[],
jpayne@69 393 bool with_frame,
jpayne@69 394 bool autoDeleteFields);
jpayne@69 395
jpayne@69 396 inline void OnError (int err) const THROW2(NCursesException const, NCursesFormException) {
jpayne@69 397 if (err != E_OK)
jpayne@69 398 THROW(new NCursesFormException (err));
jpayne@69 399 }
jpayne@69 400
jpayne@69 401 // this wraps the form_driver call.
jpayne@69 402 virtual int driver (int c) ;
jpayne@69 403
jpayne@69 404 // 'Internal' constructor, builds an object without association to a
jpayne@69 405 // field array.
jpayne@69 406 NCursesForm( int nlines,
jpayne@69 407 int ncols,
jpayne@69 408 int begin_y = 0,
jpayne@69 409 int begin_x = 0)
jpayne@69 410 : NCursesPanel(nlines, ncols, begin_y, begin_x),
jpayne@69 411 form (STATIC_CAST(FORM*)(0)),
jpayne@69 412 sub(0),
jpayne@69 413 b_sub_owner(0),
jpayne@69 414 b_framed(0),
jpayne@69 415 b_autoDelete(0),
jpayne@69 416 my_fields(0)
jpayne@69 417 {
jpayne@69 418 }
jpayne@69 419
jpayne@69 420 public:
jpayne@69 421 // Create form for the default panel.
jpayne@69 422 NCursesForm (NCursesFormField* Fields[],
jpayne@69 423 bool with_frame=FALSE, // reserve space for a frame?
jpayne@69 424 bool autoDelete_Fields=FALSE) // do automatic cleanup?
jpayne@69 425 : NCursesPanel(),
jpayne@69 426 form(0),
jpayne@69 427 sub(0),
jpayne@69 428 b_sub_owner(0),
jpayne@69 429 b_framed(0),
jpayne@69 430 b_autoDelete(0),
jpayne@69 431 my_fields(0)
jpayne@69 432 {
jpayne@69 433 InitForm(Fields, with_frame, autoDelete_Fields);
jpayne@69 434 }
jpayne@69 435
jpayne@69 436 // Create a form in a panel with the given position and size.
jpayne@69 437 NCursesForm (NCursesFormField* Fields[],
jpayne@69 438 int nlines,
jpayne@69 439 int ncols,
jpayne@69 440 int begin_y,
jpayne@69 441 int begin_x,
jpayne@69 442 bool with_frame=FALSE, // reserve space for a frame?
jpayne@69 443 bool autoDelete_Fields=FALSE) // do automatic cleanup?
jpayne@69 444 : NCursesPanel(nlines, ncols, begin_y, begin_x),
jpayne@69 445 form(0),
jpayne@69 446 sub(0),
jpayne@69 447 b_sub_owner(0),
jpayne@69 448 b_framed(0),
jpayne@69 449 b_autoDelete(0),
jpayne@69 450 my_fields(0)
jpayne@69 451 {
jpayne@69 452 InitForm(Fields, with_frame, autoDelete_Fields);
jpayne@69 453 }
jpayne@69 454
jpayne@69 455 NCursesForm& operator=(const NCursesForm& rhs)
jpayne@69 456 {
jpayne@69 457 if (this != &rhs) {
jpayne@69 458 *this = rhs;
jpayne@69 459 NCursesPanel::operator=(rhs);
jpayne@69 460 }
jpayne@69 461 return *this;
jpayne@69 462 }
jpayne@69 463
jpayne@69 464 NCursesForm(const NCursesForm& rhs)
jpayne@69 465 : NCursesPanel(rhs),
jpayne@69 466 form(rhs.form),
jpayne@69 467 sub(rhs.sub),
jpayne@69 468 b_sub_owner(rhs.b_sub_owner),
jpayne@69 469 b_framed(rhs.b_framed),
jpayne@69 470 b_autoDelete(rhs.b_autoDelete),
jpayne@69 471 my_fields(rhs.my_fields)
jpayne@69 472 {
jpayne@69 473 }
jpayne@69 474
jpayne@69 475 virtual ~NCursesForm() THROWS(NCursesException);
jpayne@69 476
jpayne@69 477 // Set the default attributes for the form
jpayne@69 478 virtual void setDefaultAttributes();
jpayne@69 479
jpayne@69 480 // Retrieve current field of the form.
jpayne@69 481 inline NCursesFormField* current_field() const {
jpayne@69 482 return my_fields[::field_index(::current_field(form))];
jpayne@69 483 }
jpayne@69 484
jpayne@69 485 // Set the forms subwindow
jpayne@69 486 void setSubWindow(NCursesWindow& sub);
jpayne@69 487
jpayne@69 488 // Set these fields for the form
jpayne@69 489 inline void setFields(NCursesFormField* Fields[]) {
jpayne@69 490 OnError(::set_form_fields(form,mapFields(Fields)));
jpayne@69 491 }
jpayne@69 492
jpayne@69 493 // Remove the form from the screen
jpayne@69 494 inline void unpost (void) {
jpayne@69 495 OnError (::unpost_form (form));
jpayne@69 496 }
jpayne@69 497
jpayne@69 498 // Post the form to the screen if flag is true, unpost it otherwise
jpayne@69 499 inline void post(bool flag = TRUE) {
jpayne@69 500 OnError (flag ? ::post_form(form) : ::unpost_form (form));
jpayne@69 501 }
jpayne@69 502
jpayne@69 503 // Decorations
jpayne@69 504 inline void frame(const char *title=NULL, const char* btitle=NULL) NCURSES_OVERRIDE {
jpayne@69 505 if (b_framed)
jpayne@69 506 NCursesPanel::frame(title,btitle);
jpayne@69 507 else
jpayne@69 508 OnError(E_SYSTEM_ERROR);
jpayne@69 509 }
jpayne@69 510
jpayne@69 511 inline void boldframe(const char *title=NULL, const char* btitle=NULL) NCURSES_OVERRIDE {
jpayne@69 512 if (b_framed)
jpayne@69 513 NCursesPanel::boldframe(title,btitle);
jpayne@69 514 else
jpayne@69 515 OnError(E_SYSTEM_ERROR);
jpayne@69 516 }
jpayne@69 517
jpayne@69 518 inline void label(const char *topLabel, const char *bottomLabel) NCURSES_OVERRIDE {
jpayne@69 519 if (b_framed)
jpayne@69 520 NCursesPanel::label(topLabel,bottomLabel);
jpayne@69 521 else
jpayne@69 522 OnError(E_SYSTEM_ERROR);
jpayne@69 523 }
jpayne@69 524
jpayne@69 525 // -----
jpayne@69 526 // Hooks
jpayne@69 527 // -----
jpayne@69 528
jpayne@69 529 // Called after the form gets repositioned in its window.
jpayne@69 530 // This is especially true if the form is posted.
jpayne@69 531 virtual void On_Form_Init();
jpayne@69 532
jpayne@69 533 // Called before the form gets repositioned in its window.
jpayne@69 534 // This is especially true if the form is unposted.
jpayne@69 535 virtual void On_Form_Termination();
jpayne@69 536
jpayne@69 537 // Called after the field became the current field
jpayne@69 538 virtual void On_Field_Init(NCursesFormField& field);
jpayne@69 539
jpayne@69 540 // Called before this field is left as current field.
jpayne@69 541 virtual void On_Field_Termination(NCursesFormField& field);
jpayne@69 542
jpayne@69 543 // Calculate required window size for the form.
jpayne@69 544 void scale(int& rows, int& ncols) const {
jpayne@69 545 OnError(::scale_form(form,&rows,&ncols));
jpayne@69 546 }
jpayne@69 547
jpayne@69 548 // Retrieve number of fields in the form.
jpayne@69 549 int count() const {
jpayne@69 550 return ::field_count(form);
jpayne@69 551 }
jpayne@69 552
jpayne@69 553 // Make the page the current page of the form.
jpayne@69 554 void set_page(int pageNum) {
jpayne@69 555 OnError(::set_form_page(form, pageNum));
jpayne@69 556 }
jpayne@69 557
jpayne@69 558 // Retrieve current page number
jpayne@69 559 int page() const {
jpayne@69 560 return ::form_page(form);
jpayne@69 561 }
jpayne@69 562
jpayne@69 563 // Switch on the forms options
jpayne@69 564 inline void options_on (Form_Options opts) {
jpayne@69 565 OnError (::form_opts_on (form, opts));
jpayne@69 566 }
jpayne@69 567
jpayne@69 568 // Switch off the forms options
jpayne@69 569 inline void options_off (Form_Options opts) {
jpayne@69 570 OnError (::form_opts_off (form, opts));
jpayne@69 571 }
jpayne@69 572
jpayne@69 573 // Retrieve the forms options
jpayne@69 574 inline Form_Options options () const {
jpayne@69 575 return ::form_opts (form);
jpayne@69 576 }
jpayne@69 577
jpayne@69 578 // Set the forms options
jpayne@69 579 inline void set_options (Form_Options opts) {
jpayne@69 580 OnError (::set_form_opts (form, opts));
jpayne@69 581 }
jpayne@69 582
jpayne@69 583 // Are there more data in the current field after the data shown
jpayne@69 584 inline bool data_ahead() const {
jpayne@69 585 return ::data_ahead(form);
jpayne@69 586 }
jpayne@69 587
jpayne@69 588 // Are there more data in the current field before the data shown
jpayne@69 589 inline bool data_behind() const {
jpayne@69 590 return ::data_behind(form);
jpayne@69 591 }
jpayne@69 592
jpayne@69 593 // Position the cursor to the current field
jpayne@69 594 inline void position_cursor () {
jpayne@69 595 OnError (::pos_form_cursor (form));
jpayne@69 596 }
jpayne@69 597 // Set the current field
jpayne@69 598 inline void set_current(NCursesFormField& F) {
jpayne@69 599 OnError (::set_current_field(form, F.field));
jpayne@69 600 }
jpayne@69 601
jpayne@69 602 // Provide a default key virtualization. Translate the keyboard
jpayne@69 603 // code c into a form request code.
jpayne@69 604 // The default implementation provides a hopefully straightforward
jpayne@69 605 // mapping for the most common keystrokes and form requests.
jpayne@69 606 virtual int virtualize(int c);
jpayne@69 607
jpayne@69 608 // Operators
jpayne@69 609 inline NCursesFormField* operator[](int i) const {
jpayne@69 610 if ( (i < 0) || (i >= ::field_count (form)) )
jpayne@69 611 OnError (E_BAD_ARGUMENT);
jpayne@69 612 return my_fields[i];
jpayne@69 613 }
jpayne@69 614
jpayne@69 615 // Perform the menu's operation
jpayne@69 616 // Return the field where you left the form.
jpayne@69 617 virtual NCursesFormField* operator()(void);
jpayne@69 618
jpayne@69 619 // Exception handlers. The default is a Beep.
jpayne@69 620 virtual void On_Request_Denied(int c) const;
jpayne@69 621 virtual void On_Invalid_Field(int c) const;
jpayne@69 622 virtual void On_Unknown_Command(int c) const;
jpayne@69 623
jpayne@69 624 };
jpayne@69 625
jpayne@69 626 //
jpayne@69 627 // -------------------------------------------------------------------------
jpayne@69 628 // This is the typical C++ typesafe way to allow to attach
jpayne@69 629 // user data to a field of a form. Its assumed that the user
jpayne@69 630 // data belongs to some class T. Use T as template argument
jpayne@69 631 // to create a UserField.
jpayne@69 632 // -------------------------------------------------------------------------
jpayne@69 633 template<class T> class NCURSES_CXX_IMPEXP NCursesUserField : public NCursesFormField
jpayne@69 634 {
jpayne@69 635 public:
jpayne@69 636 NCursesUserField (int rows,
jpayne@69 637 int ncols,
jpayne@69 638 int first_row = 0,
jpayne@69 639 int first_col = 0,
jpayne@69 640 const T* p_UserData = STATIC_CAST(T*)(0),
jpayne@69 641 int offscreen_rows = 0,
jpayne@69 642 int additional_buffers = 0)
jpayne@69 643 : NCursesFormField (rows, ncols,
jpayne@69 644 first_row, first_col,
jpayne@69 645 offscreen_rows, additional_buffers) {
jpayne@69 646 if (field)
jpayne@69 647 OnError(::set_field_userptr(field, STATIC_CAST(void *)(p_UserData)));
jpayne@69 648 }
jpayne@69 649
jpayne@69 650 virtual ~NCursesUserField() THROWS(NCursesException) {};
jpayne@69 651
jpayne@69 652 inline const T* UserData (void) const {
jpayne@69 653 return reinterpret_cast<const T*>(::field_userptr (field));
jpayne@69 654 }
jpayne@69 655
jpayne@69 656 inline virtual void setUserData(const T* p_UserData) {
jpayne@69 657 if (field)
jpayne@69 658 OnError (::set_field_userptr (field, STATIC_CAST(void *)(p_UserData)));
jpayne@69 659 }
jpayne@69 660 };
jpayne@69 661 //
jpayne@69 662 // -------------------------------------------------------------------------
jpayne@69 663 // The same mechanism is used to attach user data to a form
jpayne@69 664 // -------------------------------------------------------------------------
jpayne@69 665 //
jpayne@69 666 template<class T> class NCURSES_CXX_IMPEXP NCursesUserForm : public NCursesForm
jpayne@69 667 {
jpayne@69 668 protected:
jpayne@69 669 // 'Internal' constructor, builds an object without association to a
jpayne@69 670 // field array.
jpayne@69 671 NCursesUserForm( int nlines,
jpayne@69 672 int ncols,
jpayne@69 673 int begin_y = 0,
jpayne@69 674 int begin_x = 0,
jpayne@69 675 const T* p_UserData = STATIC_CAST(T*)(0))
jpayne@69 676 : NCursesForm(nlines,ncols,begin_y,begin_x) {
jpayne@69 677 if (form)
jpayne@69 678 set_user (const_cast<void *>(reinterpret_cast<const void*>
jpayne@69 679 (p_UserData)));
jpayne@69 680 }
jpayne@69 681
jpayne@69 682 public:
jpayne@69 683 NCursesUserForm (NCursesFormField* Fields[],
jpayne@69 684 const T* p_UserData = STATIC_CAST(T*)(0),
jpayne@69 685 bool with_frame=FALSE,
jpayne@69 686 bool autoDelete_Fields=FALSE)
jpayne@69 687 : NCursesForm (Fields, with_frame, autoDelete_Fields) {
jpayne@69 688 if (form)
jpayne@69 689 set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
jpayne@69 690 };
jpayne@69 691
jpayne@69 692 NCursesUserForm (NCursesFormField* Fields[],
jpayne@69 693 int nlines,
jpayne@69 694 int ncols,
jpayne@69 695 int begin_y = 0,
jpayne@69 696 int begin_x = 0,
jpayne@69 697 const T* p_UserData = STATIC_CAST(T*)(0),
jpayne@69 698 bool with_frame=FALSE,
jpayne@69 699 bool autoDelete_Fields=FALSE)
jpayne@69 700 : NCursesForm (Fields, nlines, ncols, begin_y, begin_x,
jpayne@69 701 with_frame, autoDelete_Fields) {
jpayne@69 702 if (form)
jpayne@69 703 set_user (const_cast<void *>(reinterpret_cast<const void*>
jpayne@69 704 (p_UserData)));
jpayne@69 705 };
jpayne@69 706
jpayne@69 707 virtual ~NCursesUserForm() THROWS(NCursesException) {
jpayne@69 708 };
jpayne@69 709
jpayne@69 710 inline T* UserData (void) {
jpayne@69 711 return reinterpret_cast<T*>(get_user ());
jpayne@69 712 };
jpayne@69 713
jpayne@69 714 inline virtual void setUserData (const T* p_UserData) {
jpayne@69 715 if (form)
jpayne@69 716 set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
jpayne@69 717 }
jpayne@69 718
jpayne@69 719 };
jpayne@69 720 //
jpayne@69 721 // -------------------------------------------------------------------------
jpayne@69 722 // Builtin Fieldtypes
jpayne@69 723 // -------------------------------------------------------------------------
jpayne@69 724 //
jpayne@69 725 class NCURSES_CXX_IMPEXP Alpha_Field : public NCursesFieldType
jpayne@69 726 {
jpayne@69 727 private:
jpayne@69 728 int min_field_width;
jpayne@69 729
jpayne@69 730 void set(NCursesFormField& f) NCURSES_OVERRIDE {
jpayne@69 731 OnError(::set_field_type(f.get_field(),fieldtype,min_field_width));
jpayne@69 732 }
jpayne@69 733
jpayne@69 734 public:
jpayne@69 735 explicit Alpha_Field(int width)
jpayne@69 736 : NCursesFieldType(TYPE_ALPHA),
jpayne@69 737 min_field_width(width) {
jpayne@69 738 }
jpayne@69 739 };
jpayne@69 740
jpayne@69 741 class NCURSES_CXX_IMPEXP Alphanumeric_Field : public NCursesFieldType
jpayne@69 742 {
jpayne@69 743 private:
jpayne@69 744 int min_field_width;
jpayne@69 745
jpayne@69 746 void set(NCursesFormField& f) NCURSES_OVERRIDE {
jpayne@69 747 OnError(::set_field_type(f.get_field(),fieldtype,min_field_width));
jpayne@69 748 }
jpayne@69 749
jpayne@69 750 public:
jpayne@69 751 explicit Alphanumeric_Field(int width)
jpayne@69 752 : NCursesFieldType(TYPE_ALNUM),
jpayne@69 753 min_field_width(width) {
jpayne@69 754 }
jpayne@69 755 };
jpayne@69 756
jpayne@69 757 class NCURSES_CXX_IMPEXP Integer_Field : public NCursesFieldType
jpayne@69 758 {
jpayne@69 759 private:
jpayne@69 760 int precision;
jpayne@69 761 long lower_limit, upper_limit;
jpayne@69 762
jpayne@69 763 void set(NCursesFormField& f) NCURSES_OVERRIDE {
jpayne@69 764 OnError(::set_field_type(f.get_field(),fieldtype,
jpayne@69 765 precision,lower_limit,upper_limit));
jpayne@69 766 }
jpayne@69 767
jpayne@69 768 public:
jpayne@69 769 Integer_Field(int prec, long low=0L, long high=0L)
jpayne@69 770 : NCursesFieldType(TYPE_INTEGER),
jpayne@69 771 precision(prec), lower_limit(low), upper_limit(high) {
jpayne@69 772 }
jpayne@69 773 };
jpayne@69 774
jpayne@69 775 class NCURSES_CXX_IMPEXP Numeric_Field : public NCursesFieldType
jpayne@69 776 {
jpayne@69 777 private:
jpayne@69 778 int precision;
jpayne@69 779 double lower_limit, upper_limit;
jpayne@69 780
jpayne@69 781 void set(NCursesFormField& f) NCURSES_OVERRIDE {
jpayne@69 782 OnError(::set_field_type(f.get_field(),fieldtype,
jpayne@69 783 precision,lower_limit,upper_limit));
jpayne@69 784 }
jpayne@69 785
jpayne@69 786 public:
jpayne@69 787 Numeric_Field(int prec, double low=0.0, double high=0.0)
jpayne@69 788 : NCursesFieldType(TYPE_NUMERIC),
jpayne@69 789 precision(prec), lower_limit(low), upper_limit(high) {
jpayne@69 790 }
jpayne@69 791 };
jpayne@69 792
jpayne@69 793 class NCURSES_CXX_IMPEXP Regular_Expression_Field : public NCursesFieldType
jpayne@69 794 {
jpayne@69 795 private:
jpayne@69 796 char* regex;
jpayne@69 797
jpayne@69 798 void set(NCursesFormField& f) NCURSES_OVERRIDE {
jpayne@69 799 OnError(::set_field_type(f.get_field(),fieldtype,regex));
jpayne@69 800 }
jpayne@69 801
jpayne@69 802 void copy_regex(const char *source)
jpayne@69 803 {
jpayne@69 804 regex = new char[1 + ::strlen(source)];
jpayne@69 805 (::strcpy)(regex, source);
jpayne@69 806 }
jpayne@69 807
jpayne@69 808 public:
jpayne@69 809 explicit Regular_Expression_Field(const char *expr)
jpayne@69 810 : NCursesFieldType(TYPE_REGEXP),
jpayne@69 811 regex(NULL)
jpayne@69 812 {
jpayne@69 813 copy_regex(expr);
jpayne@69 814 }
jpayne@69 815
jpayne@69 816 Regular_Expression_Field& operator=(const Regular_Expression_Field& rhs)
jpayne@69 817 {
jpayne@69 818 if (this != &rhs) {
jpayne@69 819 *this = rhs;
jpayne@69 820 copy_regex(rhs.regex);
jpayne@69 821 NCursesFieldType::operator=(rhs);
jpayne@69 822 }
jpayne@69 823 return *this;
jpayne@69 824 }
jpayne@69 825
jpayne@69 826 Regular_Expression_Field(const Regular_Expression_Field& rhs)
jpayne@69 827 : NCursesFieldType(rhs),
jpayne@69 828 regex(NULL)
jpayne@69 829 {
jpayne@69 830 copy_regex(rhs.regex);
jpayne@69 831 }
jpayne@69 832
jpayne@69 833 ~Regular_Expression_Field() {
jpayne@69 834 delete[] regex;
jpayne@69 835 }
jpayne@69 836 };
jpayne@69 837
jpayne@69 838 class NCURSES_CXX_IMPEXP Enumeration_Field : public NCursesFieldType
jpayne@69 839 {
jpayne@69 840 private:
jpayne@69 841 const char** list;
jpayne@69 842 int case_sensitive;
jpayne@69 843 int non_unique_matches;
jpayne@69 844
jpayne@69 845 void set(NCursesFormField& f) NCURSES_OVERRIDE {
jpayne@69 846 OnError(::set_field_type(f.get_field(),fieldtype,
jpayne@69 847 list,case_sensitive,non_unique_matches));
jpayne@69 848 }
jpayne@69 849 public:
jpayne@69 850 Enumeration_Field(const char* enums[],
jpayne@69 851 bool case_sens=FALSE,
jpayne@69 852 bool non_unique=FALSE)
jpayne@69 853 : NCursesFieldType(TYPE_ENUM),
jpayne@69 854 list(enums),
jpayne@69 855 case_sensitive(case_sens ? -1 : 0),
jpayne@69 856 non_unique_matches(non_unique ? -1 : 0) {
jpayne@69 857 }
jpayne@69 858
jpayne@69 859 Enumeration_Field& operator=(const Enumeration_Field& rhs)
jpayne@69 860 {
jpayne@69 861 if (this != &rhs) {
jpayne@69 862 *this = rhs;
jpayne@69 863 NCursesFieldType::operator=(rhs);
jpayne@69 864 }
jpayne@69 865 return *this;
jpayne@69 866 }
jpayne@69 867
jpayne@69 868 Enumeration_Field(const Enumeration_Field& rhs)
jpayne@69 869 : NCursesFieldType(rhs),
jpayne@69 870 list(rhs.list),
jpayne@69 871 case_sensitive(rhs.case_sensitive),
jpayne@69 872 non_unique_matches(rhs.non_unique_matches)
jpayne@69 873 {
jpayne@69 874 }
jpayne@69 875 };
jpayne@69 876
jpayne@69 877 class NCURSES_CXX_IMPEXP IPV4_Address_Field : public NCursesFieldType
jpayne@69 878 {
jpayne@69 879 private:
jpayne@69 880 void set(NCursesFormField& f) NCURSES_OVERRIDE {
jpayne@69 881 OnError(::set_field_type(f.get_field(),fieldtype));
jpayne@69 882 }
jpayne@69 883
jpayne@69 884 public:
jpayne@69 885 IPV4_Address_Field() : NCursesFieldType(TYPE_IPV4) {
jpayne@69 886 }
jpayne@69 887 };
jpayne@69 888
jpayne@69 889 extern "C" {
jpayne@69 890 bool _nc_xx_fld_fcheck(FIELD *, const void*);
jpayne@69 891 bool _nc_xx_fld_ccheck(int c, const void *);
jpayne@69 892 void* _nc_xx_fld_makearg(va_list*);
jpayne@69 893 }
jpayne@69 894
jpayne@69 895 //
jpayne@69 896 // -------------------------------------------------------------------------
jpayne@69 897 // Abstract base class for User-Defined Fieldtypes
jpayne@69 898 // -------------------------------------------------------------------------
jpayne@69 899 //
jpayne@69 900 class NCURSES_CXX_IMPEXP UserDefinedFieldType : public NCursesFieldType
jpayne@69 901 {
jpayne@69 902 friend class UDF_Init; // Internal helper to set up statics
jpayne@69 903 private:
jpayne@69 904 // For all C++ defined fieldtypes we need only one generic lowlevel
jpayne@69 905 // FIELDTYPE* element.
jpayne@69 906 static FIELDTYPE* generic_fieldtype;
jpayne@69 907
jpayne@69 908 protected:
jpayne@69 909 // This are the functions required by the low level libforms functions
jpayne@69 910 // to construct a fieldtype.
jpayne@69 911 friend bool _nc_xx_fld_fcheck(FIELD *, const void*);
jpayne@69 912 friend bool _nc_xx_fld_ccheck(int c, const void *);
jpayne@69 913 friend void* _nc_xx_fld_makearg(va_list*);
jpayne@69 914
jpayne@69 915 void set(NCursesFormField& f) NCURSES_OVERRIDE {
jpayne@69 916 OnError(::set_field_type(f.get_field(),fieldtype,&f));
jpayne@69 917 }
jpayne@69 918
jpayne@69 919 protected:
jpayne@69 920 // Redefine this function to do a field validation. The argument
jpayne@69 921 // is a reference to the field you should validate.
jpayne@69 922 virtual bool field_check(NCursesFormField& f) = 0;
jpayne@69 923
jpayne@69 924 // Redefine this function to do a character validation. The argument
jpayne@69 925 // is the character to be validated.
jpayne@69 926 virtual bool char_check (int c) = 0;
jpayne@69 927
jpayne@69 928 public:
jpayne@69 929 UserDefinedFieldType();
jpayne@69 930 };
jpayne@69 931
jpayne@69 932 extern "C" {
jpayne@69 933 bool _nc_xx_next_choice(FIELD*, const void *);
jpayne@69 934 bool _nc_xx_prev_choice(FIELD*, const void *);
jpayne@69 935 }
jpayne@69 936
jpayne@69 937 //
jpayne@69 938 // -------------------------------------------------------------------------
jpayne@69 939 // Abstract base class for User-Defined Fieldtypes with Choice functions
jpayne@69 940 // -------------------------------------------------------------------------
jpayne@69 941 //
jpayne@69 942 class NCURSES_CXX_IMPEXP UserDefinedFieldType_With_Choice : public UserDefinedFieldType
jpayne@69 943 {
jpayne@69 944 friend class UDF_Init; // Internal helper to set up statics
jpayne@69 945 private:
jpayne@69 946 // For all C++ defined fieldtypes with choice functions we need only one
jpayne@69 947 // generic lowlevel FIELDTYPE* element.
jpayne@69 948 static FIELDTYPE* generic_fieldtype_with_choice;
jpayne@69 949
jpayne@69 950 // This are the functions required by the low level libforms functions
jpayne@69 951 // to construct a fieldtype with choice functions.
jpayne@69 952 friend bool _nc_xx_next_choice(FIELD*, const void *);
jpayne@69 953 friend bool _nc_xx_prev_choice(FIELD*, const void *);
jpayne@69 954
jpayne@69 955 protected:
jpayne@69 956 // Redefine this function to do the retrieval of the next choice value.
jpayne@69 957 // The argument is a reference to the field tobe examined.
jpayne@69 958 virtual bool next (NCursesFormField& f) = 0;
jpayne@69 959
jpayne@69 960 // Redefine this function to do the retrieval of the previous choice value.
jpayne@69 961 // The argument is a reference to the field tobe examined.
jpayne@69 962 virtual bool previous(NCursesFormField& f) = 0;
jpayne@69 963
jpayne@69 964 public:
jpayne@69 965 UserDefinedFieldType_With_Choice();
jpayne@69 966 };
jpayne@69 967
jpayne@69 968 #endif /* NCURSES_CURSESF_H_incl */