Gentoo Archives: gentoo-commits

From: Sven Eden <sven.eden@×××.de>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/ufed:master commit in: /
Date: Fri, 01 Feb 2013 10:50:13
Message-Id: 1359656698.da9fd3adf9e5aa3c3b8f99aa99535ab95efd9e2f.yamakuzure@gentoo
1 commit: da9fd3adf9e5aa3c3b8f99aa99535ab95efd9e2f
2 Author: Sven Eden <sven.eden <AT> gmx <DOT> de>
3 AuthorDate: Thu Jan 31 18:24:58 2013 +0000
4 Commit: Sven Eden <sven.eden <AT> gmx <DOT> de>
5 CommitDate: Thu Jan 31 18:24:58 2013 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/ufed.git;a=commit;h=da9fd3ad
7
8 Changed ufed-curses.c to support the new data model and added the implementation of the new drawing functions.
9
10 ---
11 ufed-curses.c | 756 ++++++++++++++++++++++++++++++---------------------------
12 1 files changed, 403 insertions(+), 353 deletions(-)
13
14 diff --git a/ufed-curses.c b/ufed-curses.c
15 index f45b8e3..bc55ca1 100644
16 --- a/ufed-curses.c
17 +++ b/ufed-curses.c
18 @@ -6,61 +6,47 @@
19 #include <unistd.h>
20 #include <locale.h>
21
22 -/* internal types */
23 -struct window window[wCount] = {
24 - { NULL, 0, 0, 5, 0 }, /* Top */
25 - { NULL, 5, 0, -8, 3 }, /* Left */
26 - { NULL, 5, 3, -9, -6 }, /* List */
27 - { NULL, -4, 3, 1, -6 }, /* Input */
28 - { NULL, 5, -3, -8, 1 }, /* Scrollbar */
29 - { NULL, 5, -2, -8, 2 }, /* Right */
30 - { NULL, -3, 0, 3, 0 }, /* Bottom */
31 -};
32 -
33 -
34 /* internal members */
35 -static const char *subtitle;
36 -static const struct key *keys;
37 -static struct item *items, *currentitem;
38 +static const char* subtitle = NULL;
39 +static const sKey* keys = NULL;
40 +static sFlag* currentflag = NULL;
41 +static sFlag* flags = NULL;
42 +
43 // Needed for the scrollbar and its mouse events
44 static int listHeight, barStart, barEnd, dispStart, dispEnd;
45
46
47 /* external members */
48 -int topline, bottomline, minwidth;
49 -extern enum mask showMasked;
50 -extern enum order pkgOrder;
51 -extern enum scope showScope;
52 -extern int lineCountGlobal;
53 -extern int lineCountGlobalInstalled;
54 -extern int lineCountLocal;
55 -extern int lineCountLocalInstalled;
56 -extern int lineCountMasked;
57 -extern int lineCountMaskedInstalled;
58 -extern int lineCountMasked;
59 +sWindow window[wCount] = {
60 + { NULL, 0, 0, 5, 0 }, /* Top --- Top ---- */
61 + { NULL, 5, 0, -8, 3 }, /* Left L+------+S|R */
62 + { NULL, 5, 3, -9, -6 }, /* List E| |c|i */
63 + { NULL, -4, 3, 1, -6 }, /* Input F| List |r|g */
64 + { NULL, 5, -3, -8, 1 }, /* Scrollbar T|______|B|h */
65 + { NULL, 5, -2, -8, 2 }, /* Right |+Input-+r|t */
66 + { NULL, -3, 0, 3, 0 }, /* Bottom ---Bottom--- */
67 +};
68 +int topline = 0, bottomline = 0, minwidth = 0;
69 +extern eMask e_mask;
70 +extern eOrder e_order;
71 +extern eScope e_scope;
72 +extern eState e_state;
73 +extern sListStats listStats;
74
75
76 /* internal prototypes */
77 -int (*callback)(struct item **, int);
78 -int (*drawitem)(struct item *, bool);
79 +static int (*callback)(sFlag**, int);
80 +static int (*drawflag)(sFlag*, bool);
81 void checktermsize(void);
82 -void draw(void);
83 -void drawscrollbar(void);
84 +void draw(bool withSep);
85 +void drawScrollbar(void);
86 int getListHeight(void);
87 -void resetDisplay(void);
88 +void resetDisplay(bool withSep);
89 void setNextItem(int count, bool strict);
90 void setPrevItem(int count, bool strict);
91
92
93 /* internal functions */
94 -/** @brief return the number of lines the full item display needs
95 -**/
96 -int getItemHeight(struct item *item)
97 -{
98 - // TODO : Add filtering and possible line break
99 - return item->ndescr;
100 -}
101 -
102
103 /** @brief get the sum of lines the list holds respecting current filtering
104 **/
105 @@ -68,19 +54,28 @@ int getListHeight()
106 {
107 int result = 0;
108
109 - if (show_unmasked != showMasked) {
110 - // TODO : add installed/not installed filter
111 - result += lineCountMasked + lineCountMaskedInstalled;
112 + // Add masked lines
113 + if (eMask_masked != e_mask) {
114 + if (eState_installed != e_state)
115 + result += listStats.lineCountMasked;
116 + if (eState_notinstalled != e_state)
117 + result += listStats.lineCountMaskedInstalled;
118 }
119 - if (show_masked != showMasked) {
120 - if (show_global != showScope) {
121 - // TODO : add installed/not installed filter
122 - result += lineCountLocal + lineCountLocalInstalled;
123 - }
124 - if (show_local != showScope) {
125 - // TODO : add installed/not installed filter
126 - result += lineCountGlobal + lineCountGlobalInstalled;
127 - }
128 +
129 + // Add global lines
130 + if (eScope_local != e_scope) {
131 + if (eState_installed != e_state)
132 + result += listStats.lineCountGlobal;
133 + if (eState_notinstalled != e_state)
134 + result += listStats.lineCountGlobalInstalled;
135 + }
136 +
137 + // Add local lines
138 + if (eScope_global != e_scope) {
139 + if (eState_installed != e_state)
140 + result += listStats.lineCountLocal;
141 + if (eState_notinstalled != e_state)
142 + result += listStats.lineCountLocalInstalled;
143 }
144
145 return result;
146 @@ -103,14 +98,14 @@ void initcurses() {
147 mousemask(BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED | BUTTON1_PRESSED | BUTTON1_RELEASED, NULL);
148 #endif
149 checktermsize();
150 - { enum win w; for(w = (enum win) 0; w != wCount; w++) {
151 + { eWin w; for(w = (eWin) 0; w != wCount; w++) {
152 window[w].win = newwin(wHeight(w), wWidth(w), wTop(w), wLeft(w));
153 } }
154 }
155
156 void cursesdone() {
157 - enum win w;
158 - for(w = (enum win) 0; w != wCount; w++)
159 + eWin w;
160 + for(w = (eWin) 0; w != wCount; w++)
161 delwin(window[w].win);
162 endwin();
163 }
164 @@ -124,77 +119,142 @@ void checktermsize() {
165 mvaddstr(0, 0, "Your screen is too small. Press Ctrl+C to exit.");
166 while(getch()!=KEY_RESIZE) {}
167 #else
168 - cursesdone();
169 - fputs("Your screen is too small.\n", stderr);
170 - exit(-1);
171 + ERROR_EXIT(-1, "The following error occurred:\n\"%2\n\"",
172 + "Your screen is too small.\n")
173 #endif
174 }
175 }
176
177 -void drawitems() {
178 +
179 +/** @brief redraw Bottom with or without status separators
180 + * The window is not fully refreshed!
181 + * @param withSep Draw status separators and filter status if true.
182 + */
183 +void drawBottom(bool withSep)
184 +{
185 + WINDOW* w = win(Bottom);
186 +
187 + wattrset(w, COLOR_PAIR(2) | A_BOLD);
188 + mvwaddch(w, 0, 0, ACS_VLINE);
189 + wattrset(w, COLOR_PAIR(3));
190 + waddch(w, ' ');
191 + waddch(w, ACS_LLCORNER);
192 + whline(w, ACS_HLINE, wWidth(Bottom)-6);
193 + if (withSep) {
194 + mvwaddch(w, 0, minwidth + 3, ACS_BTEE); // Before state
195 + mvwaddch(w, 0, minwidth + 7, ACS_BTEE); // Between state and scope
196 + mvwaddch(w, 0, minwidth + 10, ACS_BTEE); // After scope
197 + }
198 + mvwaddch(w, 0, wWidth(Bottom)-3, ACS_LRCORNER);
199 + waddch(w, ' ');
200 + wattrset(w, COLOR_PAIR(2) | A_BOLD);
201 + waddch(w, ACS_VLINE);
202 +
203 + waddch(w, ACS_VLINE);
204 + wattrset(w, COLOR_PAIR(3));
205 + if (keys) {
206 + char buf[COLS + 1];
207 + char *p = buf;
208 + const sKey* key;
209 + const size_t maxAdr = (const size_t)(buf+wWidth(Bottom)-3);
210 + *p++ = ' ';
211 + for(key=keys; key->key!='\0'; key++) {
212 + size_t n = maxAdr - (size_t)p;
213 + if(n > key->length)
214 + n = key->length;
215 + memcpy(p, key->descr, n);
216 + p += n;
217 + if ((size_t)p == maxAdr)
218 + break;
219 + *p++ = ' ';
220 + }
221 + memset(p, ' ', maxAdr + 1 - (size_t)p);
222 + buf[wWidth(Bottom)-2] = '\0';
223 + waddstr(w, buf);
224 + } else
225 + whline(w, ' ', wWidth(Bottom) - 3);
226 +
227 + wattrset(w, COLOR_PAIR(2) | A_BOLD);
228 + waddch(w, ACS_VLINE);
229 +
230 + waddch(w, ACS_LLCORNER);
231 + whline(w, ACS_HLINE, wWidth(Bottom)-2);
232 + mvwhline(w, 2, wWidth(Bottom)-1, ACS_LRCORNER, 1);
233 +
234 + wnoutrefresh(w);
235 +}
236 +
237 +
238 +void drawFlags() {
239 + int lHeight = wHeight(List);
240 +
241 /* this method must not be called if the current
242 * item is not valid.
243 */
244 - if (!isLegalItem(currentitem))
245 + if (!isFlagLegal(currentflag))
246 ERROR_EXIT(-1,
247 - "drawitems() must not be called with a filtered currentitem! (topline %d listline %d)\n",
248 - topline, currentitem->listline)
249 + "drawflags() must not be called with a filtered currentflag! (topline %d listline %d)\n",
250 + topline, currentflag->listline)
251
252 - struct item *item = currentitem;
253 - int line = item->listline - topline;
254 + sFlag* flag = currentflag;
255 +
256 + int line = flag->listline - topline;
257
258 /* move to the top of the displayed list */
259 - while ((item != items) && (line > 0)) {
260 - item = item->prev;
261 - if (isLegalItem(item))
262 - line -= getItemHeight(item);
263 + while ((flag != flags) && (line > 0)) {
264 + flag = flag->prev;
265 + if (isFlagLegal(flag))
266 + line -= getFlagHeight(flag);
267 }
268
269 - /* If the above move ended up with item == items
270 + /* If the above move ended up with flag == flags
271 * topline and line must be adapted to the current
272 - * item.
273 + * flag.
274 * This can happen if the flag filter is toggled
275 - * and the current item is the first not filtered item.
276 + * and the current flag is the first not filtered.
277 */
278 - if ((item == items) && !isLegalItem(item)) {
279 - item = currentitem;
280 - topline = currentitem->listline;
281 + if ((flag == flags) && !isFlagLegal(flag)) {
282 + flag = currentflag;
283 + topline = currentflag->listline;
284 line = 0;
285 }
286
287 // The display start line might differ from topline:
288 - dispStart = item->listline;
289 + dispStart = flag->listline;
290
291 - for( ; line < wHeight(List); ) {
292 - item->currline = line; // drawitem() and maineventloop() need this
293 - line += drawitem(item, item == currentitem ? TRUE : FALSE);
294 + for( ; line < lHeight; ) {
295 + flag->currline = line; // drawflag() and maineventloop() need this
296 + line += drawflag(flag, flag == currentflag ? TRUE : FALSE);
297
298 - if (line < wHeight(List)) {
299 - item = item->next;
300 + if (line < lHeight) {
301 + flag = flag->next;
302
303 /* Add blank lines if we reached the end of the
304 * flag list, but not the end of the display.
305 */
306 - if(item == items) {
307 - char buf[wWidth(List)];
308 - memset(buf, ' ', wWidth(List));
309 - buf[wWidth(List)] = '\0';
310 + if(flag == flags) {
311 + int lWidth = wWidth(List);
312 + char buf[lWidth];
313 + memset(buf, ' ', lWidth);
314 + buf[lWidth] = '\0';
315 wmove(win(List), line, 0);
316 wattrset(win(List), COLOR_PAIR(3));
317 - while(line++ < wHeight(List))
318 + while(line++ < lHeight)
319 waddstr(win(List), buf);
320 }
321 } else
322 - dispEnd = item->listline + item->ndescr;
323 + dispEnd = flag->listline + flag->ndesc;
324 }
325 wnoutrefresh(win(List));
326 }
327
328 -void drawscrollbar() {
329 +void drawScrollbar() {
330 + int sHeight = wHeight(Scrollbar);
331 + int lHeight = wHeight(List);
332 WINDOW *w = win(Scrollbar);
333 wattrset(w, COLOR_PAIR(3) | A_BOLD);
334 mvwaddch(w, 0, 0, ACS_UARROW);
335 - wvline(w, ACS_CKBOARD, wHeight(Scrollbar)-3);
336 + wvline(w, ACS_CKBOARD, sHeight - 3);
337
338 /* The scrollbar location differs related to the
339 * current filtering of masked flags.
340 @@ -202,10 +262,10 @@ void drawscrollbar() {
341 listHeight = getListHeight();
342
343 // Only show a scrollbar if the list is actually longer than can be displayed:
344 - if (listHeight > wHeight(List)) {
345 - int sbHeight = wHeight(Scrollbar) - 3;
346 + if (listHeight > lHeight) {
347 + int sbHeight = sHeight - 3;
348 barStart = 1 + (dispStart * sbHeight / bottomline);
349 - barEnd = barStart + ((dispEnd - dispStart) * wHeight(List) / bottomline);
350 + barEnd = barStart + ((dispEnd - dispStart) * lHeight / bottomline);
351
352 // Strongly filtered lists scatter much and must be corrected:
353 if (barEnd > sbHeight) {
354 @@ -216,19 +276,62 @@ void drawscrollbar() {
355 mvwaddch(w, barStart, 0, ACS_BLOCK);
356 }
357
358 - mvwaddch(w, wHeight(Scrollbar)-2, 0, ACS_DARROW);
359 - mvwaddch(w, wHeight(Scrollbar)-1, 0, ACS_VLINE);
360 + mvwaddch(w, sHeight - 2, 0, ACS_DARROW);
361 + mvwaddch(w, sHeight - 1, 0, ACS_VLINE);
362 wnoutrefresh(w);
363 }
364
365 -void draw() {
366 - size_t bufsize = COLS+1;
367 - char buf[bufsize];
368 - WINDOW *w;
369
370 - wnoutrefresh(stdscr);
371 +/** @brief redraw Input with blank input and current status if @a withSep is true
372 + * This function resets the cursor to 0,0.
373 + * The window is not fully refreshed!
374 + * @param withSep Draw status separators and filter status if true.
375 + */
376 +void drawStatus(bool withSep)
377 +{
378 + WINDOW* w = win(Input);
379 + int iWidth = wWidth(Input);
380 +
381 + wattrset(w, COLOR_PAIR(3));
382 +
383 + // Blank the input area
384 + mvwhline(w, 0, 0, ' ', withSep ? minwidth : iWidth);
385 +
386 + if (withSep) {
387 + char buf[COLS+1];
388 +
389 + // Add Status separators and explenation characters
390 + mvwaddstr(w, 0, minwidth, " DPC Si");
391 + mvwaddch(w, 0, minwidth, ACS_VLINE); // Before state
392 + mvwaddch(w, 0, minwidth + 4, ACS_VLINE); // Between state and scope
393 + mvwaddch(w, 0, minwidth + 7, ACS_VLINE); // After scope
394 +
395 + // Use the unused right side to show the filter status
396 + sprintf(buf, "%-*s%-6s / %-6s / %-12s] ",
397 + max(2, iWidth - 40 - minwidth), " [",
398 + eMask_masked == e_mask ? "masked" :
399 + eMask_unmasked == e_mask ? "normal" : "all",
400 + eScope_global == e_scope ? "global" :
401 + eScope_local == e_scope ? "local" : "all",
402 + eState_installed == e_state ? "installed" :
403 + eState_notinstalled == e_state ? "not installed" : "all");
404 + waddstr(w, buf);
405 + }
406 +
407 + // Reset cursor to 0,0 and apply changes
408 + wmove(w, 0, 0);
409 + wnoutrefresh(w);
410 +}
411 +
412
413 - w = win(Top);
414 +/** @brief redraw Top with or without status separators
415 + * The window is not fully refreshed!
416 + * @param withSep Draw status separators and filter status if true.
417 + */
418 +void drawTop(bool withSep)
419 +{
420 + WINDOW* w = win(Top);
421 + char buf[COLS + 1];
422
423 wattrset(w, COLOR_PAIR(1) | A_BOLD);
424 sprintf(buf, "%-*.*s", wWidth(Top), wWidth(Top), "Gentoo USE flags editor " PACKAGE_VERSION);
425 @@ -248,23 +351,37 @@ void draw() {
426 wattrset(w, COLOR_PAIR(2) | A_BOLD);
427 waddch(w, ACS_VLINE);
428
429 - /* maybe this should be based on List? */
430 + /* maybe this should be based on List?
431 + * A: Absolutely not, or every line drawing algorithm
432 + * had to be rewritten to cover the offsets. - Sven
433 + */
434 waddch(w, ACS_VLINE);
435 wattrset(w, COLOR_PAIR(3));
436 waddch(w, ' ');
437 waddch(w, ACS_ULCORNER);
438 whline(w, ACS_HLINE, wWidth(Top)-6);
439 - mvwaddch(w, 4, minwidth + 3, ACS_TTEE); // Before state
440 - mvwaddch(w, 4, minwidth + 6, ACS_TTEE); // Between state and scope
441 - mvwaddch(w, 4, minwidth + 9, ACS_TTEE); // After scope
442 + if (withSep) {
443 + mvwaddch(w, 4, minwidth + 3, ACS_TTEE); // Before state
444 + mvwaddch(w, 4, minwidth + 7, ACS_TTEE); // Between state and scope
445 + mvwaddch(w, 4, minwidth + 10, ACS_TTEE); // After scope
446 + }
447 mvwaddch(w, 4, wWidth(Top)-3, ACS_URCORNER);
448 waddch(w, ' ');
449 wattrset(w, COLOR_PAIR(2) | A_BOLD);
450 waddch(w, ACS_VLINE);
451
452 wnoutrefresh(w);
453 +}
454 +
455 +
456 +/** @brief redraw the whole screen
457 + * @param withSep draw status separators if set to true
458 + */
459 +void draw(bool withSep) {
460 + WINDOW *w = win(Left);
461 +
462 + wnoutrefresh(stdscr);
463
464 - w = win(Left);
465 wattrset(w, COLOR_PAIR(2) | A_BOLD);
466 mvwvline(w, 0, 0, ACS_VLINE, wHeight(Left));
467 wattrset(w, COLOR_PAIR(3));
468 @@ -278,176 +395,116 @@ void draw() {
469 mvwvline(w, 0, 1, ACS_VLINE, wHeight(Right));
470 wnoutrefresh(w);
471
472 - w = win(Bottom);
473 -
474 - wattrset(w, COLOR_PAIR(2) | A_BOLD);
475 - mvwaddch(w, 0, 0, ACS_VLINE);
476 - wattrset(w, COLOR_PAIR(3));
477 - waddch(w, ' ');
478 - waddch(w, ACS_LLCORNER);
479 - whline(w, ACS_HLINE, wWidth(Bottom)-6);
480 - mvwaddch(w, 0, minwidth + 3, ACS_BTEE); // Before state
481 - mvwaddch(w, 0, minwidth + 6, ACS_BTEE); // Between state and scope
482 - mvwaddch(w, 0, minwidth + 9, ACS_BTEE); // After scope
483 - mvwaddch(w, 0, wWidth(Bottom)-3, ACS_LRCORNER);
484 - waddch(w, ' ');
485 - wattrset(w, COLOR_PAIR(2) | A_BOLD);
486 - waddch(w, ACS_VLINE);
487 + drawTop(withSep);
488 + drawBottom(withSep);
489 + drawStatus(withSep);
490
491 - waddch(w, ACS_VLINE);
492 - wattrset(w, COLOR_PAIR(3));
493 - {
494 - char *p = buf;
495 - const struct key *key;
496 - const size_t maxAdr = (const size_t)(buf+wWidth(Bottom)-3);
497 - *p++ = ' ';
498 - for(key=keys; key->key!='\0'; key++) {
499 - size_t n = maxAdr - (size_t)p;
500 - if(n > key->length)
501 - n = key->length;
502 - memcpy(p, key->descr, n);
503 - p += n;
504 - if ((size_t)p == maxAdr)
505 - break;
506 - *p++ = ' ';
507 - }
508 - /* If there is enough space, show which kind of flags
509 - * are displayed: normal, masked or all
510 - */
511 - if ((size_t)p < (maxAdr - 9)) {
512 - memset(p, ' ', maxAdr - 9 - (size_t)p);
513 - p += maxAdr - 9 - (size_t)p;
514 - if (show_unmasked == showMasked) strcpy(p, "[normal]");
515 - if (show_masked == showMasked) strcpy(p, "[masked]");
516 - if (show_both == showMasked) strcpy(p, "[ all ]");
517 - p += 8;
518 - }
519 - memset(p, ' ', maxAdr + 1 - (size_t)p);
520 - buf[wWidth(Bottom)-2] = '\0';
521 + if (flags) {
522 + drawFlags();
523 + drawScrollbar();
524 }
525 - waddstr(w, buf);
526 - wattrset(w, COLOR_PAIR(2) | A_BOLD);
527 - waddch(w, ACS_VLINE);
528 -
529 - waddch(w, ACS_LLCORNER);
530 - whline(w, ACS_HLINE, wWidth(Bottom)-2);
531 - mvwhline(w, 2, wWidth(Bottom)-1, ACS_LRCORNER, 1);
532 -
533 - wnoutrefresh(w);
534 -
535 - w = win(Input);
536 - wattrset(w, COLOR_PAIR(3));
537 - mvwhline(w, 0, 0, ' ', wWidth(Input));
538 - mvwaddch(w, 0, minwidth, ACS_VLINE); // Before state
539 - mvwaddch(w, 0, minwidth + 3, ACS_VLINE); // Between state and scope
540 - mvwaddch(w, 0, minwidth + 6, ACS_VLINE); // After scope
541 - wmove(w, 0, 0);
542 - wnoutrefresh(w);
543 -
544 - drawitems();
545 - drawscrollbar();
546
547 wrefresh(win(List));
548 }
549
550 bool scrollcurrent() {
551 - if(currentitem->listline < topline)
552 - topline = max(currentitem->listline, currentitem->listline + currentitem->ndescr - wHeight(List));
553 - else if( (currentitem->listline + currentitem->ndescr) > (topline + wHeight(List)))
554 - topline = min(currentitem->listline + currentitem->ndescr - wHeight(List), currentitem->listline);
555 + if(currentflag->listline < topline)
556 + topline = max(currentflag->listline, currentflag->listline + currentflag->ndesc - wHeight(List));
557 + else if( (currentflag->listline + currentflag->ndesc) > (topline + wHeight(List)))
558 + topline = min(currentflag->listline + currentflag->ndesc - wHeight(List), currentflag->listline);
559 else
560 return false;
561 - drawitems();
562 - drawscrollbar();
563 + drawFlags();
564 + drawScrollbar();
565 return true;
566 }
567
568 bool yesno(const char *prompt) {
569 - wattrset(win(Input), COLOR_PAIR(4) | A_BOLD | A_REVERSE);
570 - mvwhline(win(Input), 0, 0, ' ', wWidth(Input));
571 - mvwaddch(win(Input), 0, minwidth, ACS_VLINE); // Before state
572 - mvwaddch(win(Input), 0, minwidth + 3, ACS_VLINE); // Between state and scope
573 - mvwaddch(win(Input), 0, minwidth + 6, ACS_VLINE); // After scope
574 - wmove(win(Input), 0, 0);
575 - waddstr(win(Input), prompt);
576 - whline(win(Input), 'Y', 1);
577 - wrefresh(win(Input));
578 - for(;;) switch(getch()) {
579 - case '\n': case KEY_ENTER:
580 - case 'Y': case 'y':
581 - return TRUE;
582 - case '\033':
583 - case 'N': case 'n':
584 - wattrset(win(Input), COLOR_PAIR(3));
585 - mvwhline(win(Input), 0, 0, ' ', wWidth(Input));
586 - mvwaddch(win(Input), 0, minwidth, ACS_VLINE); // Before state
587 - mvwaddch(win(Input), 0, minwidth + 3, ACS_VLINE); // Between state and scope
588 - mvwaddch(win(Input), 0, minwidth + 6, ACS_VLINE); // After scope
589 - wmove(win(Input), 0, 0);
590 - wnoutrefresh(win(Input));
591 - wrefresh(win(List));
592 - return FALSE;
593 + WINDOW* wInp = win(Input);
594 + bool doWait = true;
595 + bool result = true;
596 +
597 + drawStatus(true);
598 + wattrset(wInp, COLOR_PAIR(4) | A_BOLD);
599 + waddstr(wInp, prompt);
600 + waddch(wInp, 'Y');
601 + wrefresh(wInp);
602 +
603 + while(doWait) {
604 + switch(getch()) {
605 + case '\n': case KEY_ENTER:
606 + case 'Y': case 'y':
607 + doWait = false;
608 + break;
609 + case '\033':
610 + case 'N': case 'n':
611 + drawStatus(true);
612 + wrefresh(wInp);
613 + result = false;
614 + doWait = false;
615 + break;
616 #ifdef KEY_RESIZE
617 case KEY_RESIZE:
618 resizeterm(LINES, COLS);
619 checktermsize();
620 - { enum win w; for(w = (enum win) 0; w != wCount; w++) {
621 + { eWin w; for(w = (eWin) 0; w != wCount; w++) {
622 delwin(window[w].win);
623 window[w].win = newwin(wHeight(w), wWidth(w), wTop(w), wLeft(w));
624 } }
625 +
626 /* this won't work for the help viewer, but it doesn't use yesno() */
627 topline = 0;
628 scrollcurrent();
629 - draw();
630 - wattrset(win(Input), COLOR_PAIR(4) | A_BOLD | A_REVERSE);
631 - mvwhline(win(Input), 0, 0, ' ', wWidth(Input));
632 - mvwaddch(win(Input), 0, minwidth, ACS_VLINE); // Before state
633 - mvwaddch(win(Input), 0, minwidth + 3, ACS_VLINE); // Between state and scope
634 - mvwaddch(win(Input), 0, minwidth + 6, ACS_VLINE); // After scope
635 - wmove(win(Input), 0, 0);
636 - waddstr(win(Input), prompt);
637 - whline(win(Input), 'Y', 1);
638 - wrefresh(win(Input));
639 + draw(true); // Only used outside help view.
640 + wattrset(wInp, COLOR_PAIR(4) | A_BOLD);
641 + waddstr(wInp, prompt);
642 + waddch (wInp, 'Y');
643 + wrefresh(wInp);
644 break;
645 #endif
646 + }
647 }
648 - return FALSE;
649 +
650 + return result;
651 }
652
653 int maineventloop(
654 const char *_subtitle,
655 - int(*_callback)(struct item **, int),
656 - int(*_drawitem)(struct item *, bool),
657 - struct item *_items,
658 - const struct key *_keys) {
659 + int(*_callback)(sFlag**, int),
660 + int(*_drawflag)(sFlag*, bool),
661 + sFlag* _flags,
662 + const sKey *_keys,
663 + bool withSep) {
664 int result;
665
666 // Always reset the Filters on start and revert on exit
667 - enum mask oldMask = showMasked;
668 - enum scope oldScope = showScope;
669 - showMasked = show_unmasked;
670 - showScope = show_all;
671 + eMask oldMask = e_mask;
672 + eScope oldScope = e_scope;
673 + eState oldState = e_state;
674 + e_mask = eMask_unmasked;
675 + e_scope = eScope_all;
676 + e_state = eState_all;
677
678 { const char *temp = subtitle;
679 - subtitle=_subtitle;
680 - _subtitle=temp; }
681 - { int(*temp)(struct item **, int) = callback;
682 - callback=_callback;
683 - _callback=temp; }
684 - { int(*temp)(struct item *, bool) = drawitem;
685 - drawitem=_drawitem;
686 - _drawitem=temp; }
687 - { struct item *temp=items;
688 - items=_items;
689 - _items=temp; }
690 - { const struct key *temp=keys;
691 - keys=_keys;
692 - _keys=temp; }
693 -
694 - currentitem = items;
695 + subtitle = _subtitle;
696 + _subtitle = temp; }
697 + { int(*temp)(sFlag**, int) = callback;
698 + callback = _callback;
699 + _callback = temp; }
700 + { int(*temp)(sFlag*, bool) = drawflag;
701 + drawflag = _drawflag;
702 + _drawflag = temp; }
703 + { sFlag* temp = flags;
704 + flags = _flags;
705 + _flags = temp; }
706 + { const sKey *temp = keys;
707 + keys = _keys;
708 + _keys = temp; }
709 +
710 + currentflag = flags;
711 topline = 0;
712
713 - draw();
714 + draw(withSep);
715
716 for(;;) {
717 int c = getch();
718 @@ -476,27 +533,27 @@ int maineventloop(
719 }
720 if(wmouse_trafo(win(List), &event.y, &event.x, FALSE)) {
721 if(event.bstate & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED)) {
722 - struct item *item = currentitem;
723 - if(currentitem->currline > event.y) {
724 - do item = item->prev;
725 - while((item==items ? item=NULL, 0 : 1)
726 - && item->currline > event.y);
727 - } else if(currentitem->currline + getItemHeight(currentitem) - 1 < event.y) {
728 - do item = item->next;
729 - while((item->next==items ? item=NULL, 0 : 1)
730 - && item->currline + getItemHeight(item) - 1 < event.y);
731 + sFlag* flag = currentflag;
732 + if(currentflag->currline > event.y) {
733 + do flag = flag->prev;
734 + while((flag == flags ? flag = NULL, 0 : 1)
735 + && flag->currline > event.y);
736 + } else if(currentflag->currline + getFlagHeight(currentflag) - 1 < event.y) {
737 + do flag = flag->next;
738 + while((flag->next == flags ? flag = NULL, 0 : 1)
739 + && flag->currline + getFlagHeight(flag) - 1 < event.y);
740 }
741 - if(item==NULL)
742 + if(flag == NULL)
743 continue;
744 - drawitem(currentitem, FALSE);
745 - currentitem = item;
746 + drawflag(currentflag, FALSE);
747 + currentflag = flag;
748 if(event.bstate & BUTTON1_DOUBLE_CLICKED) {
749 - result=callback(&currentitem, KEY_MOUSE);
750 + result=callback(&currentflag, KEY_MOUSE);
751 if(result>=0)
752 goto exit;
753 }
754 scrollcurrent();
755 - drawitem(currentitem, TRUE);
756 + drawflag(currentflag, TRUE);
757 }
758 } else if(wmouse_trafo(win(Scrollbar), &event.y, &event.x, FALSE)) {
759 // Only do mouse events if there actually is a scrollbar
760 @@ -531,19 +588,17 @@ int maineventloop(
761 event.y -= wTop(Scrollbar) + 1;
762 int sbHeight = wHeight(Scrollbar) - 3;
763 if( (event.y >= 0) && (event.y < sbHeight) ) {
764 - /// TODO : This needs to be fixed!
765 topline = (event.y * (listHeight - sbHeight + 2) + sbHeight - 1) / sbHeight;
766 - // was: topy = (event.y*(items->prev->top+items->prev->height-(wHeight(List)-1))+(wHeight(Scrollbar)-4))/(wHeight(Scrollbar)-3);
767 - while( (currentitem != items)
768 - && (currentitem->prev->listline >= topline) )
769 - currentitem = currentitem->prev;
770 - while( (currentitem->next != items)
771 - && (currentitem->listline < topline) )
772 - currentitem = currentitem->next;
773 - if( (currentitem->listline + currentitem->ndescr) > (topline + wHeight(List)) )
774 - topline = currentitem->listline + currentitem->ndescr - wHeight(List);
775 - drawitems();
776 - drawscrollbar();
777 + while( (currentflag != flags)
778 + && (currentflag->prev->listline >= topline) )
779 + currentflag = currentflag->prev;
780 + while( (currentflag->next != flags)
781 + && (currentflag->listline < topline) )
782 + currentflag = currentflag->next;
783 + if( (currentflag->listline + currentflag->ndesc) > (topline + wHeight(List)) )
784 + topline = currentflag->listline + currentflag->ndesc - wHeight(List);
785 + drawFlags();
786 + drawScrollbar();
787 wrefresh(win(List));
788 }
789 }
790 @@ -558,7 +613,7 @@ int maineventloop(
791 } else if(wmouse_trafo(win(Bottom), &event.y, &event.x, FALSE)) {
792 if( (event.bstate & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED))
793 && (event.y == 1) ) {
794 - const struct key *key;
795 + const sKey* key;
796 int x = event.x;
797 if(x < 2)
798 continue;
799 @@ -588,72 +643,79 @@ int maineventloop(
800 } else
801 #endif
802 {
803 - result=callback(&currentitem, c);
804 - if(result>=0)
805 + result = callback(&currentflag, c);
806 + if(result >= 0)
807 goto exit;
808
809 switch(c) {
810 case KEY_UP:
811 - if(currentitem->currline < 0 ) {
812 + if(currentflag->currline < 0 ) {
813 --topline;
814 - drawitems();
815 - drawscrollbar();
816 + drawFlags();
817 + drawScrollbar();
818 } else
819 setPrevItem(1, true);
820 break;
821
822 case KEY_DOWN:
823 - if( (currentitem->currline + getItemHeight(currentitem)) > wHeight(List) ) {
824 + if( (currentflag->currline + getFlagHeight(currentflag)) > wHeight(List) ) {
825 ++topline;
826 - drawitems();
827 - drawscrollbar();
828 + drawFlags();
829 + drawScrollbar();
830 } else
831 setNextItem(1, true);
832 break;
833
834 case KEY_PPAGE:
835 - if(currentitem!=items)
836 + if(currentflag != flags)
837 setPrevItem(wHeight(List), false);
838 break;
839
840 case KEY_NPAGE:
841 - if(currentitem->next!=items)
842 + if(currentflag->next != flags)
843 setNextItem(wHeight(List), false);
844 break;
845
846 case KEY_HOME:
847 - if(currentitem!=items)
848 - resetDisplay();
849 + if(currentflag != flags)
850 + resetDisplay(withSep);
851 break;
852
853 case KEY_END:
854 - if(currentitem->next!=items) {
855 - drawitem(currentitem, FALSE);
856 - currentitem = items->prev;
857 - while (!isLegalItem(currentitem))
858 - currentitem = currentitem->prev;
859 + if(currentflag->next != flags) {
860 + drawflag(currentflag, FALSE);
861 + currentflag = flags->prev;
862 + while (!isFlagLegal(currentflag))
863 + currentflag = currentflag->prev;
864 scrollcurrent();
865 - drawitem(currentitem, TRUE);
866 + drawflag(currentflag, TRUE);
867 }
868 break;
869
870 case KEY_F(5):
871 - if (show_masked == showMasked) showMasked = show_unmasked;
872 - else if (show_both == showMasked) showMasked = show_masked;
873 - else if (show_unmasked == showMasked) showMasked = show_both;
874 - resetDisplay();
875 + if (eMask_masked == e_mask) e_mask = eMask_unmasked;
876 + else if (eMask_unmasked == e_mask) e_mask = eMask_both;
877 + else e_mask = eMask_masked;
878 + resetDisplay(withSep);
879 break;
880
881 case KEY_F(6):
882 - if (pkgs_left == pkgOrder) pkgOrder = pkgs_right;
883 - else pkgOrder = pkgs_left;
884 - drawitems();
885 + if (eOrder_left == e_order) e_order = eOrder_right;
886 + else e_order = eOrder_left;
887 + drawFlags();
888 break;
889
890 // case KEY_F(7):
891 -// if (show_local == showScope) showScope = show_all;
892 -// else if (show_global == showScope) showScope = show_local;
893 -// else if (show_all == showScope) showScope = show_global;
894 +// if (eScope_local == e_scope) e_scope = eScope_all;
895 +// else if (eScope_global == e_scope) e_scope = eScope_local;
896 +// else if (eScope_all == e_scope) e_scope = eScope_global;
897 +// resetDisplay();
898 +// break;
899 +//
900 +// case KEY_F(8):
901 +// if (eState_installed == e_state) e_state = eState_notinstalled;
902 +// else if (eState_notinstalled == e_state) e_state = eState_all;
903 +// else if (eState_all == e_state) e_state = eState_installed;
904 // resetDisplay();
905 // break;
906
907 @@ -661,16 +723,19 @@ int maineventloop(
908 case KEY_RESIZE:
909 resizeterm(LINES, COLS);
910 checktermsize();
911 - { enum win w; for(w = (enum win) 0; w != wCount; w++) {
912 + { eWin w; for(w = (eWin) 0; w != wCount; w++) {
913 delwin(window[w].win);
914 window[w].win = newwin(wHeight(w), wWidth(w), wTop(w), wLeft(w));
915 } }
916 - if(result==-1) {
917 + if(result == -1) {
918 topline = 0;
919 scrollcurrent();
920 } else
921 - items = currentitem;
922 - draw();
923 + // This is the result of a resize in
924 + // the help screen, it will re-init
925 + // the help text lines.
926 + flags = currentflag;
927 + draw(withSep);
928 break;
929 #endif
930 }
931 @@ -680,124 +745,109 @@ int maineventloop(
932 exit:
933 subtitle = _subtitle;
934 callback = _callback;
935 - drawitem = _drawitem;
936 - items = _items;
937 + drawflag = _drawflag;
938 + flags = _flags;
939 keys = _keys;
940
941 // revert filters
942 - showMasked = oldMask;
943 - showScope = oldScope;
944 + e_mask = oldMask;
945 + e_scope = oldScope;
946 + e_state = oldState;
947
948 - if(items!=NULL)
949 - resetDisplay();
950 + if(flags != NULL)
951 + resetDisplay(withSep);
952
953 return result;
954 }
955
956
957 -/* @brief Set display to first legal item and redraw
958 +/** @brief Set display to first legal item and redraw
959 + * @param withSep draw status separators if set to true
960 */
961 -void resetDisplay()
962 +void resetDisplay(bool withSep)
963 {
964 - currentitem = items;
965 - while (!isLegalItem(currentitem))
966 - currentitem = currentitem->next;
967 - topline = currentitem->listline;
968 - draw();
969 + currentflag = flags;
970 + while (!isFlagLegal(currentflag) && (currentflag->next != flags))
971 + currentflag = currentflag->next;
972 + topline = currentflag->listline;
973 + draw(withSep);
974 }
975
976
977 -/* @brief set currentitem to the next item @a count lines away
978 +/** @brief set currentflag to the next flag @a count lines away
979 * @param count set how many lines should be skipped
980 * @param strict if set to false, at least one item has to be skipped.
981 */
982 void setNextItem(int count, bool strict)
983 {
984 - bool result = true;
985 - struct item *curr = currentitem;
986 - int skipped = 0;
987 - int oldTop = topline;
988 + bool result = true;
989 + sFlag* curr = currentflag;
990 + int skipped = 0;
991 + int oldTop = topline;
992
993 while (result && (skipped < count)) {
994 - if (curr->next == items)
995 + if (curr->next == flags)
996 result = false; // The list is finished, no next item to display
997 else
998 curr = curr->next;
999
1000 // curr is only counted if it is not filtered out:
1001 - if (isLegalItem(curr))
1002 - skipped += getItemHeight(curr);
1003 + if (isFlagLegal(curr))
1004 + skipped += getFlagHeight(curr);
1005 else
1006 // Otherwise topline must be adapted or scrollcurrent() wreaks havoc!
1007 - topline += curr->ndescr;
1008 + topline += curr->ndesc;
1009 } // End of trying to find a next item
1010
1011 if ( (result && strict) || (!strict && skipped) ) {
1012 // Move back again if curr ended up being filtered
1013 - while (!isLegalItem(curr)) {
1014 - topline -= curr->ndescr;
1015 + while (!isFlagLegal(curr)) {
1016 + topline -= curr->ndesc;
1017 curr = curr->prev;
1018 }
1019 - drawitem(currentitem, FALSE);
1020 - currentitem = curr;
1021 + drawflag(currentflag, FALSE);
1022 + currentflag = curr;
1023 if (!scrollcurrent())
1024 - drawitem(currentitem, TRUE);
1025 + drawflag(currentflag, TRUE);
1026 } else
1027 topline = oldTop;
1028 }
1029
1030
1031 -/* @brief set currentitem to the previous item @a count lines away
1032 +/* @brief set currentflag to the previous item @a count lines away
1033 * @param count set how many lines should be skipped
1034 * @param strict if set to false, at least one item has to be skipped.
1035 */
1036 void setPrevItem(int count, bool strict)
1037 {
1038 - bool result = true;
1039 - struct item *curr = currentitem;
1040 - int skipped = 0;
1041 - int oldTop = topline;
1042 + bool result = true;
1043 + sFlag* curr = currentflag;
1044 + int skipped = 0;
1045 + int oldTop = topline;
1046
1047 while (result && (skipped < count)) {
1048 - if (curr == items)
1049 + if (curr == flags)
1050 result = false; // The list is finished, no previous item to display
1051 else
1052 curr = curr->prev;
1053
1054 // curr is only counted if it is not filtered out:
1055 - if (isLegalItem(curr))
1056 - skipped += getItemHeight(curr);
1057 + if (isFlagLegal(curr))
1058 + skipped += getFlagHeight(curr);
1059 else
1060 - topline -= curr->ndescr;
1061 + topline -= curr->ndesc;
1062 } // End of trying to find next item
1063
1064 if ( (result && strict) || (!strict && skipped) ) {
1065 // Move forth again if curr ended up being filtered
1066 - while (!isLegalItem(curr)) {
1067 - topline += curr->ndescr;
1068 + while (!isFlagLegal(curr)) {
1069 + topline += curr->ndesc;
1070 curr = curr->next;
1071 }
1072 - drawitem(currentitem, FALSE);
1073 - currentitem = curr;
1074 + drawflag(currentflag, FALSE);
1075 + currentflag = curr;
1076 if (!scrollcurrent())
1077 - drawitem(currentitem, TRUE);
1078 + drawflag(currentflag, TRUE);
1079 } else
1080 topline = oldTop;
1081 }
1082 -
1083 -
1084 -/* @brief return true if the given @a item is not filtered out
1085 - */
1086 -bool isLegalItem(struct item *item)
1087 -{
1088 - if ( // 1: Mask filter
1089 - ( ( item->isMasked && (show_unmasked != showMasked))
1090 - || (!item->isMasked && (show_masked != showMasked)) )
1091 - // 2: Global / Local filter
1092 - && ( ( item->isGlobal && ( (show_local != showScope) || (item->ndescr > 1) ) )
1093 - || (!item->isGlobal && ( show_global != showScope)) ) )
1094 - return true;
1095 - return false;
1096 -}
1097 -
1098 -