1218799Snwhitehorn/*- 2218799Snwhitehorn * Copyright (c) 2011 Nathan Whitehorn 3218799Snwhitehorn * All rights reserved. 4218799Snwhitehorn * 5218799Snwhitehorn * Redistribution and use in source and binary forms, with or without 6218799Snwhitehorn * modification, are permitted provided that the following conditions 7218799Snwhitehorn * are met: 8218799Snwhitehorn * 1. Redistributions of source code must retain the above copyright 9218799Snwhitehorn * notice, this list of conditions and the following disclaimer. 10218799Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright 11218799Snwhitehorn * notice, this list of conditions and the following disclaimer in the 12218799Snwhitehorn * documentation and/or other materials provided with the distribution. 13218799Snwhitehorn * 14218799Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15218799Snwhitehorn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16218799Snwhitehorn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17218799Snwhitehorn * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18218799Snwhitehorn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19218799Snwhitehorn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20218799Snwhitehorn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21218799Snwhitehorn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22218799Snwhitehorn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23218799Snwhitehorn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24218799Snwhitehorn * SUCH DAMAGE. 25218799Snwhitehorn * 26218799Snwhitehorn * $FreeBSD$ 27218799Snwhitehorn */ 28218799Snwhitehorn 29218799Snwhitehorn#include <stdio.h> 30218799Snwhitehorn#include <unistd.h> 31218799Snwhitehorn#include <libutil.h> 32218799Snwhitehorn#include <dialog.h> 33218799Snwhitehorn#include <dlg_keys.h> 34218799Snwhitehorn 35218799Snwhitehorn#include "diskeditor.h" 36218799Snwhitehorn 37218799Snwhitehornstatic void 38218799Snwhitehornprint_partedit_item(WINDOW *partitions, struct partedit_item *items, 39218799Snwhitehorn int item, int nscroll, int selected) 40218799Snwhitehorn{ 41218799Snwhitehorn chtype attr = A_NORMAL; 42218799Snwhitehorn char sizetext[16]; 43218799Snwhitehorn int y = item - nscroll + 1; 44218799Snwhitehorn 45218799Snwhitehorn wattrset(partitions, selected ? item_selected_attr : item_attr); 46218799Snwhitehorn wmove(partitions, y, MARGIN + items[item].indentation*2); 47226212Snwhitehorn dlg_print_text(partitions, items[item].name, 10, &attr); 48226212Snwhitehorn wmove(partitions, y, 17); 49218799Snwhitehorn wattrset(partitions, item_attr); 50218799Snwhitehorn 51218799Snwhitehorn humanize_number(sizetext, 7, items[item].size, "B", HN_AUTOSCALE, 52218799Snwhitehorn HN_DECIMAL); 53218799Snwhitehorn dlg_print_text(partitions, sizetext, 8, &attr); 54218799Snwhitehorn wmove(partitions, y, 25); 55218799Snwhitehorn dlg_print_text(partitions, items[item].type, 15, &attr); 56218799Snwhitehorn wmove(partitions, y, 40); 57218799Snwhitehorn if (items[item].mountpoint != NULL) 58218799Snwhitehorn dlg_print_text(partitions, items[item].mountpoint, 8, &attr); 59218799Snwhitehorn} 60218799Snwhitehorn 61218799Snwhitehornint 62218799Snwhitehorndiskeditor_show(const char *title, const char *cprompt, 63218799Snwhitehorn struct partedit_item *items, int nitems, int *selected, int *nscroll) 64218799Snwhitehorn{ 65218799Snwhitehorn WINDOW *dialog, *partitions; 66218799Snwhitehorn char *prompt; 67218799Snwhitehorn const char *buttons[] = 68225066Snwhitehorn { "Create", "Delete", "Modify", "Revert", "Auto", "Finish", NULL }; 69225066Snwhitehorn const char *help_text[] = { 70225066Snwhitehorn "Add a new partition", "Delete selected partition or partitions", 71225066Snwhitehorn "Change partition type or mountpoint", 72225066Snwhitehorn "Revert changes to disk setup", "Use guided partitioning tool", 73225066Snwhitehorn "Exit partitioner (will ask whether to save changes)", NULL }; 74218799Snwhitehorn int x, y; 75218799Snwhitehorn int i; 76218799Snwhitehorn int height, width, min_width; 77237428Seadler int partlist_height, partlist_width; 78218799Snwhitehorn int cur_scroll = 0; 79218799Snwhitehorn int key, fkey; 80248239Snwhitehorn int cur_button = 5, cur_part = 0; 81218799Snwhitehorn int result = DLG_EXIT_UNKNOWN; 82218799Snwhitehorn 83218799Snwhitehorn static DLG_KEYS_BINDING binding[] = { 84218799Snwhitehorn ENTERKEY_BINDINGS, 85218799Snwhitehorn DLG_KEYS_DATA( DLGK_ENTER, ' ' ), 86218799Snwhitehorn DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ), 87218799Snwhitehorn DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ), 88218799Snwhitehorn DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ), 89218799Snwhitehorn DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), 90218799Snwhitehorn DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), 91218799Snwhitehorn DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ), 92218799Snwhitehorn 93218799Snwhitehorn SCROLLKEY_BINDINGS, 94218799Snwhitehorn END_KEYS_BINDING 95218799Snwhitehorn }; 96218799Snwhitehorn 97218799Snwhitehorn /* 98218799Snwhitehorn * Set up editor window. 99218799Snwhitehorn */ 100218799Snwhitehorn prompt = dlg_strclone(cprompt); 101218799Snwhitehorn 102218799Snwhitehorn min_width = 50; 103218799Snwhitehorn height = width = 0; 104218799Snwhitehorn partlist_height = 10; 105218799Snwhitehorn dlg_tab_correct_str(prompt); 106218799Snwhitehorn dlg_button_layout(buttons, &min_width); 107218799Snwhitehorn dlg_auto_size(title, prompt, &height, &width, 2, min_width); 108218799Snwhitehorn height += partlist_height; 109218799Snwhitehorn partlist_width = width - 2*MARGIN; 110218799Snwhitehorn dlg_print_size(height, width); 111218799Snwhitehorn dlg_ctl_size(height, width); 112218799Snwhitehorn 113218799Snwhitehorn x = dlg_box_x_ordinate(width); 114218799Snwhitehorn y = dlg_box_y_ordinate(height); 115218799Snwhitehorn 116218799Snwhitehorn dialog = dlg_new_window(height, width, y, x); 117218799Snwhitehorn dlg_register_window(dialog, "diskeditorbox", binding); 118218799Snwhitehorn dlg_register_buttons(dialog, "diskeditorbox", buttons); 119218799Snwhitehorn 120218799Snwhitehorn dlg_draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); 121218799Snwhitehorn dlg_draw_bottom_box(dialog); 122218799Snwhitehorn dlg_draw_title(dialog, title); 123218799Snwhitehorn wattrset(dialog, dialog_attr); 124218799Snwhitehorn 125218799Snwhitehorn /* Partition list sub-window */ 126218799Snwhitehorn partitions = dlg_sub_window(dialog, partlist_height, partlist_width, 127218799Snwhitehorn y + 3, x + 1); 128218799Snwhitehorn dlg_register_window(partitions, "partlist", binding); 129218799Snwhitehorn dlg_register_buttons(partitions, "partlist", buttons); 130218799Snwhitehorn wattrset(partitions, menubox_attr); 131218799Snwhitehorn 132225066Snwhitehorn dlg_item_help(help_text[cur_button]); 133218799Snwhitehorn dlg_draw_buttons(dialog, height - 2*MARGIN, 0, buttons, 134218799Snwhitehorn cur_button, FALSE, width); 135218799Snwhitehorn dlg_print_autowrap(dialog, prompt, height, width); 136218799Snwhitehorn 137218799Snwhitehorn if (selected != NULL) 138218799Snwhitehorn cur_part = *selected; 139218799Snwhitehorn if (nscroll != NULL) 140218799Snwhitehorn cur_scroll = *nscroll; 141218799Snwhitehorn if (cur_part - cur_scroll >= partlist_height - 2 || 142218799Snwhitehorn cur_part - cur_scroll < 0) 143218799Snwhitehorn cur_scroll = cur_part; 144218799Snwhitehorn 145218799Snwhitehornrepaint: 146218799Snwhitehorn dlg_draw_box(dialog, 3, 1, partlist_height, partlist_width, 147218799Snwhitehorn menubox_border_attr, menubox_attr); 148218799Snwhitehorn for (i = cur_scroll; i < MIN(cur_scroll + partlist_height - 2, nitems); 149218799Snwhitehorn i++) 150218799Snwhitehorn print_partedit_item(partitions, items, i, cur_scroll, 151218799Snwhitehorn i == cur_part); 152218799Snwhitehorn if (nitems > partlist_height - 2) 153218799Snwhitehorn dlg_draw_arrows(partitions, cur_scroll > 0, 154218799Snwhitehorn nitems > cur_scroll + partlist_height - 2, 155218799Snwhitehorn partlist_width - 5, 0, partlist_height - 1); 156218799Snwhitehorn wrefresh(partitions); 157218799Snwhitehorn 158218799Snwhitehorn while (result == DLG_EXIT_UNKNOWN) { 159218799Snwhitehorn key = dlg_mouse_wgetch(dialog, &fkey); 160218799Snwhitehorn if ((i = dlg_char_to_button(key, buttons)) >= 0) { 161218799Snwhitehorn cur_button = i; 162225066Snwhitehorn dlg_item_help(help_text[cur_button]); 163218799Snwhitehorn dlg_draw_buttons(dialog, height - 2*MARGIN, 0, buttons, 164218799Snwhitehorn cur_button, FALSE, width); 165218799Snwhitehorn break; 166218799Snwhitehorn } 167218799Snwhitehorn 168218799Snwhitehorn if (!fkey) 169218799Snwhitehorn continue; 170218799Snwhitehorn 171218799Snwhitehorn switch (key) { 172218799Snwhitehorn case DLGK_FIELD_NEXT: 173218799Snwhitehorn cur_button = dlg_next_button(buttons, cur_button); 174218799Snwhitehorn if (cur_button < 0) 175218799Snwhitehorn cur_button = 0; 176225066Snwhitehorn dlg_item_help(help_text[cur_button]); 177218799Snwhitehorn dlg_draw_buttons(dialog, height - 2*MARGIN, 0, buttons, 178218799Snwhitehorn cur_button, FALSE, width); 179218799Snwhitehorn break; 180218799Snwhitehorn case DLGK_FIELD_PREV: 181218799Snwhitehorn cur_button = dlg_prev_button(buttons, cur_button); 182218799Snwhitehorn if (cur_button < 0) 183218799Snwhitehorn cur_button = 0; 184225066Snwhitehorn dlg_item_help(help_text[cur_button]); 185218799Snwhitehorn dlg_draw_buttons(dialog, height - 2*MARGIN, 0, buttons, 186218799Snwhitehorn cur_button, FALSE, width); 187218799Snwhitehorn break; 188218799Snwhitehorn case DLGK_ITEM_NEXT: 189218799Snwhitehorn if (cur_part == nitems - 1) 190218799Snwhitehorn break; /* End of list */ 191218799Snwhitehorn 192218799Snwhitehorn /* Deselect old item */ 193218799Snwhitehorn print_partedit_item(partitions, items, cur_part, 194218799Snwhitehorn cur_scroll, 0); 195218799Snwhitehorn /* Select new item */ 196218799Snwhitehorn cur_part++; 197218799Snwhitehorn if (cur_part - cur_scroll >= partlist_height - 2) { 198218799Snwhitehorn cur_scroll = cur_part; 199218799Snwhitehorn goto repaint; 200218799Snwhitehorn } 201218799Snwhitehorn print_partedit_item(partitions, items, cur_part, 202218799Snwhitehorn cur_scroll, 1); 203218799Snwhitehorn wrefresh(partitions); 204218799Snwhitehorn break; 205218799Snwhitehorn case DLGK_ITEM_PREV: 206218799Snwhitehorn if (cur_part == 0) 207218799Snwhitehorn break; /* Start of list */ 208218799Snwhitehorn 209218799Snwhitehorn /* Deselect old item */ 210218799Snwhitehorn print_partedit_item(partitions, items, cur_part, 211218799Snwhitehorn cur_scroll, 0); 212218799Snwhitehorn /* Select new item */ 213218799Snwhitehorn cur_part--; 214218799Snwhitehorn if (cur_part - cur_scroll < 0) { 215218799Snwhitehorn cur_scroll = cur_part; 216218799Snwhitehorn goto repaint; 217218799Snwhitehorn } 218218799Snwhitehorn print_partedit_item(partitions, items, cur_part, 219218799Snwhitehorn cur_scroll, 1); 220218799Snwhitehorn wrefresh(partitions); 221218799Snwhitehorn break; 222218799Snwhitehorn case DLGK_PAGE_NEXT: 223218799Snwhitehorn cur_scroll += (partlist_height - 2); 224218799Snwhitehorn if (cur_scroll + partlist_height - 2 >= nitems) 225218799Snwhitehorn cur_scroll = nitems - (partlist_height - 2); 226225066Snwhitehorn if (cur_scroll < 0) 227225066Snwhitehorn cur_scroll = 0; 228218799Snwhitehorn if (cur_part < cur_scroll) 229218799Snwhitehorn cur_part = cur_scroll; 230218799Snwhitehorn goto repaint; 231218799Snwhitehorn case DLGK_PAGE_PREV: 232218799Snwhitehorn cur_scroll -= (partlist_height - 2); 233218799Snwhitehorn if (cur_scroll < 0) 234218799Snwhitehorn cur_scroll = 0; 235218799Snwhitehorn if (cur_part >= cur_scroll + partlist_height - 2) 236218799Snwhitehorn cur_part = cur_scroll; 237218799Snwhitehorn goto repaint; 238218799Snwhitehorn case DLGK_PAGE_FIRST: 239218799Snwhitehorn cur_scroll = 0; 240218799Snwhitehorn cur_part = cur_scroll; 241218799Snwhitehorn goto repaint; 242218799Snwhitehorn case DLGK_PAGE_LAST: 243218799Snwhitehorn cur_scroll = nitems - (partlist_height - 2); 244225066Snwhitehorn if (cur_scroll < 0) 245225066Snwhitehorn cur_scroll = 0; 246218799Snwhitehorn cur_part = cur_scroll; 247218799Snwhitehorn goto repaint; 248218799Snwhitehorn case DLGK_ENTER: 249218799Snwhitehorn goto done; 250218799Snwhitehorn default: 251218799Snwhitehorn if (is_DLGK_MOUSE(key)) { 252218799Snwhitehorn cur_button = key - M_EVENT; 253225066Snwhitehorn dlg_item_help(help_text[cur_button]); 254218799Snwhitehorn dlg_draw_buttons(dialog, height - 2*MARGIN, 0, 255218799Snwhitehorn buttons, cur_button, FALSE, width); 256218799Snwhitehorn goto done; 257218799Snwhitehorn } 258218799Snwhitehorn break; 259218799Snwhitehorn } 260218799Snwhitehorn } 261218799Snwhitehorn 262218799Snwhitehorndone: 263218799Snwhitehorn if (selected != NULL) 264218799Snwhitehorn *selected = cur_part; 265218799Snwhitehorn if (nscroll != NULL) 266218799Snwhitehorn *nscroll = cur_scroll; 267218799Snwhitehorn 268218799Snwhitehorn dlg_del_window(partitions); 269218799Snwhitehorn dlg_del_window(dialog); 270218799Snwhitehorn dlg_mouse_free_regions(); 271218799Snwhitehorn 272218799Snwhitehorn return (cur_button); 273218799Snwhitehorn} 274218799Snwhitehorn 275