ncurses 5.3
[ncurses.git] / menu / m_item_new.c
1 /****************************************************************************
2  * Copyright (c) 1998,2000 Free Software Foundation, Inc.                   *
3  *                                                                          *
4  * Permission is hereby granted, free of charge, to any person obtaining a  *
5  * copy of this software and associated documentation files (the            *
6  * "Software"), to deal in the Software without restriction, including      *
7  * without limitation the rights to use, copy, modify, merge, publish,      *
8  * distribute, distribute with modifications, sublicense, and/or sell       *
9  * copies of the Software, and to permit persons to whom the Software is    *
10  * furnished to do so, subject to the following conditions:                 *
11  *                                                                          *
12  * The above copyright notice and this permission notice shall be included  *
13  * in all copies or substantial portions of the Software.                   *
14  *                                                                          *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
18  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
21  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
22  *                                                                          *
23  * Except as contained in this notice, the name(s) of the above copyright   *
24  * holders shall not be used in advertising or otherwise to promote the     *
25  * sale, use or other dealings in this Software without prior written       *
26  * authorization.                                                           *
27  ****************************************************************************/
28
29 /****************************************************************************
30  *   Author:  Juergen Pfeifer, 1995,1997                                    *
31  *   Contact: http://www.familiepfeifer.de/Contact.aspx?Lang=en             *
32  ****************************************************************************/
33
34 /***************************************************************************
35 * Module m_item_new                                                        *
36 * Create and destroy menu items                                            *
37 * Set and get marker string for menu                                       *
38 ***************************************************************************/
39
40 #include "menu.priv.h"
41
42 MODULE_ID("$Id: m_item_new.c,v 1.13 2002/07/06 15:22:16 juergen Exp $")
43
44 /*---------------------------------------------------------------------------
45 |   Facility      :  libnmenu  
46 |   Function      :  bool Is_Printable_String(const char *s)
47 |   
48 |   Description   :  Checks whether or not the string contains only printable
49 |                    characters.
50 |
51 |   Return Values :  TRUE     - if string is printable
52 |                    FALSE    - if string contains non-printable characters
53 +--------------------------------------------------------------------------*/
54 static bool Is_Printable_String(const char *s)
55 {
56   assert(s);
57   while(*s)
58     {
59       if (!isprint((unsigned char)*s))
60         return FALSE;
61       s++;
62     }
63   return TRUE;
64 }
65
66 /*---------------------------------------------------------------------------
67 |   Facility      :  libnmenu  
68 |   Function      :  ITEM *new_item(char *name, char *description)
69 |   
70 |   Description   :  Create a new item with name and description. Return
71 |                    a pointer to this new item.
72 |                    N.B.: an item must(!) have a name.
73 |
74 |   Return Values :  The item pointer or NULL if creation failed.
75 +--------------------------------------------------------------------------*/
76 NCURSES_EXPORT(ITEM *)
77 new_item (const char *name, const char *description)
78 {
79   ITEM *item;
80   
81   if ( !name || (*name == '\0') || !Is_Printable_String(name) )
82     {
83       item = (ITEM *)0;
84       SET_ERROR( E_BAD_ARGUMENT );
85     }
86   else
87     {
88       item = (ITEM *)calloc(1,sizeof(ITEM));
89       if (item)
90         {
91           *item  = _nc_Default_Item; /* hope we have struct assignment */
92           
93           item->name.length        = strlen(name);
94           item->name.str           = name;
95
96           if (description && (*description != '\0') && 
97               Is_Printable_String(description))
98             {
99               item->description.length = strlen(description);         
100               item->description.str    = description;
101             }
102           else
103             {
104               item->description.length = 0;
105               item->description.str    = (char *)0;
106             }
107         }
108       else
109         SET_ERROR( E_SYSTEM_ERROR );
110     }  
111   return(item);
112 }
113
114 /*---------------------------------------------------------------------------
115 |   Facility      :  libnmenu  
116 |   Function      :  int free_item(ITEM *item)
117 |   
118 |   Description   :  Free the allocated storage for this item. 
119 |                    N.B.: a connected item can't be freed.
120 |
121 |   Return Values :  E_OK              - success
122 |                    E_BAD_ARGUMENT    - invalid value has been passed
123 |                    E_CONNECTED       - item is still connected to a menu    
124 +--------------------------------------------------------------------------*/
125 NCURSES_EXPORT(int)
126 free_item (ITEM * item)
127 {
128   if (!item)
129     RETURN( E_BAD_ARGUMENT );
130
131   if (item->imenu)
132     RETURN( E_CONNECTED );
133   
134   free(item);
135
136   RETURN( E_OK );
137 }
138
139 /*---------------------------------------------------------------------------
140 |   Facility      :  libnmenu  
141 |   Function      :  int set_menu_mark( MENU *menu, const char *mark )
142 |   
143 |   Description   :  Set the mark string used to indicate the current
144 |                    item (single-valued menu) or the selected items
145 |                    (multi-valued menu).
146 |                    The mark argument may be NULL, in which case no 
147 |                    marker is used.
148 |                    This might be a little bit tricky, because this may 
149 |                    affect the geometry of the menu, which we don't allow 
150 |                    if it is already posted.
151 |
152 |   Return Values :  E_OK               - success
153 |                    E_BAD_ARGUMENT     - an invalid value has been passed
154 |                    E_SYSTEM_ERROR     - no memory to store mark
155 +--------------------------------------------------------------------------*/
156 NCURSES_EXPORT(int)
157 set_menu_mark (MENU * menu, const char * mark)
158 {
159   int l;
160
161   if ( mark && (*mark != '\0') && Is_Printable_String(mark) )
162     l = strlen(mark);
163   else
164     l = 0;
165
166   if ( menu )
167     {
168       char *old_mark = menu->mark;
169       unsigned short old_status = menu->status;
170
171       if (menu->status & _POSTED)
172         {
173           /* If the menu is already posted, the geometry is fixed. Then
174              we can only accept a mark with exactly the same length */
175           if (menu->marklen != l) 
176             RETURN(E_BAD_ARGUMENT);
177         }       
178       menu->marklen = l;
179       if (l)
180         {
181           menu->mark = (char *)malloc(l+1);
182           if (menu->mark)
183             {
184               strcpy(menu->mark, mark);
185               if (menu != &_nc_Default_Menu)
186                 menu->status |= _MARK_ALLOCATED;
187             }
188           else
189             {
190               menu->mark = old_mark;
191               RETURN(E_SYSTEM_ERROR);
192             }
193         }
194       else
195         menu->mark = (char *)0;
196       
197       if ((old_status & _MARK_ALLOCATED) && old_mark)
198         free(old_mark);
199
200       if (menu->status & _POSTED)
201         {
202           _nc_Draw_Menu( menu );
203           _nc_Show_Menu( menu );
204         }
205       else
206         {
207           /* Recalculate the geometry */
208           _nc_Calculate_Item_Length_and_Width( menu );                  
209         }
210     }
211   else
212     {
213       return set_menu_mark(&_nc_Default_Menu, mark);
214     }
215   RETURN(E_OK);
216 }
217
218 /*---------------------------------------------------------------------------
219 |   Facility      :  libnmenu  
220 |   Function      :  char *menu_mark(const MENU *menu)
221 |   
222 |   Description   :  Return a pointer to the marker string
223 |
224 |   Return Values :  The marker string pointer or NULL if no marker defined
225 +--------------------------------------------------------------------------*/
226 NCURSES_EXPORT(const char *)
227 menu_mark (const MENU * menu)
228 {
229   return Normalize_Menu( menu )->mark;
230 }
231
232 /* m_item_new.c */