]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
cfdisk: improve info line and menu updates
authorKarel Zak <kzak@redhat.com>
Wed, 22 Jan 2014 13:22:35 +0000 (14:22 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 11 Mar 2014 10:35:13 +0000 (11:35 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
fdisks/cfdisk.c

index 264c6bdcb3ad11bc632e27c2429959a8b3a452a9..9b5d91b70b96ce6332a8dcf7c2461c0162eaacf0 100644 (file)
@@ -58,8 +58,15 @@ struct cfdisk;
 typedef int (menu_callback_t)(struct cfdisk *, int);
 
 static int menu_cb_main(struct cfdisk *cf, int key);
+static struct cfdisk_menudesc *menu_get_menuitem(struct cfdisk *cf, size_t idx);
+static struct cfdisk_menudesc *menu_get_menuitem_by_key(struct cfdisk *cf, int key, size_t *idx);
+
 static int ui_refresh(struct cfdisk *cf);
+static void ui_warnx(const char *fmt, ...);
+static void ui_warn(const char *fmt, ...);
+static void ui_info(const char *fmt, ...);
 
+static int ui_enabled;
 
 struct cfdisk_menudesc {
        int             key;            /* keyboard shortcut */
@@ -123,8 +130,6 @@ struct cfdisk {
        char    **lines;        /* array with lines */
        size_t  nlines;         /* number of lines */
        size_t  lines_idx;              /* current line <0..N>, exclude header */
-
-       unsigned int    ui_enabled : 1;
 };
 
 static int cols_init(struct cfdisk *cf)
@@ -271,20 +276,17 @@ static int ask_callback(struct fdisk_context *cxt, struct fdisk_ask *ask,
 
        switch(fdisk_ask_get_type(ask)) {
        case FDISK_ASKTYPE_INFO:
-               fputs(fdisk_ask_print_get_mesg(ask), stdout);
-               fputc('\n', stdout);
+               ui_info(fdisk_ask_print_get_mesg(ask));
                break;
        case FDISK_ASKTYPE_WARNX:
-               fputs(fdisk_ask_print_get_mesg(ask), stderr);
-               fputc('\n', stderr);
+               ui_warnx(fdisk_ask_print_get_mesg(ask));
                break;
        case FDISK_ASKTYPE_WARN:
-               fputs(fdisk_ask_print_get_mesg(ask), stderr);
-               errno = fdisk_ask_print_get_errno(ask);
-               fprintf(stderr, ": %m\n");
+               ui_warn(fdisk_ask_print_get_mesg(ask));
                break;
        default:
-               warnx(_("internal error: unsupported dialog type %d"), fdisk_ask_get_type(ask));
+               ui_warnx(_("internal error: unsupported dialog type %d"),
+                       fdisk_ask_get_type(ask));
                return -EINVAL;
        }
        return rc;
@@ -293,7 +295,7 @@ static int ask_callback(struct fdisk_context *cxt, struct fdisk_ask *ask,
 
 static int ui_end(struct cfdisk *cf)
 {
-       if (cf && !cf->ui_enabled)
+       if (cf && !ui_enabled)
                return -EINVAL;
 
 #if defined(HAVE_SLCURSES_H) || defined(HAVE_SLANG_SLCURSES_H)
@@ -334,19 +336,41 @@ static void ui_center(int line, const char *fmt, ...)
        va_end(ap);
 }
 
-static void ui_warning(const char *fmt, ...)
+static void ui_warnx(const char *fmt, ...)
+{
+       va_list ap;
+       va_start(ap, fmt);
+       if (ui_enabled)
+               ui_vprint_center(INFO_LINE, COLOR_PAIR(CFDISK_CL_WARNING), fmt, ap);
+       else
+               vfprintf(stderr, fmt, ap);
+       va_end(ap);
+}
+
+static void ui_warn(const char *fmt, ...)
 {
+       char *fmt_m;
        va_list ap;
+
+       xasprintf(&fmt_m, "%s: %m", fmt);
+
        va_start(ap, fmt);
-       ui_vprint_center(INFO_LINE, COLOR_PAIR(CFDISK_CL_WARNING), fmt, ap);
+       if (ui_enabled)
+               ui_vprint_center(INFO_LINE, COLOR_PAIR(CFDISK_CL_WARNING), fmt_m, ap);
+       else
+               vfprintf(stderr, fmt_m, ap);
        va_end(ap);
+       free(fmt_m);
 }
 
 static void ui_info(const char *fmt, ...)
 {
        va_list ap;
        va_start(ap, fmt);
-       ui_vprint_center(INFO_LINE, A_BOLD, fmt, ap);
+       if (ui_enabled)
+               ui_vprint_center(INFO_LINE, A_BOLD, fmt, ap);
+       else
+               vfprintf(stdout, fmt, ap);
        va_end(ap);
 }
 
@@ -368,11 +392,14 @@ static void menu_update_ignore(struct cfdisk *cf)
        int i = 0;
        struct fdisk_partition *pa;
        struct cfdisk_menu *m;
-       struct cfdisk_menudesc *d;
+       struct cfdisk_menudesc *d, *org;
+       size_t idx;
 
        assert(cf);
 
        m = cf->menu;
+       org = menu_get_menuitem(cf, cf->menu_idx);
+
        DBG(FRONTEND, dbgprint("menu: update menu ignored keys"));
 
        switch (m->id) {
@@ -384,8 +411,12 @@ static void menu_update_ignore(struct cfdisk *cf)
                        ignore[i++] = 'd';      /* delete */
                        ignore[i++] = 't';      /* set type */
                        ignore[i++] = 'b';      /* set bootable */
-               } else
+               } else {
                        ignore[i++] = 'n';
+                       if (!fdisk_is_disklabel(cf->cxt, DOS) &&
+                           !fdisk_is_disklabel(cf->cxt, SGI))
+                               ignore[i++] = 'b';
+               }
 
                break;
        }
@@ -407,6 +438,12 @@ static void menu_update_ignore(struct cfdisk *cf)
                        continue;
                m->nitems++;
        }
+
+       /* refresh menu index to be at the same menuitem or go to the first */
+       if (org && menu_get_menuitem_by_key(cf, org->key, &idx))
+               cf->menu_idx = idx;
+       else
+               cf->menu_idx = 0;
 }
 
 static struct cfdisk_menu *menu_push(struct cfdisk *cf, size_t id)
@@ -456,21 +493,34 @@ static struct cfdisk_menu *menu_pop(struct cfdisk *cf)
 /* returns: error: < 0, success: 0, quit: 1 */
 static int menu_cb_main(struct cfdisk *cf, int key)
 {
-       int rc;
+       size_t n;
+       int ref = 0;
+       const char *info = NULL, *warn = NULL;
 
        assert(cf);
        assert(cf->cxt);
        assert(key);
 
+       n = cf->lines_idx;      /* the current partition */
+
        switch (key) {
+       case 'b': /* Bootable flag */
+       {
+               int fl = fdisk_is_disklabel(cf->cxt, DOS) ? DOS_FLAG_ACTIVE :
+                        fdisk_is_disklabel(cf->cxt, SGI) ? SGI_FLAG_BOOT : 0;
+
+               if (fl && fdisk_partition_toggle_flag(cf->cxt, n, fl))
+                       warn = _("Could not toggle the flag.");
+               else if (fl)
+                       ref = 1;
+               break;
+       }
        case 'd': /* Delete */
-               rc = fdisk_delete_partition(cf->cxt, cf->lines_idx);
-               lines_refresh(cf);
-               ui_refresh(cf);
-               if (rc)
-                       ui_warning(_("Could not delete partition %zu."), cf->lines_idx + 1);
+               if (fdisk_delete_partition(cf->cxt, n) != 0)
+                       warn = _("Could not delete partition %zu.");
                else
-                       ui_info(_("Partition %zu has been deleted."), cf->lines_idx + 1);
+                       info = _("Partition %zu has been deleted.");
+               ref = 1;
                break;
        case 'n': /* New */
                break;
@@ -481,6 +531,16 @@ static int menu_cb_main(struct cfdisk *cf, int key)
        case 'W': /* Write */
                break;
        }
+
+       if (ref) {
+               lines_refresh(cf);
+               ui_refresh(cf);
+       }
+       if (warn)
+               ui_warnx(warn, n);
+       else if (info)
+               ui_info(info, n);
+
        return 0;
 }
 
@@ -497,7 +557,7 @@ static int ui_init(struct cfdisk *cf)
        sigaction(SIGINT, &sa, NULL);
        sigaction(SIGTERM, &sa, NULL);
 
-       cf->ui_enabled = 1;
+       ui_enabled = 1;
        initscr();
 
        if (has_colors()) {
@@ -557,6 +617,22 @@ static struct cfdisk_menudesc *menu_get_menuitem(struct cfdisk *cf, size_t idx)
        return NULL;
 }
 
+static struct cfdisk_menudesc *menu_get_menuitem_by_key(struct cfdisk *cf,
+                                                       int key, size_t *idx)
+{
+       struct cfdisk_menudesc *d;
+
+       for (*idx = 0, d = cf->menu->desc; d->name; d++) {
+               if (cf->menu->ignore && strchr(cf->menu->ignore, d->key))
+                       continue;
+               if (key == d->key)
+                       return d;
+               (*idx)++;
+       }
+
+       return NULL;
+}
+
 static void ui_draw_menuitem(struct cfdisk *cf,
                             struct cfdisk_menudesc *d,
                             size_t idx)
@@ -734,7 +810,7 @@ static int ui_refresh(struct cfdisk *cf)
                                | SIZE_SUFFIX_3LETTER, bytes);
        erase();
 
-       if (!cf->ui_enabled)
+       if (!ui_enabled)
                return -EINVAL;
 
        /* header */