123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- /*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2008 Sean Bright
- *
- * Sean Bright <sean.bright@gmail.com>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
- /*
- * \file
- *
- * \author Sean Bright <sean.bright@gmail.com>
- *
- * \brief newt frontend for selection maintenance
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <newt.h>
- #include "menuselect.h"
- #define MIN_X 80
- #define MIN_Y 21
- #define MIN(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); ((__a > __b) ? __b : __a);})
- #define MAX(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); ((__a < __b) ? __b : __a);})
- extern int changes_made;
- static newtComponent rootOptions;
- static newtComponent subOptions;
- static newtComponent memberNameTextbox;
- static newtComponent dependsLabel;
- static newtComponent usesLabel;
- static newtComponent conflictsLabel;
- static newtComponent supportLevelLabel;
- static newtComponent dependsDataTextbox;
- static newtComponent usesDataTextbox;
- static newtComponent conflictsDataTextbox;
- static newtComponent supportLevelDataTextbox;
- static newtComponent exitButton;
- static newtComponent saveAndExitButton;
- static void build_members_menu(int overlay);
- static void root_menu_callback(newtComponent component, void *data);
- static void toggle_all_options(int select)
- {
- struct category *cat = newtListboxGetCurrent(rootOptions);
- set_all(cat, select);
- /* Redraw */
- build_members_menu(1);
- return;
- }
- static void toggle_selected_option()
- {
- int i;
- struct member *mem = newtListboxGetCurrent(subOptions);
- toggle_enabled(mem);
- /* Redraw */
- build_members_menu(1);
- /* Select the next item in the list */
- for (i = 0; i < newtListboxItemCount(subOptions); i++) {
- struct member *cur;
- newtListboxGetEntry(subOptions, i, NULL, (void **) &cur);
- if (cur == mem) {
- i = MIN(i + 1, newtListboxItemCount(subOptions) - 1);
- break;
- }
- }
- newtListboxSetCurrent(subOptions, i);
- return;
- }
- static void reset_display()
- {
- newtTextboxSetText(memberNameTextbox, "");
- newtTextboxSetText(dependsDataTextbox, "");
- newtTextboxSetText(usesDataTextbox, "");
- newtTextboxSetText(conflictsDataTextbox, "");
- newtTextboxSetText(supportLevelDataTextbox, "");
- newtRefresh();
- }
- static void display_member_info(struct member *mem)
- {
- char buffer[128] = { 0 };
- struct reference *dep;
- struct reference *con;
- struct reference *uses;
- reset_display();
- if (mem->displayname) {
- newtTextboxSetText(memberNameTextbox, mem->displayname);
- }
- if (AST_LIST_EMPTY(&mem->deps)) {
- if (mem->is_separator) {
- newtTextboxSetText(dependsDataTextbox, "");
- } else {
- newtTextboxSetText(dependsDataTextbox, "N/A");
- }
- } else {
- strcpy(buffer, "");
- AST_LIST_TRAVERSE(&mem->deps, dep, list) {
- strncat(buffer, dep->displayname, sizeof(buffer) - strlen(buffer) - 1);
- strncat(buffer, dep->member ? "(M)" : "(E)", sizeof(buffer) - strlen(buffer) - 1);
- if (AST_LIST_NEXT(dep, list))
- strncat(buffer, ", ", sizeof(buffer) - strlen(buffer) - 1);
- }
- newtTextboxSetText(dependsDataTextbox, buffer);
- }
- if (AST_LIST_EMPTY(&mem->uses)) {
- if (mem->is_separator) {
- newtTextboxSetText(usesDataTextbox, "");
- } else {
- newtTextboxSetText(usesDataTextbox, "N/A");
- }
- } else {
- strcpy(buffer, "");
- AST_LIST_TRAVERSE(&mem->uses, uses, list) {
- strncat(buffer, uses->displayname, sizeof(buffer) - strlen(buffer) - 1);
- strncat(buffer, uses->member ? "(M)" : "(E)", sizeof(buffer) - strlen(buffer) - 1);
- if (AST_LIST_NEXT(uses, list))
- strncat(buffer, ", ", sizeof(buffer) - strlen(buffer) - 1);
- }
- newtTextboxSetText(usesDataTextbox, buffer);
- }
- if (AST_LIST_EMPTY(&mem->conflicts)) {
- if (!mem->is_separator) {
- newtTextboxSetText(conflictsDataTextbox, "N/A");
- } else {
- newtTextboxSetText(conflictsDataTextbox, "");
- }
- } else {
- strcpy(buffer, "");
- AST_LIST_TRAVERSE(&mem->conflicts, con, list) {
- strncat(buffer, con->displayname, sizeof(buffer) - strlen(buffer) - 1);
- strncat(buffer, con->member ? "(M)" : "(E)", sizeof(buffer) - strlen(buffer) - 1);
- if (AST_LIST_NEXT(con, list))
- strncat(buffer, ", ", sizeof(buffer) - strlen(buffer) - 1);
- }
- newtTextboxSetText(conflictsDataTextbox, buffer);
- }
- { /* Support Level */
- snprintf(buffer, sizeof(buffer), "%s", mem->support_level);
- if (mem->replacement && *mem->replacement) {
- char buf2[64];
- snprintf(buf2, sizeof(buf2), ", Replaced by: %s", mem->replacement);
- strncat(buffer, buf2, sizeof(buffer) - strlen(buffer) - 1);
- }
- if (mem->is_separator) {
- newtTextboxSetText(supportLevelDataTextbox, "");
- } else {
- newtTextboxSetText(supportLevelDataTextbox, buffer);
- }
- }
- }
- static void build_members_menu(int overlay)
- {
- struct category *cat;
- struct member *mem;
- char buf[64];
- int i = 0;
- if (!overlay) {
- reset_display();
- newtListboxClear(subOptions);
- }
- cat = newtListboxGetCurrent(rootOptions);
- AST_LIST_TRAVERSE(&cat->members, mem, list) {
- if ((mem->depsfailed == HARD_FAILURE) || (mem->conflictsfailed == HARD_FAILURE)) {
- snprintf(buf, sizeof(buf), "XXX %s", mem->name);
- } else if (mem->is_separator) {
- snprintf(buf, sizeof(buf), " --- %s ---", mem->name);
- } else if (mem->depsfailed == SOFT_FAILURE) {
- snprintf(buf, sizeof(buf), "<%s> %s", mem->enabled ? "*" : " ", mem->name);
- } else if (mem->conflictsfailed == SOFT_FAILURE) {
- snprintf(buf, sizeof(buf), "(%s) %s", mem->enabled ? "*" : " ", mem->name);
- } else {
- snprintf(buf, sizeof(buf), "[%s] %s", mem->enabled ? "*" : " ", mem->name);
- }
- if (overlay) {
- newtListboxSetEntry(subOptions, i, buf);
- } else {
- newtListboxAppendEntry(subOptions, buf, mem);
- }
- i++;
- }
- if (!overlay) {
- display_member_info(AST_LIST_FIRST(&cat->members));
- }
- return;
- }
- static void build_main_menu()
- {
- struct category *cat;
- char buf[64];
- int i = 1;
- newtListboxClear(rootOptions);
- AST_LIST_TRAVERSE(&categories, cat, list) {
- if (!strlen_zero(cat->displayname))
- snprintf(buf, sizeof(buf), " %s ", cat->displayname);
- else
- snprintf(buf, sizeof(buf), " %s ", cat->name);
- newtListboxAppendEntry(rootOptions, buf, cat);
- i++;
- }
- }
- static void category_menu_callback(newtComponent component, void *data)
- {
- display_member_info(newtListboxGetCurrent(subOptions));
- }
- static void root_menu_callback(newtComponent component, void *data)
- {
- build_members_menu(0);
- }
- int run_confirmation_dialog(int *result)
- {
- int res = newtWinTernary("Are You Sure?", "Discard changes & Exit", "Save & Exit", "Cancel",
- "It appears you have made some changes, and you have opted to Quit "
- "without saving these changes. Please choose \"Discard changes & Exit\" to exit "
- "without saving; Choose \"Cancel\" to cancel your decision to quit, and keep "
- "working in menuselect, or choose \"Save & Exit\" to save your changes, and exit.");
- switch (res) {
- case 1:
- /* Discard and exit */
- *result = -1;
- return 1;
- case 2:
- /* Save and exit */
- *result = 0;
- return 1;
- case 3:
- /* They either chose "No" or they hit F12 */
- default:
- *result = -1;
- return 0;
- }
- }
- int run_menu(void)
- {
- struct newtExitStruct es;
- newtComponent form;
- int x = 0, y = 0, res = 0;
- newtInit();
- newtCls();
- newtGetScreenSize(&x, &y);
- if (x < MIN_X || y < MIN_Y) {
- newtFinished();
- fprintf(stderr, "Terminal must be at least %d x %d.\n", MIN_X, MIN_Y);
- return -1;
- }
- newtPushHelpLine(" <ENTER> toggles selection | <F12> saves & exits | <ESC> exits without save");
- newtRefresh();
- newtCenteredWindow(x - 8, y - 7, menu_name);
- form = newtForm(NULL, NULL, 0);
- /* F8 for select all */
- newtFormAddHotKey(form, NEWT_KEY_F8);
- /* F7 for deselect all */
- newtFormAddHotKey(form, NEWT_KEY_F7);
- newtFormSetTimer(form, 200);
- rootOptions = newtListbox(2, 1, y - 15, 0);
- newtListboxSetWidth(rootOptions, 34);
- newtFormAddComponent(form, rootOptions);
- newtComponentAddCallback(rootOptions, root_menu_callback, NULL);
- subOptions = newtListbox(38, 1, y - 15, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
- newtListboxSetWidth(subOptions, x - 47);
- newtFormAddComponent(form, subOptions);
- newtComponentAddCallback(subOptions, category_menu_callback, NULL);
- memberNameTextbox = newtTextbox(2, y - 13, x - 10, 1, 0);
- dependsLabel = newtLabel(2, y - 11, " Depends on:");
- usesLabel = newtLabel(2, y - 10, " Can use:");
- conflictsLabel = newtLabel(2, y - 9, "Conflicts with:");
- supportLevelLabel = newtLabel(2, y - 8, " Support Level:");
- dependsDataTextbox = newtTextbox(18, y - 11, x - 27, 1, 0);
- usesDataTextbox = newtTextbox(18, y - 10, x - 27, 1, 0);
- conflictsDataTextbox = newtTextbox(18, y - 9, x - 27, 1, 0);
- supportLevelDataTextbox = newtTextbox(18, y - 8, x - 27, 1, 0);
- exitButton = newtButton(x - 23, y - 11, " Exit ");
- saveAndExitButton = newtButton(x - 43, y - 11, " Save & Exit ");
- newtFormAddComponents(
- form,
- memberNameTextbox,
- dependsLabel,
- dependsDataTextbox,
- usesLabel,
- usesDataTextbox,
- conflictsLabel,
- conflictsDataTextbox,
- supportLevelLabel,
- supportLevelDataTextbox,
- saveAndExitButton,
- exitButton,
- NULL);
- build_main_menu();
- root_menu_callback(rootOptions, AST_LIST_FIRST(&categories));
- for (;;) {
- do {
- newtFormRun(form, &es);
- } while (es.reason == NEWT_EXIT_TIMER);
- if (es.reason == NEWT_EXIT_HOTKEY) {
- int done = 1;
- switch (es.u.key) {
- case NEWT_KEY_F12:
- res = 0;
- break;
- case NEWT_KEY_F7:
- toggle_all_options(0);
- done = 0;
- break;
- case NEWT_KEY_F8:
- toggle_all_options(1);
- done = 0;
- break;
- case NEWT_KEY_ESCAPE:
- if (changes_made) {
- done = run_confirmation_dialog(&res);
- } else {
- res = -1;
- }
- break;
- default:
- done = 0;
- break;
- }
- if (done) {
- break;
- }
- } else if (es.reason == NEWT_EXIT_COMPONENT) {
- if (es.u.co == saveAndExitButton) {
- res = 0;
- break;
- } else if (es.u.co == exitButton) {
- int done = 1;
- if (changes_made) {
- done = run_confirmation_dialog(&res);
- } else {
- res = -1;
- }
- if (done) {
- break;
- }
- } else if (es.u.co == subOptions) {
- toggle_selected_option();
- }
- }
- }
- /* Cleanup */
- reset_display();
- newtFormDestroy(form);
- newtPopWindow();
- newtPopHelpLine();
- newtCls();
- newtFinished();
- return res;
- }
|