bc3b375f |
# Copyright (C) 2015 vmware inc.
#
# Author: Mahmoud Bassiouny <mbassiouny@vmware.com>
import curses
from actionresult import ActionResult
from action import Action
class TextPane(Action): |
c533b308 |
def __init__(self, starty, maxx, width, text_file_path, height,
menu_items, partition=False, popupWindow=False,
install_config={}, text_items=[], table_space=0,
default_start=0, info=[], size_left=[]): |
bc3b375f |
self.head_position = 0 #This is the start of showing |
72832a72 |
self.menu_position = default_start |
bc3b375f |
self.lines = [] |
72832a72 |
self.menu_items = menu_items
self.text_items = text_items
self.table_space = table_space |
c533b308 |
self.info = info
self.size_left = size_left |
bc3b375f |
self.width = width |
c533b308 |
|
72832a72 |
if partition == False: |
c533b308 |
self.read_file(text_file_path, self.width - 3) |
72832a72 |
else: |
c533b308 |
self.install_config = install_config
self.partition()
|
bc3b375f |
self.num_items = len(self.lines) |
72832a72 |
if self.info:
self.text_height = height - 4
else:
self.text_height = height - 2 |
bc3b375f |
# Check if we need to add a scroll bar
if self.num_items > self.text_height:
self.show_scroll = True
else:
self.show_scroll = False
# Some calculation to detitmine the size of the scroll filled portion |
c533b308 |
if self.num_items == 0: |
72832a72 |
self.filled = 0
else:
self.filled = int(round(self.text_height * self.text_height / float(self.num_items))) |
bc3b375f |
if self.filled == 0:
self.filled += 1
for i in [1, 2]: |
c533b308 |
if ((self.num_items - self.text_height) >= i and
(self.text_height - self.filled) == (i - 1)): |
bc3b375f |
self.filled -= 1
self.window = curses.newwin(height, self.width)
self.window.bkgd(' ', curses.color_pair(2)) |
72832a72 |
self.popupWindow = popupWindow |
bc3b375f |
self.window.keypad(1)
self.panel = curses.panel.new_panel(self.window)
|
0c250142 |
self.panel.move(starty, (maxx - self.width) // 2) |
bc3b375f |
self.panel.hide()
curses.panel.update_panels()
|
72832a72 |
def partition(self):
if self.install_config == {}:
return
tstring = ''
#calculate the start index for each item and draw the title
for index, item in enumerate(self.text_items):
tstring = tstring + item[0] + ' '*(item[1] - len(item[0])) + ' '*self.table_space
self.lines.append(tstring)
#draw the table |
c533b308 |
for i in range(int(self.install_config['partitionsnumber'])): |
72832a72 |
pdisk = self.install_config['partition_disk']
if len(pdisk) > self.text_items[0][1]:
pdisk = pdisk[-self.text_items[0][1]:]
psize = self.install_config[str(i)+'partition_info'+str(0)]
if len(psize) > self.text_items[1][1]:
psize = psize[-self.text_items[1][1]:] |
c533b308 |
if len(psize) == 0:
psize = '<' + self.size_left + '>'
ptype = self.install_config[str(i) + 'partition_info' + str(1)] |
72832a72 |
if len(ptype) > self.text_items[2][1]:
ptype = ptype[-self.text_items[2][1]:] |
c533b308 |
pmountpoint = self.install_config[str(i) + 'partition_info' + str(2)] |
72832a72 |
if len(pmountpoint) > self.text_items[3][1]:
pmountpoint = pmountpoint[-self.text_items[3][1]:] |
c533b308 |
pstring = (pdisk + ' '*(self.text_items[0][1] - len(pdisk)) +
' ' * self.table_space + psize +
' '*(self.text_items[1][1] - len(psize)) +
' ' * self.table_space + ptype +
' '*(self.text_items[2][1] - len(ptype) +
self.table_space) + pmountpoint) |
72832a72 |
self.lines.append(pstring)
|
bc3b375f |
def read_file(self, text_file_path, line_width): |
a672bd24 |
with open(text_file_path, "rb") as f: |
bc3b375f |
for line in f: |
286a6cae |
# expand tab to 8 spaces. |
a672bd24 |
try:
line = line.decode(encoding='latin1')
except UnicodeDecodeError:
pass |
286a6cae |
line = line.expandtabs() |
bbfff61b |
indent = len(line) - len(line.lstrip())
actual_line_width = line_width - indent
line = line.strip() |
bc3b375f |
# Adjust the words on the lines |
bbfff61b |
while len(line) > actual_line_width:
sep_index = actual_line_width |
bb4b7c31 |
while sep_index > 0 and line[sep_index-1] != ' ' and line[sep_index] != ' ': |
bc3b375f |
sep_index = sep_index - 1 |
bb4b7c31 |
|
c533b308 |
current_line_width = sep_index |
bb4b7c31 |
if sep_index == 0: |
bbfff61b |
current_line_width = actual_line_width |
bb4b7c31 |
currLine = line[:current_line_width]
line = line[current_line_width:] |
286a6cae |
line = line.strip() |
bc3b375f |
# Lengthen the line with spaces |
c533b308 |
self.lines.append(' ' * indent + currLine +
' ' *(actual_line_width - len(currLine))) |
bc3b375f |
# lengthen the line with spaces |
bbfff61b |
self.lines.append(' ' * indent + line + ' ' *(actual_line_width - len(line))) |
bc3b375f |
def navigate(self, n): |
72832a72 |
if self.show_scroll:
self.head_position += n
if self.head_position < 0:
self.head_position = 0
elif self.head_position > (len(self.lines) - self.text_height + 1):
self.head_position = len(self.lines) - self.text_height + 1 |
bc3b375f |
def navigate_menu(self, n):
self.menu_position += n
if self.menu_position < 0:
self.menu_position = 0
elif self.menu_position >= len(self.menu_items):
self.menu_position = len(self.menu_items) - 1
def render_scroll_bar(self):
if self.show_scroll:
remaining_above = self.head_position
remaining_down = self.num_items - self.text_height - self.head_position# |
c533b308 |
|
bc3b375f |
up = int(round(remaining_above * self.text_height / float(self.num_items)))
down = self.text_height - up - self.filled
if up == 0 and remaining_above > 0:
up += 1
down -= 1
if down == 0 and remaining_down > 0:
up -= 1
down += 1
if remaining_down == 0 and down != 0:
up += down
down = 0
for index in range(up):
self.window.addch(index, self.width - 2, curses.ACS_CKBOARD)
for index in range(self.filled):
self.window.addstr(index + up, self.width - 2, ' ', curses.A_REVERSE)
for index in range(down):
self.window.addch(index + up + self.filled, self.width - 2, curses.ACS_CKBOARD)
def refresh(self):
self.window.clear()
for index, line in enumerate(self.lines): |
c533b308 |
if index < self.head_position: |
bc3b375f |
continue |
c533b308 |
elif index > self.head_position + self.text_height - 1: |
bc3b375f |
continue
x = 0
y = index - self.head_position
if len(line) > 0:
self.window.addstr(y, x, line)
xpos = self.width
for index, item in enumerate(self.menu_items):
if index == self.menu_position:
mode = curses.color_pair(3)
else:
mode = curses.color_pair(2) |
72832a72 |
if self.info:
self.window.addstr(self.text_height + 3, xpos - len(item[0]) - 4, item[0], mode)
else:
self.window.addstr(self.text_height + 1, xpos - len(item[0]) - 4, item[0], mode) |
bc3b375f |
xpos = xpos - len(item[0]) - 4
|
72832a72 |
if self.info:
self.window.addstr(self.text_height+1, 5, self.info)
|
bc3b375f |
self.render_scroll_bar()
self.window.refresh()
self.panel.top()
self.panel.show()
curses.panel.update_panels()
curses.doupdate()
def hide(self):
self.panel.hide()
curses.panel.update_panels()
curses.doupdate()
def do_action(self):
while True:
self.refresh()
key = self.window.getch()
if key in [curses.KEY_ENTER, ord('\n')]:
self.hide()
return self.menu_items[self.menu_position][1]()
if key == curses.KEY_UP:
self.navigate(-1)
elif key == curses.KEY_DOWN:
self.navigate(1)
elif key == curses.KEY_LEFT:
self.navigate_menu(1)
elif key == curses.KEY_RIGHT:
self.navigate_menu(-1)
elif key == curses.KEY_NPAGE:
self.navigate(self.text_height)
elif key == curses.KEY_PPAGE:
self.navigate(-self.text_height)
elif key == curses.KEY_HOME:
self.head_position = 0 |