comparison usr/src/cmd/fmli/menu/mfolder.c @ 0:c9caec207d52 b86

Initial porting based on b86
author Koji Uno <koji.uno@sun.com>
date Tue, 02 Jun 2009 18:56:50 +0900
parents
children 1a15d5aaf794
comparison
equal deleted inserted replaced
-1:000000000000 0:c9caec207d52
1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
24
25
26 /*
27 * Copyright (c) 1986 AT&T
28 * All Rights Reserved
29 */
30
31 #ident "@(#)mfolder.c 1.7 05/06/08 SMI" /* SVr4.0 1.2 */
32
33 #include <stdio.h>
34 #include "wish.h"
35 #include "menu.h"
36 #include "menudefs.h"
37 #include "vtdefs.h"
38 #include "terror.h"
39 #include "ctl.h"
40 #include "sizes.h"
41
42 /*
43 * This is a special version of menu_make ( called folder_make ) and
44 * menu_reinit ( called folder_reinit ) that are used soley for
45 * file folder display. Lots of assumptions are made, like that
46 * rows is always specified as 18.
47 */
48
49 menu_id
50 folder_make(num, title, flags, startrow, startcol, menurows, menucols, disp, arg)
51 int num; /* menu number */
52 char *title; /* menu title */
53 unsigned flags; /* menu/vt flags */
54 int startrow; /* start row for the menu frame */
55 int startcol; /* start column for the menu frame */
56 int menurows; /* default menu rows */
57 int menucols; /* default menu cols */
58 struct menu_line (*disp)();
59 char *arg;
60 {
61 register int total; /* total items */
62 register int itemwidth; /* width of longest item */
63 register int descwidth; /* width of longest description */
64 register int menuwidth; /* width of the menu */
65 struct menu_line ml; /* item offset into menu */
66 vt_id vid; /* vt identifier of new frame */
67 int probrows, probcols, probwidth; /* tmp vars */
68 int i_num; /* tmp var */
69 int mflags = flags; /* menu flags (as opposed to vt flags) */
70 char *shrink_folder();
71 bool has_description = FALSE;
72
73 menurows = 18;
74 menucols = 0;
75
76 /*
77 * Determine ITEMWIDTH and DESCRIPTION WIDTH
78 * as well as the TOTAL number of items
79 */
80 itemwidth = descwidth = 0;
81 ml = (*disp)(0, arg);
82 for (total = 0; ml.highlight; ml = (*disp)(++total, arg)) {
83 itemwidth = max(itemwidth, strlen(ml.highlight));
84 if (ml.description) {
85 has_description = TRUE;
86 descwidth = max(descwidth, strlen(ml.description));
87 }
88 }
89
90 if (!total)
91 return((menu_id) FAIL); /* empty menu */
92
93
94 if (has_description) {
95 /*
96 * Now truncate the highlite so that the entire description fits
97 * we only truncate the highlight if there was a description.
98 * If there is no description, we have already truncated the
99 * highlite in the dir_disp.
100 */
101
102 itemwidth = 0;
103
104 for (i_num = 0; i_num < total; i_num++) {
105 ml = (*disp)(i_num, arg);
106 ml.highlight = shrink_folder(ml.highlight,
107 ( COLS - FIXED_COLS - descwidth - 3 ));
108 itemwidth = max(itemwidth, strlen(ml.highlight));
109 }
110 /*
111 * If ANY item has a description, then stay single column,
112 *
113 * width = longest highlight +
114 * longest description +
115 * 3 (for the " - ") +
116 * 2 (for space between text and sides)
117 *
118 */
119 /*
120 * actual rows = min(specified rows,
121 * fittable rows,
122 * needed rows);
123 */
124 for ( ; !fits(flags, menurows, 1); menurows--)
125 ;
126 if (menurows > total)
127 menurows = total;
128 menucols = 1;
129 menuwidth = itemwidth + descwidth + 5;
130
131 /*
132 * if the description is too long, then truncate
133 */
134 for ( ; !fits(flags, menurows, menuwidth); menuwidth--)
135 ;
136
137 }
138 else {
139 /*
140 * determine probable rows, then probable columns
141 *
142 * probable rows = min(specified rows, "fittable" rows)
143 */
144 for (probrows = menurows; !fits(flags, probrows, 1); probrows--)
145 ;
146 probcols = (total / probrows) + (total % probrows ? 1 : 0);
147 probwidth = 1 + probcols * (1 + itemwidth);
148
149 /*
150 * determine actual rows and columns
151 */
152 if (!fits(flags, probrows, probwidth)) {
153 /*
154 * menu not displayable in multi-columns ...
155 *
156 * actual rows = probable rows
157 * actual cols = 1
158 *
159 * truncate the menu if necessary
160 */
161 menurows = probrows;
162 menucols = 1;
163 menuwidth = 2 + itemwidth;
164 for (; !fits(flags, 1, menuwidth); )
165 menuwidth--;
166 }
167 else {
168 /*
169 * actual rows = probable cols == 1 ?
170 * min(specified rows, fittable rows) :
171 * probable rows
172 * actual cols = probable cols
173 */
174 if (probcols == 1) {
175 for ( ; !fits(flags, menurows, 1); menurows--)
176 ;
177 }
178 else
179 menurows = probrows;
180 menucols = probcols;
181 menuwidth = probwidth;
182 }
183
184 /*
185 * Eliminate white-space from unused rows
186 */
187 if (menurows > total)
188 menurows = total;
189 }
190
191 /*
192 * Make sure the menu VT (frame) can house the title
193 * vt_create adds the border cols hence FIXED_TITLE - 2
194 */
195 /* made it FIXED_TITLE -3 to min. testing impact. -2 is better in longterm */
196 menuwidth = max(menuwidth, strlen(title) + FIXED_TITLE - 3);
197
198
199 /*
200 * Create a VT (frame) to house the menu
201 */
202 if ((vid = vt_create(title, flags, startrow, startcol, menurows,
203 menuwidth)) == VT_UNDEFINED)
204 {
205
206 /*
207 * try putting the VT anywhere
208 */
209 vid = vt_create(title, flags, VT_UNDEFINED, VT_UNDEFINED,
210 menurows, menuwidth);
211 }
212 /*
213 * If the menu still can't be displayed then return FAIL
214 */
215 if (vid == VT_UNDEFINED) {
216 mess_temp("Object can not be displayed, frame may be too large for the screen");
217 return((menu_id) FAIL);
218 }
219
220 if (num >= 0)
221 vt_ctl(vid, CTSETWDW, num);
222 return(menu_custom(vid, mflags, menucols, itemwidth, descwidth, total, disp, arg));
223 }
224
225
226 menu_id
227 folder_reinit(mid, flags, menurows, menucols, disp, arg)
228 menu_id mid;
229 unsigned flags;
230 int menurows;
231 int menucols;
232 struct menu_line (*disp)();
233 char *arg;
234 {
235 char *s;
236 register menu_id newmid;
237 register vt_id oldvid;
238 register menu_id oldmid;
239 int top, line;
240
241 oldmid = MNU_curid;
242 oldvid = vt_current(MNU_array[mid].vid);
243 vt_ctl(VT_UNDEFINED, CTGETITLE, &s);
244 newmid = folder_make(vt_ctl(VT_UNDEFINED, CTGETWDW), s,
245 flags | VT_COVERCUR, VT_UNDEFINED, VT_UNDEFINED,
246 menurows, menucols, disp, arg);
247 menu_ctl(mid, CTGETPARMS, &top, &line);
248 menu_close(mid);
249 menu_ctl(newmid, CTSETPARMS, top, line);
250 menu_current(newmid);
251 if (MNU_array[mid].vid != oldvid) {
252 menu_noncurrent();
253 if (oldmid >= 0)
254 menu_current(oldmid);
255 else
256 vt_current(oldvid);
257 }
258 return newmid;
259 }
260
261 /* shrink_folder truncates the provided string so it will fit in a
262 ** window thats the screen width minus reserved_col wide. The
263 ** end of the string is replaced with TRUNCATE_STR to show that
264 ** the string was truncated.
265 ** RETURN VALUE: Pointer to the truncated string.
266 ** SIDE AFFECTS: The string parameter is itself may be modified.
267 ** this routine does not make a copy before truncation.
268 ** If called with the result of a multi_eval, the
269 ** cur field of the attribute will be modified, affecting
270 ** future multi_evals if the descriptor is not
271 ** EVAL_ALWAYS
272 */
273 char *
274 shrink_folder(str, max_len)
275 char *str;
276 int max_len;
277 {
278 if (strlen(str) > max_len)
279 strcpy((str + max_len - 1), ">");
280 return(str);
281 }