cursesf.h 27 KB

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