menuselect: Various menuselect enhancements
authorGeorge Joseph <gjoseph@digium.com>
Sun, 24 Jul 2016 23:27:26 +0000 (17:27 -0600)
committerGeorge Joseph <gjoseph@digium.com>
Mon, 25 Jul 2016 19:31:48 +0000 (14:31 -0500)
* Add 'external' as a support level.
* Add ability for module directories to add entries to the menu
  by adding members to the <module_prefix>/<module_prefix>.xml file.
* Expand the description field to 3 lines in the ncurses implementation.
* Allow the description field to wrap in the newt implementation.
* Add description field to the gtk implementation.

Change-Id: I7f9600a1984a42ce0696db574c1051bc9ad7c808

Makefile.moddir_rules
Makefile.rules
menuselect/menuselect.c
menuselect/menuselect.h
menuselect/menuselect_curses.c
menuselect/menuselect_gtk.c
menuselect/menuselect_newt.c

index a92b0d8..9b5f3f1 100644 (file)
@@ -164,7 +164,7 @@ dist-clean::
        $(AWK) -f $(ASTTOPDIR)/build_tools/get_moduleinfo $^ >> $@
        echo "</member>" >> $@
 
-.moduleinfo:: $(addsuffix .moduleinfo,$(addprefix .,$(sort $(ALL_C_MODS) $(ALL_CC_MODS))))
+.moduleinfo:: $(addsuffix .moduleinfo,$(addprefix .,$(sort $(ALL_C_MODS) $(ALL_CC_MODS)))) $(wildcard $(call tolower,$(MENUSELECT_CATEGORY)).xml)
        @echo "<category name=\"MENUSELECT_$(MENUSELECT_CATEGORY)\" displayname=\"$(MENUSELECT_DESCRIPTION)\" remove_on_change=\"$(SUBDIR)/modules.link\">" > $@
        @cat $^ >> $@
        @echo "</category>" >> $@
index a22f19c..45989d6 100644 (file)
 
 -include $(ASTTOPDIR)/makeopts
 
+# Helpful functions
+# call with $(call function,...)
+tolower = $(shell echo $(1) | tr '[:upper:]' '[:lower:]')
+
 .PHONY: dist-clean
 
 # If 'make' decides to create intermediate files to satisfy a build requirement
index 6136135..efae311 100644 (file)
@@ -246,6 +246,10 @@ static enum support_level_values string_to_support_level(const char *support_lev
                return SUPPORT_DEPRECATED;
        }
 
+       if (!strcasecmp(support_level, "external")) {
+               return SUPPORT_EXTERNAL;
+       }
+
        return SUPPORT_UNSPECIFIED;
 }
 
@@ -259,6 +263,8 @@ static const char *support_level_to_string(enum support_level_values support_lev
                return "Extended";
        case SUPPORT_DEPRECATED:
                return "Deprecated";
+       case SUPPORT_EXTERNAL:
+               return "External";
        default:
                return "Unspecified";
        }
index 112f1c8..7b3fe26 100644 (file)
@@ -105,7 +105,8 @@ enum support_level_values {
        SUPPORT_EXTENDED = 1,
        SUPPORT_DEPRECATED = 2,
        SUPPORT_UNSPECIFIED = 3,
-       SUPPORT_COUNT = 4, /* Keep this item at the end of the list. Tracks total number of support levels. */
+       SUPPORT_EXTERNAL = 4,
+       SUPPORT_COUNT = 5, /* Keep this item at the end of the list. Tracks total number of support levels. */
 };
 
 AST_LIST_HEAD_NOLOCK(support_level_bucket, member);
index 0064592..e799574 100644 (file)
@@ -194,46 +194,49 @@ static void display_mem_info(WINDOW *menu, struct member *mem, int start_y, int
        int start_x = (max_x / 2 - MEMBER_INFO_LEFT_ADJ);
        int maxlen = (max_x - start_x);
 
-       wmove(menu, end - start_y + 1, start_x);
+       wmove(menu, end - start_y + 1, 0);
        wclrtoeol(menu);
-       wmove(menu, end - start_y + 2, start_x);
+       wmove(menu, end - start_y + 2, 0);
        wclrtoeol(menu);
-       wmove(menu, end - start_y + 3, start_x);
+       wmove(menu, end - start_y + 3, 0);
        wclrtoeol(menu);
-       wmove(menu, end - start_y + 4, start_x);
+       wmove(menu, end - start_y + 4, 0);
        wclrtoeol(menu);
-       wmove(menu, end - start_y + 5, start_x);
+       wmove(menu, end - start_y + 5, 0);
        wclrtoeol(menu);
-       wmove(menu, end - start_y + 6, start_x);
+       wmove(menu, end - start_y + 6, 0);
+       wclrtoeol(menu);
+       wmove(menu, end - start_y + 7, 0);
        wclrtoeol(menu);
 
        if (mem->displayname) {
-               int name_len = strlen(mem->displayname);
+               char buf[maxlen + 1];
+               char *displayname = strdupa(mem->displayname);
+               char *word;
+               int current_line = 1;
+               int new_line = 1;
 
+               buf[0] = '\0';
                wmove(menu, end - start_y + 1, start_x);
-               if (name_len >  maxlen) {
-                       char *last_space;
-                       char *line_1 = strdup(mem->displayname);
-
-                       if (line_1) {
-                               line_1[maxlen] = '\0';
-                               last_space = strrchr(line_1, ' ');
-                               if (last_space) {
-                                       *last_space = '\0';
-                               }
-                               waddstr(menu, line_1);
-                               wmove(menu, end - start_y + 2, start_x);
-                               waddstr(menu, &mem->displayname[last_space - line_1]);
-                               free(line_1);
-                       } else {
-                               waddstr(menu, (char *) mem->displayname);
+
+               while ((word = strsep(&displayname, " "))) {
+                       if ((strlen(buf) + strlen(word) + 1) > maxlen) {
+                               waddstr(menu, buf);
+                               current_line++;
+                               wmove(menu, end - start_y + current_line, start_x);
+                               buf[0] = '\0';
+                               new_line = 1;
                        }
-               } else {
-                       waddstr(menu, (char *) mem->displayname);
+                       sprintf(buf, "%s%*.*s%s", buf, new_line ? 0 : 1, new_line ? 0 : 1, " ", word);
+                       new_line = 0;
+               }
+               if (strlen(buf)) {
+                       waddstr(menu, buf);
                }
        }
+
        if (!AST_LIST_EMPTY(&mem->deps)) {
-               wmove(menu, end - start_y + 3, start_x);
+               wmove(menu, end - start_y + 4, start_x);
                strcpy(buf, "Depends on: ");
                AST_LIST_TRAVERSE(&mem->deps, dep, list) {
                        strncat(buf, dep->displayname, sizeof(buf) - strlen(buf) - 1);
@@ -244,7 +247,7 @@ static void display_mem_info(WINDOW *menu, struct member *mem, int start_y, int
                waddstr(menu, buf);
        }
        if (!AST_LIST_EMPTY(&mem->uses)) {
-               wmove(menu, end - start_y + 4, start_x);
+               wmove(menu, end - start_y + 5, start_x);
                strcpy(buf, "Can use: ");
                AST_LIST_TRAVERSE(&mem->uses, use, list) {
                        strncat(buf, use->displayname, sizeof(buf) - strlen(buf) - 1);
@@ -255,7 +258,7 @@ static void display_mem_info(WINDOW *menu, struct member *mem, int start_y, int
                waddstr(menu, buf);
        }
        if (!AST_LIST_EMPTY(&mem->conflicts)) {
-               wmove(menu, end - start_y + 5, start_x);
+               wmove(menu, end - start_y + 6, start_x);
                strcpy(buf, "Conflicts with: ");
                AST_LIST_TRAVERSE(&mem->conflicts, con, list) {
                        strncat(buf, con->displayname, sizeof(buf) - strlen(buf) - 1);
@@ -268,7 +271,7 @@ static void display_mem_info(WINDOW *menu, struct member *mem, int start_y, int
 
        if (!mem->is_separator) { /* Separators lack support levels */
                { /* support level */
-                       wmove(menu, end - start_y + 6, start_x);
+                       wmove(menu, end - start_y + 7, start_x);
                        snprintf(buf, sizeof(buf), "Support Level: %s", mem->support_level);
                        if (mem->replacement && *mem->replacement) {
                                char buf2[64];
index cd31b35..9379d7d 100644 (file)
@@ -16,6 +16,8 @@ enum {
        COLUMN_USES,
        /*! Conflicts */
        COLUMN_CNFS,
+       /*! Description */
+       COLUMN_DESC,
        /*! Number of columns, must be the last element in the enum */
        NUM_COLUMNS,
 };
@@ -254,7 +256,8 @@ int run_menu(void)
                G_TYPE_BOOLEAN,  /* COLUMN_SELECTED */
                G_TYPE_STRING,   /* COLUMN_DEPS */
                G_TYPE_STRING,   /* COLUMN_USES */
-               G_TYPE_STRING);  /* COLUMN_CNFS */
+               G_TYPE_STRING,  /* COLUMN_CNFS */
+               G_TYPE_STRING);  /* COLUMN_DESC */
 
        AST_LIST_TRAVERSE(&categories, cat, list) {
                GtkTreeIter iter, iter2;
@@ -307,6 +310,7 @@ int run_menu(void)
                                COLUMN_DEPS, dep_buf,
                                COLUMN_USES, use_buf,
                                COLUMN_CNFS, cnf_buf,
+                               COLUMN_DESC, mem->displayname,
                                -1);
                }
        }
@@ -344,6 +348,11 @@ int run_menu(void)
                                renderer, "text", COLUMN_CNFS, NULL);
        gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
        
+       renderer = gtk_cell_renderer_text_new();
+       column = gtk_tree_view_column_new_with_attributes("Description",
+                               renderer, "text", COLUMN_DESC, NULL);
+       gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
+
        g_signal_connect(tree, "row-activated", (GCallback) row_activated_handler, store);
 
        gtk_container_add(GTK_CONTAINER(s_window), GTK_WIDGET(tree));
index fca5587..bc03f9b 100644 (file)
@@ -326,7 +326,7 @@ int run_menu(void)
        newtFormAddComponent(form, subOptions);
        newtComponentAddCallback(subOptions, category_menu_callback, NULL);
 
-       memberNameTextbox       = newtTextbox(2, y - 13, x - 10, 1, 0);
+       memberNameTextbox       = newtTextbox(2, y - 13, x - 10, 2, NEWT_FLAG_WRAP);
        dependsLabel            = newtLabel(2, y - 11, "    Depends on:");
        usesLabel               = newtLabel(2, y - 10, "       Can use:");
        conflictsLabel          = newtLabel(2, y - 9,  "Conflicts with:");