Anonymous avatar Anonymous committed cf40673

Update cfdisk to use keypad mode, make shortcuts case sensitive and change unit shortcuts. Fix another missing include in tests. (fdisk@sv.gnu.org/fdisk--main--0--patch-57)
fdisk@sv.gnu.org/fdisk--main--0--patch-57
Keywords:

Comments (0)

Files changed (3)

 If you have selected the extended partition, this makes it as small as possible. You should need this, if you want to create more primary partitions after the logical partitions contained in the extended. If the extended partition contains no partitions, this deletes it.
 
 @item @b{u}
-This allows you to select the display units. The key shortcuts are not very convenient, so use the menu, if possible. The shortcuts are `1', `2', ..., `9', `a', ..., `e'. This changes the units used to display the sizes in the partition list and the default unit that is used on size prompts, though you are not limited to it when entering sizes. See the ``Units'' section for more information.
+This allows you to select the display units. This changes the units used to display the sizes in the partition list and the default unit that is used on size prompts, though you are not limited to it when entering sizes. See the ``Units'' section for more information. The shortcuts are `b', `k', `m', `g', `t' for bytes, decimal kilobytes, megabytes, etc., `K', `M', `G' and `T' for the binary equivalents, `c' for percents, `a' to automatically choose the most suitable (`Compact'), `s' for sectors, `y' for cylinders, `C' for C/H/S values.
 
 @item @b{i}
 Displays a short info about the partition, like its device (or at least what cfdisk believes that should be its device), the system type of the partition in the partition table (most useful if you are editing a DOS type partition table), the exact start and end of the partition.
   #include <curses.h>
 #endif
 
+/* FIXME: I'm not sure when these are available, and what portability issues they will raise
+          Most likely this is not needed at all */
+#ifdef KEY_MIN
+#define USE_KEYPAD 1
+#else
+#define USE_KEYPAD 0
+/* Like Linux cfdisk */
+#define KEY_UP 1
+#define KEY_DOWN 2
+#define KEY_LEFT 3
+#define KEY_RIGHT 4
+#endif
+
 #include <ctype.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #define MENUDIV 1
 
 
-#define UP_KEY 1
-#define DOWN_KEY 2
 
 
 enum _MenuOptions {
 	MENU_ANYKEY = 4,
 	MENU_BUTTON = 8,
 	MENU_LEAVE_WARNING = 16, /* Don't clear the warning line */
-	MENU_NOHIGHLIGHT = 32 /* Do not highlight the selected element in the menu */
+	MENU_NOHIGHLIGHT = 32, /* Do not highlight the selected element in the menu */
+	MENU_ARROWS = 64 /* Accept arrow keys as valid */
 };
 
 typedef enum _MenuOptions MenuOptions;
 #define clear_status(warn) clear_lines(LINES - 1 - ((warn) != 0),0)
 #define clear_menu() clear_lines(LINES - 2 - MENUSIZE, LINES - 1);
 
-/*static void
-clear_status(int warn_line) {
-	move(LINES-1-warn_line,0);
-	clrtoeol();
-}*/
-
-
-
 static void
 set_status(const char *status, int warn_line) {
 	clear_status(warn_line);
 static const StrList*
 do_strlist (const char *prompt, const StrList *strlist, int opts);
 
+
+
 static void
 _display_strlist (const char* title, const StrList *message, int y) {
 	int x, i;
 
 }
 
+
 static void 
 display_message (const char* title, const char *msg) {
 	int lines;
 	move(y,0);
 	clrtoeol();
 	for (i = 0; items[i].name; i++) {
-		if (strchr(keys,tolower(items[i].key))) {
+		/* NOTE: Was tolower(items[i].key) */
+		if (strchr(keys, items[i].key)) {
 			char buf[item_size+2];
 			int name_len;
 			const char *name;
 	refresh();
 }
 
+/* TODO: Not perfect */
+static is_key_ok (int key, const char* ok_keys, MenuOptions opts) {
 
+	if (opts & MENU_ARROWS) {
+		switch (key) {
+			case KEY_UP:
+			case KEY_DOWN:
+			case KEY_LEFT:
+			case KEY_RIGHT:
+				return 1;
+		}
+	}
+#if USE_KEYPAD
+	if (key > 255)
+		return 0;
+#endif
+	return strchr(ok_keys,key) != NULL;
+}
 
 /* Menu display function. The selected parameter specifies the item that is selected by
  * default and the keys string includes the keys that should be accepted by the interface. */
 	if (selected >= count)
 		selected = 0;
 	i = 0;
-	while (!strchr(keys,tolower(items[selected].key))) {
+	/* NOTE: Was tolower(items[selected].key) */
+	while (!strchr(keys,items[selected].key)) {
 		selected = (selected + 1) % count;
 		if (i++ > count) {
 			selected = 0;
 			redraw = 0;
 		}
 		key = getch();
+#if USE_KEYPAD == 0
 		if (key == ESC) {
 			key = getch();
 			if (key == '[' || key == 'O') {
 				key = getch();
 				if (key == 'A') { /* ^[[A = Up arrow */
-					key = UP_KEY;
+					key = KEY_UP;
 				}
 				else if (key == 'B') {	/* ^[[B = Down arrow */
-					key = DOWN_KEY;
+					key = KEY_DOWN;
 				}
 				else if (key == 'C') {	/* ^[[C = Right arrow */
-					do {
-						selected = (selected + 1) % count;
-					} while (!strchr(keys,tolower(items[selected].key)));
-					key = 0;
-					redraw = 1;
-					save_selection = 1;
+					key = KEY_RIGHT;
 				}
 				else if (key == 'D') { /* ^[[D = Left arrow */
-					do {
-						selected -= 1;
-						if (selected < 0) selected += count;
-					} while (!strchr(keys,tolower(items[selected].key)));
-					key = 0;
-					redraw = 1;
-					save_selection = 1;
+					key = KEY_LEFT;
 				}
 			}
 		}
+#endif
+		if (key == KEY_RIGHT) {
+			do {
+				selected = (selected + 1) % count;
+			/* NOTE: Was tolower(items[selected].key) */
+			} while (!strchr(keys,items[selected].key));
+			key = 0;
+			redraw = 1;
+			save_selection = 1;
+		}
+		else if (key == KEY_LEFT) {
+			do {
+				selected -= 1;
+				if (selected < 0) selected += count;
+			/* NOTE: Was tolower(items[selected].key) */
+			} while (!strchr(keys,items[selected].key));
+			key = 0;
+			redraw = 1;
+			save_selection = 1;
+		}
 		else if (key == CR) {
 			key = items[selected].key;
 		}
 		/* If the pressed key is in the list of accepted keys, print a warning */
-		if(!(opts & MENU_ANYKEY) && !strchr(keys,tolower(key))) {
+		/* NOTE: Was tolower(key) */
+		if(!(opts & MENU_ANYKEY) && !is_key_ok(key,keys,opts)) {
 			key = 0;
 			print_warning(_("Invalid key"),0);
 		}
 		}
 		refresh();
 		key = getch();
+#if USE_KEYPAD == 0
 		if (key == ESC) {
 			key = getch();
 			if (key == '[' || key == 'O') {
 			key = getch();
 				if (key == 'B' && !(opts & 2)) { /*Down arrow*/
-					if (!selected->next)
-						print_warning(end_warning,0);
-					else {
-						selected = selected->next;
-						selnum++;
-						redraw = 1;
-					}
+					key = KEY_UP;
 				}
 				else
 				if (key == 'A' && !(opts & 2)) { /*Up arrow*/
-					if (strlist == selected || 
-					    ((opts & 1) && selnum <= LINES-2-SLD_HEAD))
-						print_warning(end_warning,0);
-					else {
-					/* FIXME: Edit strlist and make this faster */
-					/* Users should not use the up arrow much anyway */
-						temp = strlist;
-						while (temp && temp->next != selected)
-							temp = temp->next;
-						/* This should never happen */
-						if (temp->next != selected)
-							print_warning(_("Bug in the program. "
-							                "The programmer is an idiot."),0);
-						else {
-							selnum--;
-							selected = temp;
-							redraw = 1;
-						}
-					}
+					key = KEY_DOWN;
 				}
 				else if (opts & 1)
 					done = 1;
 			else
 				print_warning(_("Invalid key"),0);
 		}
+#endif
+		if (key == KEY_DOWN) {
+			if (!selected->next)
+				print_warning(end_warning,0);
+			else {
+				selected = selected->next;
+				selnum++;
+				redraw = 1;
+			}
+		}
+		else if (key == KEY_UP) {
+			if (strlist == selected || 
+			    ((opts & 1) && selnum <= LINES-2-SLD_HEAD))
+				print_warning(end_warning,0);
+			else {
+			/* FIXME: Edit strlist and make this faster */
+			/* Users should not use the up arrow much anyway */
+				temp = strlist;
+				while (temp && temp->next != selected)
+					temp = temp->next;
+				/* This should never happen */
+				if (temp->next != selected)
+					print_warning(_("Bug in the program. "
+							"The programmer is an idiot."),0);
+				else {
+					selnum--;
+					selected = temp;
+					redraw = 1;
+				}
+			}
+		}
 		else if (key == CR) {
 			done = 1;
 		}
 	while(!done) {
 		key = getch();
 		if (key == ESC) {
+#if USE_KEYPAD == 0
 			if (getch() == ESC) 
 				return 0;
 			else getch();
+#else
+			return 0;
+#endif
 		}
 		else if (key == BKSP || key == DEL) {
 			if (i > 0) {
 
 static int
 getstring (const char* prompt, char **value, const StrList* words, const StrList* locwords, int mword) {
-	/* TODO: Implement multiword, etc. */
 
 	const StrList *selected, *walk, *locwalk;
 	if (words || locwords) {
 }
 
 /* Get previous non-METADATA partition. Needed for menu navigation */
-/* FIXME: This is *ugly*. Fix it. Can be fixed with a expand/collapse
-          list of logical partitions. At least it works. */
+/* FIXME: It can be done faster */
 static PedPartition *
 disk_get_prev_nmd_partition(PedDisk *cdisk, PedPartition *part) {
 	PedPartition *temp_a, *temp_b;
    They commited it before failing, anyway. It is a bit like a hack, I might make the functions
    make it themselves. I actually did, but I had a little trouble with the UI, so for now it is this way
  */
-/* FIXME */
+/* FIXME: It would be better if we created a copy of the disk, or implemented queuing */
 static int
 _disk_reread(PedPartition **part) {
 	int partnum;
 
 static int
 do_units () {
-	/* TODO: The shortcuts are not very cool */
 	static MenuItem units[] = {
-		{ '1' , N_("Sectors"), N_("Show the sizes in sectors") },
-		{ '2' , N_("Bytes"), N_("Show the sizes in bytes") },
-		{ '3' , N_("Kilobytes"), N_("Use 1,000 bytes as unit size") },
-		{ '4' , N_("Megabytes"), N_("Use 1,000,000 bytes as unit size") },
-		{ '5' , N_("Gigabytes"), N_("Use 1,000,000,000 bytes as unit size") },
-		{ '6' , N_("Terabytes"), N_("Use 1,000,000,000,000 bytes as unit size") },
-		{ '7', N_("Percents"), N_("Show the sizes in percents") },
-		{ '8', N_("Compact"), N_("Show the size in most appropriate units") },
-		{ '9' , N_("Kibibytes"), N_("Use 1,024 bytes as unit size") },
-		{ 'a' , N_("Mebibytes"), N_("Use 1,048,576 bytes as unit size") },
-		{ 'b' , N_("Gibibytes"), N_("Use 1,073,741,824 bytes as unit size") },
-		{ 'c', N_("Tebibytes"), N_("Use 1,099,511,627,776 bytes as unit size") },
-		{ 'd', N_("Cylinders"), N_("Show the sizes in cylinders") },
-		{ 'e', N_("CHS"), N_("Show the sizes in CHS units") },
+		{ 's' , N_("Sectors"), N_("Show the sizes in sectors") },
+		{ 'b' , N_("Bytes"), N_("Show the sizes in bytes") },
+		{ 'k' , N_("Kilobytes"), N_("Use 1,000 bytes as unit size") },
+		{ 'm' , N_("Megabytes"), N_("Use 1,000,000 bytes as unit size") },
+		{ 'g' , N_("Gigabytes"), N_("Use 1,000,000,000 bytes as unit size") },
+		{ 't' , N_("Terabytes"), N_("Use 1,000,000,000,000 bytes as unit size") },
+		{ 'c', N_("Percents"), N_("Show the sizes in percents") },
+		{ 'a', N_("Compact"), N_("Show the size in most appropriate units") },
+		{ 'K' , N_("Kibibytes"), N_("Use 1,024 bytes as unit size") },
+		{ 'M' , N_("Mebibytes"), N_("Use 1,048,576 bytes as unit size") },
+		{ 'G' , N_("Gibibytes"), N_("Use 1,073,741,824 bytes as unit size") },
+		{ 'T', N_("Tebibytes"), N_("Use 1,099,511,627,776 bytes as unit size") },
+		{ 'y', N_("Cylinders"), N_("Show the sizes in cylinders") },
+		{ 'C', N_("CHS"), N_("Show the sizes in CHS units") },
 		{ 0, NULL, NULL }
 	};
 	int key;
+	/* FIXME: If we add another way of chnaging the unit type, change this :) */
 	static int units_menu = 3;
 	//menu_title(_("Choose the display unit type")); /* Heh, no place for a title, heh */
-	key = do_menu(units, 9, MENU_BUTTON, "1234567890abcde", &units_menu);
+	key = do_menu(units, 9, MENU_BUTTON, "sbkmgtcaKMGTyh", &units_menu);
 	switch (key) {
-		case '1': ped_unit_set_default(PED_UNIT_SECTOR); return 1;
-		case '2': ped_unit_set_default(PED_UNIT_BYTE); return 1;
-		case '3': ped_unit_set_default(PED_UNIT_KILOBYTE); return 1;
-		case '4': ped_unit_set_default(PED_UNIT_MEGABYTE); return 1;
-		case '5': ped_unit_set_default(PED_UNIT_GIGABYTE); return 1;
-		case '6': ped_unit_set_default(PED_UNIT_TERABYTE); return 1;
-		case '7': ped_unit_set_default(PED_UNIT_PERCENT); return 1;
-		case '8': ped_unit_set_default(PED_UNIT_COMPACT); return 1;
-		case '9': ped_unit_set_default(PED_UNIT_KIBIBYTE); return 1;
-		case 'a': ped_unit_set_default(PED_UNIT_MEBIBYTE); return 1;
-		case 'b': ped_unit_set_default(PED_UNIT_GIBIBYTE); return 1;
-		case 'c': ped_unit_set_default(PED_UNIT_TEBIBYTE); return 1;
-		case 'd': ped_unit_set_default(PED_UNIT_CYLINDER); return 1;
-		case 'e': ped_unit_set_default(PED_UNIT_CHS); return 1;
+		case 's': ped_unit_set_default(PED_UNIT_SECTOR); return 1;
+		case 'b': ped_unit_set_default(PED_UNIT_BYTE); return 1;
+		case 'k': ped_unit_set_default(PED_UNIT_KILOBYTE); return 1;
+		case 'm': ped_unit_set_default(PED_UNIT_MEGABYTE); return 1;
+		case 'g': ped_unit_set_default(PED_UNIT_GIGABYTE); return 1;
+		case 't': ped_unit_set_default(PED_UNIT_TERABYTE); return 1;
+		case 'c': ped_unit_set_default(PED_UNIT_PERCENT); return 1;
+		case 'a': ped_unit_set_default(PED_UNIT_COMPACT); return 1;
+		case 'K': ped_unit_set_default(PED_UNIT_KIBIBYTE); return 1;
+		case 'M': ped_unit_set_default(PED_UNIT_MEBIBYTE); return 1;
+		case 'G': ped_unit_set_default(PED_UNIT_GIBIBYTE); return 1;
+		case 'T': ped_unit_set_default(PED_UNIT_TEBIBYTE); return 1;
+		case 'y': ped_unit_set_default(PED_UNIT_CYLINDER); return 1;
+		case 'C': ped_unit_set_default(PED_UNIT_CHS); return 1;
 		
 	}
 }
 		}
 		refresh();
 		key = getch();
+#if USE_KEYPAD == 0
 		if (key == ESC) {
 			key = getch();
 			if (key == '[' || key == 'O') {
 				key = getch();
 				if (key == 'B') { /* That's down arrow */
-
-					if (!flags[i+1])
-						print_warning(_("No more flags"),0);
-					else {
-						i++;
-						redraw = 1;
-					}
+					key = KEY_DOWN;
 				}
 				else if (key == 'A') { /* That's up arrow */
-					if (i == 0)
-						print_warning(_("No more flags"),0);
-					else {
-						i--;
-						redraw = 1;
-					}
+					key = KEY_UP;
 				}
 				else
 					print_warning(_("Invalid key"),0);
 			}
-			else if (key == ESC) {
-				return 1;
+			else if (key != ESC)
+				print_warning(_("Invalid key"),0);
+		}
+#endif
+		if (key == ESC)
+			return 1;
+		else if (key == KEY_DOWN) {
+			if (!flags[i+1])
+				print_warning(_("No more flags"),0);
+			else {
+				i++;
+				redraw = 1;
 			}
-			else
-				print_warning(_("Invalid key"),0);
+		}
+		else if (key == KEY_UP) {
+			if (i == 0)
+				print_warning(_("No more flags"),0);
+			else {
+				i--;
+				redraw = 1;
+			}
 		}
 		else if (key == CR || key == ' ') {
 			perform_set(disk,*part,flags[i],UI_FLAG_TOGGLE);
         { 0, NULL, NULL }
 };
 
-const char keys_ext[] = { 'm','d','u','w','q','i','h','r','x','z',UP_KEY,DOWN_KEY, '\0' };
-const char keys_free[] = { 'n','s','u','w','q','h','i',UP_KEY,DOWN_KEY, '\0' };
-const char keys_part[] = { 'b','f','c','m','y','r','o','d','t','u','w','q','i','h',UP_KEY,DOWN_KEY, '\0' };
+const char keys_ext[] = { 'm','d','u','w','q','i','h','r','x','z', ESC, '\0' };
+const char keys_free[] = { 'n','s','u','w','q','h','i', ESC, '\0' };
+const char keys_part[] = { 'b','f','c','m','y','r','o','d','t','u','w','q','i','h', ESC, '\0' };
 /*bfcayrodtuwqph*/
 
 static MenuItem partselect_menu[] = {
 	{ 0, NULL, NULL }
 };
 
-const char keys_partselect[] = { 's', ESC, UP_KEY, DOWN_KEY, '\0' };
-const char keys_cantselect[] = { ESC, UP_KEY, DOWN_KEY, '\0' };
+const char keys_partselect[] = { 's', ESC, '\0' };
+const char keys_cantselect[] = { ESC, '\0' };
 
 /* We need to separate this to use the partition list for other purposes like partition copy */
 /* FIXME Make use of redraw or get rid of it completely */
 	const char* keys;
 	PedPartition *selected = NULL;
 	PedPartition *temp,*memp;
-	MenuOptions menu_opts = MENU_DEFAULT;
+	MenuOptions menu_opts = MENU_BUTTON | MENU_ARROWS;
 	MenuItem *part_menu;
 	int menupos = 0;
 	if (!part) 
 			keys = keys_free;
 		else keys = keys_part;
 		
-		key = do_menu(part_menu, 8, MENU_BUTTON | menu_opts, keys, &menupos);
+		key = do_menu(part_menu, 8, menu_opts, keys, &menupos);
 		menu_opts &= ~MENU_LEAVE_WARNING;
-		if (key == UP_KEY) {
+		if (key == KEY_UP) {
 
 			temp = disk_get_prev_nmd_partition(*cdisk,selected);
 			if (temp) {
 			}
 			key = 0;
 		}
-		else if (key == DOWN_KEY) {
+		else if (key == KEY_DOWN) {
 			temp = ped_disk_next_partition(*cdisk,selected);
 			while (temp && temp->type & PED_PARTITION_METADATA)
 				temp = ped_disk_next_partition(*cdisk,temp);
 static void
 do_ui (void) {
 	initscr();
+	/* TODO: Maybe we should enable colouring? */
 	//start_color();
+#if USE_KEYPAD
+	keypad(stdscr,TRUE);
+#endif
 	cbreak();
 	noecho();
 	nonl();

tests/check_advanced.c

 #include <stdlib.h>
 #include <check.h>
 #include <stdio.h>
+#include <string.h>
 #include "../src/strlist.h"
 #include "../src/common.h"
 #include "functions.h"
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.