2011-02-18 14:54:34 +00:00
|
|
|
/*-
|
|
|
|
* Copyright (c) 2011 Nathan Whitehorn
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
* $FreeBSD$
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <libutil.h>
|
|
|
|
#include <dialog.h>
|
|
|
|
#include <dlg_keys.h>
|
|
|
|
|
|
|
|
#include "diskeditor.h"
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_partedit_item(WINDOW *partitions, struct partedit_item *items,
|
|
|
|
int item, int nscroll, int selected)
|
|
|
|
{
|
|
|
|
chtype attr = A_NORMAL;
|
|
|
|
char sizetext[16];
|
|
|
|
int y = item - nscroll + 1;
|
|
|
|
|
|
|
|
wattrset(partitions, selected ? item_selected_attr : item_attr);
|
|
|
|
wmove(partitions, y, MARGIN + items[item].indentation*2);
|
2011-10-07 01:40:30 +00:00
|
|
|
dlg_print_text(partitions, items[item].name, 10, &attr);
|
|
|
|
wmove(partitions, y, 17);
|
2011-02-18 14:54:34 +00:00
|
|
|
wattrset(partitions, item_attr);
|
|
|
|
|
|
|
|
humanize_number(sizetext, 7, items[item].size, "B", HN_AUTOSCALE,
|
|
|
|
HN_DECIMAL);
|
|
|
|
dlg_print_text(partitions, sizetext, 8, &attr);
|
|
|
|
wmove(partitions, y, 25);
|
|
|
|
dlg_print_text(partitions, items[item].type, 15, &attr);
|
|
|
|
wmove(partitions, y, 40);
|
|
|
|
if (items[item].mountpoint != NULL)
|
|
|
|
dlg_print_text(partitions, items[item].mountpoint, 8, &attr);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
diskeditor_show(const char *title, const char *cprompt,
|
|
|
|
struct partedit_item *items, int nitems, int *selected, int *nscroll)
|
|
|
|
{
|
|
|
|
WINDOW *dialog, *partitions;
|
|
|
|
char *prompt;
|
|
|
|
const char *buttons[] =
|
2011-08-21 18:50:30 +00:00
|
|
|
{ "Create", "Delete", "Modify", "Revert", "Auto", "Finish", NULL };
|
|
|
|
const char *help_text[] = {
|
|
|
|
"Add a new partition", "Delete selected partition or partitions",
|
|
|
|
"Change partition type or mountpoint",
|
|
|
|
"Revert changes to disk setup", "Use guided partitioning tool",
|
|
|
|
"Exit partitioner (will ask whether to save changes)", NULL };
|
2011-02-18 14:54:34 +00:00
|
|
|
int x, y;
|
|
|
|
int i;
|
|
|
|
int height, width, min_width;
|
2012-06-19 06:09:47 +00:00
|
|
|
int partlist_height, partlist_width;
|
2011-02-18 14:54:34 +00:00
|
|
|
int cur_scroll = 0;
|
|
|
|
int key, fkey;
|
2013-01-20 03:55:08 +00:00
|
|
|
int cur_button = 5, cur_part = 0;
|
2011-02-18 14:54:34 +00:00
|
|
|
int result = DLG_EXIT_UNKNOWN;
|
|
|
|
|
|
|
|
static DLG_KEYS_BINDING binding[] = {
|
|
|
|
ENTERKEY_BINDINGS,
|
|
|
|
DLG_KEYS_DATA( DLGK_ENTER, ' ' ),
|
|
|
|
DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ),
|
|
|
|
DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ),
|
|
|
|
DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
|
|
|
|
DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
|
|
|
|
DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
|
|
|
|
DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ),
|
|
|
|
|
|
|
|
SCROLLKEY_BINDINGS,
|
|
|
|
END_KEYS_BINDING
|
|
|
|
};
|
|
|
|
|
2013-06-17 15:16:14 +00:00
|
|
|
static DLG_KEYS_BINDING binding2[] = {
|
|
|
|
INPUTSTR_BINDINGS,
|
|
|
|
ENTERKEY_BINDINGS,
|
|
|
|
DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
|
|
|
|
DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
|
|
|
|
DLG_KEYS_DATA( DLGK_ITEM_NEXT, CHR_NEXT ),
|
|
|
|
DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ),
|
|
|
|
DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_NEXT ),
|
|
|
|
DLG_KEYS_DATA( DLGK_ITEM_PREV, CHR_PREVIOUS ),
|
|
|
|
DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_PREVIOUS ),
|
|
|
|
DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ),
|
|
|
|
DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ),
|
|
|
|
DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ),
|
|
|
|
END_KEYS_BINDING
|
|
|
|
};
|
|
|
|
|
2011-02-18 14:54:34 +00:00
|
|
|
/*
|
|
|
|
* Set up editor window.
|
|
|
|
*/
|
|
|
|
prompt = dlg_strclone(cprompt);
|
|
|
|
|
|
|
|
min_width = 50;
|
|
|
|
height = width = 0;
|
|
|
|
partlist_height = 10;
|
|
|
|
dlg_tab_correct_str(prompt);
|
|
|
|
dlg_button_layout(buttons, &min_width);
|
|
|
|
dlg_auto_size(title, prompt, &height, &width, 2, min_width);
|
|
|
|
height += partlist_height;
|
|
|
|
partlist_width = width - 2*MARGIN;
|
|
|
|
dlg_print_size(height, width);
|
|
|
|
dlg_ctl_size(height, width);
|
|
|
|
|
|
|
|
x = dlg_box_x_ordinate(width);
|
|
|
|
y = dlg_box_y_ordinate(height);
|
|
|
|
|
|
|
|
dialog = dlg_new_window(height, width, y, x);
|
|
|
|
dlg_register_window(dialog, "diskeditorbox", binding);
|
|
|
|
dlg_register_buttons(dialog, "diskeditorbox", buttons);
|
|
|
|
|
|
|
|
dlg_draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
|
|
|
|
dlg_draw_bottom_box(dialog);
|
|
|
|
dlg_draw_title(dialog, title);
|
|
|
|
wattrset(dialog, dialog_attr);
|
|
|
|
|
|
|
|
/* Partition list sub-window */
|
|
|
|
partitions = dlg_sub_window(dialog, partlist_height, partlist_width,
|
|
|
|
y + 3, x + 1);
|
2013-06-17 15:16:14 +00:00
|
|
|
dlg_register_window(partitions, "partlist", binding2);
|
2011-02-18 14:54:34 +00:00
|
|
|
dlg_register_buttons(partitions, "partlist", buttons);
|
|
|
|
wattrset(partitions, menubox_attr);
|
|
|
|
|
2011-08-21 18:50:30 +00:00
|
|
|
dlg_item_help(help_text[cur_button]);
|
2011-02-18 14:54:34 +00:00
|
|
|
dlg_draw_buttons(dialog, height - 2*MARGIN, 0, buttons,
|
|
|
|
cur_button, FALSE, width);
|
|
|
|
dlg_print_autowrap(dialog, prompt, height, width);
|
|
|
|
|
|
|
|
if (selected != NULL)
|
|
|
|
cur_part = *selected;
|
|
|
|
if (nscroll != NULL)
|
|
|
|
cur_scroll = *nscroll;
|
|
|
|
if (cur_part - cur_scroll >= partlist_height - 2 ||
|
|
|
|
cur_part - cur_scroll < 0)
|
|
|
|
cur_scroll = cur_part;
|
|
|
|
|
|
|
|
repaint:
|
|
|
|
dlg_draw_box(dialog, 3, 1, partlist_height, partlist_width,
|
|
|
|
menubox_border_attr, menubox_attr);
|
|
|
|
for (i = cur_scroll; i < MIN(cur_scroll + partlist_height - 2, nitems);
|
|
|
|
i++)
|
|
|
|
print_partedit_item(partitions, items, i, cur_scroll,
|
|
|
|
i == cur_part);
|
|
|
|
if (nitems > partlist_height - 2)
|
|
|
|
dlg_draw_arrows(partitions, cur_scroll > 0,
|
|
|
|
nitems > cur_scroll + partlist_height - 2,
|
|
|
|
partlist_width - 5, 0, partlist_height - 1);
|
|
|
|
wrefresh(partitions);
|
|
|
|
|
|
|
|
while (result == DLG_EXIT_UNKNOWN) {
|
|
|
|
key = dlg_mouse_wgetch(dialog, &fkey);
|
|
|
|
if ((i = dlg_char_to_button(key, buttons)) >= 0) {
|
|
|
|
cur_button = i;
|
2011-08-21 18:50:30 +00:00
|
|
|
dlg_item_help(help_text[cur_button]);
|
2011-02-18 14:54:34 +00:00
|
|
|
dlg_draw_buttons(dialog, height - 2*MARGIN, 0, buttons,
|
|
|
|
cur_button, FALSE, width);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!fkey)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
switch (key) {
|
|
|
|
case DLGK_FIELD_NEXT:
|
|
|
|
cur_button = dlg_next_button(buttons, cur_button);
|
|
|
|
if (cur_button < 0)
|
|
|
|
cur_button = 0;
|
2011-08-21 18:50:30 +00:00
|
|
|
dlg_item_help(help_text[cur_button]);
|
2011-02-18 14:54:34 +00:00
|
|
|
dlg_draw_buttons(dialog, height - 2*MARGIN, 0, buttons,
|
|
|
|
cur_button, FALSE, width);
|
|
|
|
break;
|
|
|
|
case DLGK_FIELD_PREV:
|
|
|
|
cur_button = dlg_prev_button(buttons, cur_button);
|
|
|
|
if (cur_button < 0)
|
|
|
|
cur_button = 0;
|
2011-08-21 18:50:30 +00:00
|
|
|
dlg_item_help(help_text[cur_button]);
|
2011-02-18 14:54:34 +00:00
|
|
|
dlg_draw_buttons(dialog, height - 2*MARGIN, 0, buttons,
|
|
|
|
cur_button, FALSE, width);
|
|
|
|
break;
|
|
|
|
case DLGK_ITEM_NEXT:
|
|
|
|
if (cur_part == nitems - 1)
|
|
|
|
break; /* End of list */
|
|
|
|
|
|
|
|
/* Deselect old item */
|
|
|
|
print_partedit_item(partitions, items, cur_part,
|
|
|
|
cur_scroll, 0);
|
|
|
|
/* Select new item */
|
|
|
|
cur_part++;
|
|
|
|
if (cur_part - cur_scroll >= partlist_height - 2) {
|
|
|
|
cur_scroll = cur_part;
|
|
|
|
goto repaint;
|
|
|
|
}
|
|
|
|
print_partedit_item(partitions, items, cur_part,
|
|
|
|
cur_scroll, 1);
|
|
|
|
wrefresh(partitions);
|
|
|
|
break;
|
|
|
|
case DLGK_ITEM_PREV:
|
|
|
|
if (cur_part == 0)
|
|
|
|
break; /* Start of list */
|
|
|
|
|
|
|
|
/* Deselect old item */
|
|
|
|
print_partedit_item(partitions, items, cur_part,
|
|
|
|
cur_scroll, 0);
|
|
|
|
/* Select new item */
|
|
|
|
cur_part--;
|
|
|
|
if (cur_part - cur_scroll < 0) {
|
|
|
|
cur_scroll = cur_part;
|
|
|
|
goto repaint;
|
|
|
|
}
|
|
|
|
print_partedit_item(partitions, items, cur_part,
|
|
|
|
cur_scroll, 1);
|
|
|
|
wrefresh(partitions);
|
|
|
|
break;
|
|
|
|
case DLGK_PAGE_NEXT:
|
|
|
|
cur_scroll += (partlist_height - 2);
|
|
|
|
if (cur_scroll + partlist_height - 2 >= nitems)
|
|
|
|
cur_scroll = nitems - (partlist_height - 2);
|
2011-08-21 18:50:30 +00:00
|
|
|
if (cur_scroll < 0)
|
|
|
|
cur_scroll = 0;
|
2011-02-18 14:54:34 +00:00
|
|
|
if (cur_part < cur_scroll)
|
|
|
|
cur_part = cur_scroll;
|
|
|
|
goto repaint;
|
|
|
|
case DLGK_PAGE_PREV:
|
|
|
|
cur_scroll -= (partlist_height - 2);
|
|
|
|
if (cur_scroll < 0)
|
|
|
|
cur_scroll = 0;
|
|
|
|
if (cur_part >= cur_scroll + partlist_height - 2)
|
|
|
|
cur_part = cur_scroll;
|
|
|
|
goto repaint;
|
|
|
|
case DLGK_PAGE_FIRST:
|
|
|
|
cur_scroll = 0;
|
|
|
|
cur_part = cur_scroll;
|
|
|
|
goto repaint;
|
|
|
|
case DLGK_PAGE_LAST:
|
|
|
|
cur_scroll = nitems - (partlist_height - 2);
|
2011-08-21 18:50:30 +00:00
|
|
|
if (cur_scroll < 0)
|
|
|
|
cur_scroll = 0;
|
2011-02-18 14:54:34 +00:00
|
|
|
cur_part = cur_scroll;
|
|
|
|
goto repaint;
|
|
|
|
case DLGK_ENTER:
|
|
|
|
goto done;
|
|
|
|
default:
|
|
|
|
if (is_DLGK_MOUSE(key)) {
|
|
|
|
cur_button = key - M_EVENT;
|
2011-08-21 18:50:30 +00:00
|
|
|
dlg_item_help(help_text[cur_button]);
|
2011-02-18 14:54:34 +00:00
|
|
|
dlg_draw_buttons(dialog, height - 2*MARGIN, 0,
|
|
|
|
buttons, cur_button, FALSE, width);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
if (selected != NULL)
|
|
|
|
*selected = cur_part;
|
|
|
|
if (nscroll != NULL)
|
|
|
|
*nscroll = cur_scroll;
|
|
|
|
|
|
|
|
dlg_del_window(partitions);
|
|
|
|
dlg_del_window(dialog);
|
|
|
|
dlg_mouse_free_regions();
|
|
|
|
|
|
|
|
return (cur_button);
|
|
|
|
}
|
|
|
|
|