cursesf.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969
  1. // * This makes emacs happy -*-Mode: C++;-*-
  2. /****************************************************************************
  3. * Copyright (c) 1998-2012,2014 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.32 2014/08/09 22:06:11 Adam.Jiang 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 THROW2(NCursesException const, 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 THROW2(NCursesException const, 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 THROW2(NCursesException const, 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 *>(reinterpret_cast<const void*>
  572. (p_UserData)));
  573. }
  574. public:
  575. NCursesUserForm (NCursesFormField* Fields[],
  576. const T* p_UserData = STATIC_CAST(T*)(0),
  577. bool with_frame=FALSE,
  578. bool autoDelete_Fields=FALSE)
  579. : NCursesForm (Fields, with_frame, autoDelete_Fields) {
  580. if (form)
  581. set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
  582. };
  583. NCursesUserForm (NCursesFormField* Fields[],
  584. int nlines,
  585. int ncols,
  586. int begin_y = 0,
  587. int begin_x = 0,
  588. const T* p_UserData = STATIC_CAST(T*)(0),
  589. bool with_frame=FALSE,
  590. bool autoDelete_Fields=FALSE)
  591. : NCursesForm (Fields, nlines, ncols, begin_y, begin_x,
  592. with_frame, autoDelete_Fields) {
  593. if (form)
  594. set_user (const_cast<void *>(reinterpret_cast<const void*>
  595. (p_UserData)));
  596. };
  597. virtual ~NCursesUserForm() {
  598. };
  599. inline T* UserData (void) {
  600. return reinterpret_cast<T*>(get_user ());
  601. };
  602. inline virtual void setUserData (const T* p_UserData) {
  603. if (form)
  604. set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
  605. }
  606. };
  607. //
  608. // -------------------------------------------------------------------------
  609. // Builtin Fieldtypes
  610. // -------------------------------------------------------------------------
  611. //
  612. class NCURSES_IMPEXP Alpha_Field : public NCursesFieldType
  613. {
  614. private:
  615. int min_field_width;
  616. void set(NCursesFormField& f) {
  617. OnError(::set_field_type(f.get_field(),fieldtype,min_field_width));
  618. }
  619. public:
  620. Alpha_Field(int width)
  621. : NCursesFieldType(TYPE_ALPHA),
  622. min_field_width(width) {
  623. }
  624. };
  625. class NCURSES_IMPEXP Alphanumeric_Field : public NCursesFieldType
  626. {
  627. private:
  628. int min_field_width;
  629. void set(NCursesFormField& f) {
  630. OnError(::set_field_type(f.get_field(),fieldtype,min_field_width));
  631. }
  632. public:
  633. Alphanumeric_Field(int width)
  634. : NCursesFieldType(TYPE_ALNUM),
  635. min_field_width(width) {
  636. }
  637. };
  638. class NCURSES_IMPEXP Integer_Field : public NCursesFieldType
  639. {
  640. private:
  641. int precision;
  642. long lower_limit, upper_limit;
  643. void set(NCursesFormField& f) {
  644. OnError(::set_field_type(f.get_field(),fieldtype,
  645. precision,lower_limit,upper_limit));
  646. }
  647. public:
  648. Integer_Field(int prec, long low=0L, long high=0L)
  649. : NCursesFieldType(TYPE_INTEGER),
  650. precision(prec), lower_limit(low), upper_limit(high) {
  651. }
  652. };
  653. class NCURSES_IMPEXP Numeric_Field : public NCursesFieldType
  654. {
  655. private:
  656. int precision;
  657. double lower_limit, upper_limit;
  658. void set(NCursesFormField& f) {
  659. OnError(::set_field_type(f.get_field(),fieldtype,
  660. precision,lower_limit,upper_limit));
  661. }
  662. public:
  663. Numeric_Field(int prec, double low=0.0, double high=0.0)
  664. : NCursesFieldType(TYPE_NUMERIC),
  665. precision(prec), lower_limit(low), upper_limit(high) {
  666. }
  667. };
  668. class NCURSES_IMPEXP Regular_Expression_Field : public NCursesFieldType
  669. {
  670. private:
  671. char* regex;
  672. void set(NCursesFormField& f) {
  673. OnError(::set_field_type(f.get_field(),fieldtype,regex));
  674. }
  675. void copy_regex(const char *source)
  676. {
  677. regex = new char[1 + ::strlen(source)];
  678. (::strcpy)(regex, source);
  679. }
  680. public:
  681. Regular_Expression_Field(const char *expr)
  682. : NCursesFieldType(TYPE_REGEXP),
  683. regex(NULL)
  684. {
  685. copy_regex(expr);
  686. }
  687. Regular_Expression_Field& operator=(const Regular_Expression_Field& rhs)
  688. {
  689. if (this != &rhs) {
  690. *this = rhs;
  691. copy_regex(rhs.regex);
  692. NCursesFieldType::operator=(rhs);
  693. }
  694. return *this;
  695. }
  696. Regular_Expression_Field(const Regular_Expression_Field& rhs)
  697. : NCursesFieldType(rhs),
  698. regex(NULL)
  699. {
  700. copy_regex(rhs.regex);
  701. }
  702. ~Regular_Expression_Field() {
  703. delete[] regex;
  704. }
  705. };
  706. class NCURSES_IMPEXP Enumeration_Field : public NCursesFieldType
  707. {
  708. private:
  709. const char** list;
  710. int case_sensitive;
  711. int non_unique_matches;
  712. void set(NCursesFormField& f) {
  713. OnError(::set_field_type(f.get_field(),fieldtype,
  714. list,case_sensitive,non_unique_matches));
  715. }
  716. public:
  717. Enumeration_Field(const char* enums[],
  718. bool case_sens=FALSE,
  719. bool non_unique=FALSE)
  720. : NCursesFieldType(TYPE_ENUM),
  721. list(enums),
  722. case_sensitive(case_sens ? -1 : 0),
  723. non_unique_matches(non_unique ? -1 : 0) {
  724. }
  725. Enumeration_Field& operator=(const Enumeration_Field& rhs)
  726. {
  727. if (this != &rhs) {
  728. *this = rhs;
  729. NCursesFieldType::operator=(rhs);
  730. }
  731. return *this;
  732. }
  733. Enumeration_Field(const Enumeration_Field& rhs)
  734. : NCursesFieldType(rhs),
  735. list(rhs.list),
  736. case_sensitive(rhs.case_sensitive),
  737. non_unique_matches(rhs.non_unique_matches)
  738. {
  739. }
  740. };
  741. class NCURSES_IMPEXP IPV4_Address_Field : public NCursesFieldType
  742. {
  743. private:
  744. void set(NCursesFormField& f) {
  745. OnError(::set_field_type(f.get_field(),fieldtype));
  746. }
  747. public:
  748. IPV4_Address_Field() : NCursesFieldType(TYPE_IPV4) {
  749. }
  750. };
  751. extern "C" {
  752. bool _nc_xx_fld_fcheck(FIELD *, const void*);
  753. bool _nc_xx_fld_ccheck(int c, const void *);
  754. void* _nc_xx_fld_makearg(va_list*);
  755. }
  756. //
  757. // -------------------------------------------------------------------------
  758. // Abstract base class for User-Defined Fieldtypes
  759. // -------------------------------------------------------------------------
  760. //
  761. class NCURSES_IMPEXP UserDefinedFieldType : public NCursesFieldType
  762. {
  763. friend class UDF_Init; // Internal helper to set up statics
  764. private:
  765. // For all C++ defined fieldtypes we need only one generic lowlevel
  766. // FIELDTYPE* element.
  767. static FIELDTYPE* generic_fieldtype;
  768. protected:
  769. // This are the functions required by the low level libforms functions
  770. // to construct a fieldtype.
  771. friend bool _nc_xx_fld_fcheck(FIELD *, const void*);
  772. friend bool _nc_xx_fld_ccheck(int c, const void *);
  773. friend void* _nc_xx_fld_makearg(va_list*);
  774. void set(NCursesFormField& f) {
  775. OnError(::set_field_type(f.get_field(),fieldtype,&f));
  776. }
  777. protected:
  778. // Redefine this function to do a field validation. The argument
  779. // is a reference to the field you should validate.
  780. virtual bool field_check(NCursesFormField& f) = 0;
  781. // Redefine this function to do a character validation. The argument
  782. // is the character to be validated.
  783. virtual bool char_check (int c) = 0;
  784. public:
  785. UserDefinedFieldType() : NCursesFieldType(generic_fieldtype) {
  786. }
  787. };
  788. extern "C" {
  789. bool _nc_xx_next_choice(FIELD*, const void *);
  790. bool _nc_xx_prev_choice(FIELD*, const void *);
  791. }
  792. //
  793. // -------------------------------------------------------------------------
  794. // Abstract base class for User-Defined Fieldtypes with Choice functions
  795. // -------------------------------------------------------------------------
  796. //
  797. class NCURSES_IMPEXP UserDefinedFieldType_With_Choice : public UserDefinedFieldType
  798. {
  799. friend class UDF_Init; // Internal helper to set up statics
  800. private:
  801. // For all C++ defined fieldtypes with choice functions we need only one
  802. // generic lowlevel FIELDTYPE* element.
  803. static FIELDTYPE* generic_fieldtype_with_choice;
  804. // This are the functions required by the low level libforms functions
  805. // to construct a fieldtype with choice functions.
  806. friend bool _nc_xx_next_choice(FIELD*, const void *);
  807. friend bool _nc_xx_prev_choice(FIELD*, const void *);
  808. protected:
  809. // Redefine this function to do the retrieval of the next choice value.
  810. // The argument is a reference to the field tobe examined.
  811. virtual bool next (NCursesFormField& f) = 0;
  812. // Redefine this function to do the retrieval of the previous choice value.
  813. // The argument is a reference to the field tobe examined.
  814. virtual bool previous(NCursesFormField& f) = 0;
  815. public:
  816. UserDefinedFieldType_With_Choice() {
  817. fieldtype = generic_fieldtype_with_choice;
  818. }
  819. };
  820. #endif /* NCURSES_CURSESF_H_incl */