installer/window.py
f4d17450
 #
 #    Copyright (C) 2015 vmware inc.
 #
 #    Author: Mahmoud Bassiouny <mbassiouny@vmware.com>
 
 import curses
 from actionresult import ActionResult
 from action import Action
 
 class Window(Action):
 
c533b308
     def __init__(self, height, width, maxy, maxx, title, can_go_back,
                  action_panel=None, items=None, menu_helper=None, position=0,
                  tab_enabled=True, can_go_next=False, read_text=False):
f4d17450
         self.can_go_back = can_go_back
72832a72
         self.can_go_next = can_go_next
f4d17450
         self.height = height
c533b308
         self.width = width
0c250142
         self.y = (maxy - height) // 2
c533b308
         self.x = (maxx - width) // 2
f4d17450
         title = ' ' + title + ' '
 
         self.contentwin = curses.newwin(height - 1, width -1)
         self.contentwin.bkgd(' ', curses.color_pair(2)) #Default Window color
         self.contentwin.erase()
         self.contentwin.box()
c533b308
         self.tab_enabled = tab_enabled
         self.read_text = read_text
72832a72
 
         self.position = position
a672bd24
         if items:
             self.items = items
         else:
             self.items = []
72832a72
         self.menu_helper = menu_helper
c533b308
         self.contentwin.addstr(0, (width - 1 - len(title)) // 2, title)#
         newy = 5
72832a72
 
f4d17450
         if self.can_go_back:
             self.contentwin.addstr(height - 3, 5, '<Go Back>')
72832a72
         if self.can_go_next and self.can_go_back:
             self.update_next_item()
 
         self.dist = 0
 
a672bd24
         if len(self.items) > 0:
72832a72
         #To select items, we need to identify up left right keys
 
c533b308
             self.dist = self.width-11
             self.dist -= len('<Go Back>')
             count = 0
72832a72
             for item in self.items:
c533b308
                 self.dist -= len(item[0])
                 count += 1
             self.dist = self.dist // count
72832a72
             self.contentwin.keypad(1)
             newy += len('<Go Back>')
             newy += self.dist
             for item in self.items:
                 self.contentwin.addstr(height - 3, newy, item[0])
                 newy += len(item[0])
                 newy += self.dist
f4d17450
 
         self.textwin = curses.newwin(height - 5, width - 5)
         self.textwin.bkgd(' ', curses.color_pair(2)) #Default Window color
 
         self.shadowwin = curses.newwin(height - 1, width - 1)
         self.shadowwin.bkgd(' ', curses.color_pair(0)) #Default shadow color
 
         self.contentpanel = curses.panel.new_panel(self.contentwin)
         self.textpanel = curses.panel.new_panel(self.textwin)
         self.shadowpanel = curses.panel.new_panel(self.shadowwin)
 
         self.action_panel = action_panel
72832a72
         self.refresh(0, True)
f4d17450
         self.hide_window()
 
72832a72
     def update_next_item(self):
c533b308
         self.position = 1
72832a72
         self.items.append(('<Next>', self.next_function, False))
c533b308
         self.tab_enabled = False
72832a72
 
 
     def next_function(self, params):
         return ActionResult(True, None)
 
f4d17450
     def set_action_panel(self, action_panel):
         self.action_panel = action_panel
 
c533b308
     def update_menu(self, action_result):
         if (action_result.result and
                 'goNext' in action_result.result and
                 action_result.result['goNext']):
72832a72
             return ActionResult(True, None)
         if self.position == 0:
             self.contentwin.addstr(self.height - 3, 5, '<Go Back>')
             self.contentwin.refresh()
             self.hide_window()
             self.action_panel.hide()
             return ActionResult(False, None)
         else:
c533b308
             if (action_result.result != None and
                     'diskIndex' in action_result.result):
72832a72
                 params = action_result.result['diskIndex']
                 if self.menu_helper:
                     self.menu_helper(params)
 
             result = self.items[self.position-1][1](None)
             if result.success:
                 self.hide_window()
                 self.action_panel.hide()
                 return result
             else:
                 if 'goBack' in result.result and result.result['goBack']:
                     self.contentwin.refresh()
                     self.hide_window()
                     self.action_panel.hide()
                     return ActionResult(False, None)
 
f4d17450
     def do_action(self):
         self.show_window()
72832a72
         if self.tab_enabled:
             self.refresh(0, False)
         else:
             self.refresh(0, True)
f4d17450
         action_result = self.action_panel.do_action()
 
         if action_result.success:
c533b308
             if (action_result.result and
                     'goNext' in action_result.result and
                     action_result.result['goNext']):
72832a72
                 return ActionResult(True, None)
c533b308
             if self.position != 0:    #saving the disk index
72832a72
                 self.items[self.position-1][1](None)
             if self.items:
                 return self.update_menu(action_result)
f4d17450
             self.hide_window()
             return action_result
         else:
c533b308
             if (not self.tab_enabled and
                     action_result.result != None and
                     'direction' in action_result.result):
72832a72
                 self.refresh(action_result.result['direction'], True)
c533b308
             if (action_result.result != None and
                     'goBack' in action_result.result
                     and action_result.result['goBack']):
1ec3a643
                 self.hide_window()
                 self.action_panel.hide()
                 return action_result
             else:
                 #highlight the GoBack and keep going
72832a72
                 self.refresh(0, True)
f4d17450
 
         while action_result.success == False:
72832a72
             if self.read_text:
c533b308
                 is_go_back = self.position == 0
72832a72
                 action_result = self.action_panel.do_action(returned=True, go_back=is_go_back)
f4d17450
                 if action_result.success:
72832a72
                     if self.items:
                         return self.update_menu(action_result)
f4d17450
                     self.hide_window()
                     return action_result
                 else:
c533b308
                     if (action_result.result != None and
                             'goBack' in action_result.result and
                             action_result.result['goBack']):
72832a72
                         self.hide_window()
                         self.action_panel.hide()
                         return action_result
                     if action_result.result and 'direction' in action_result.result:
                         self.refresh(action_result.result['direction'], True)
             else:
                 key = self.contentwin.getch()
                 if key in [curses.KEY_ENTER, ord('\n')]:
                     #remove highlight from Go Back
                     if self.position == 0:
                         self.contentwin.addstr(self.height - 3, 5, '<Go Back>')
                         self.contentwin.refresh()
                         self.hide_window()
                         self.action_panel.hide()
                         return ActionResult(False, None)
                     else:
c533b308
                         if (action_result.result != None and
                                 'diskIndex' in action_result.result):
72832a72
                             params = action_result.result['diskIndex']
                             if self.menu_helper:
                                 self.menu_helper(params)
                         result = self.items[self.position-1][1](None)
                         if result.success:
                             self.hide_window()
                             self.action_panel.hide()
                             return result
                         else:
                             if 'goBack' in result.result and result.result['goBack']:
                                 self.contentwin.refresh()
                                 self.hide_window()
                                 self.action_panel.hide()
                                 return ActionResult(False, None)
                 elif key in [ord('\t')]:
                     if not self.tab_enabled:
c533b308
                         continue
72832a72
                     #remove highlight from Go Back
                     self.refresh(0, False)
                     # go do the action inside the panel
                     action_result = self.action_panel.do_action()
                     if action_result.success:
                         self.hide_window()
                         return action_result
                     else:
                         #highlight the GoBack and keep going
                         self.refresh(0, True)
                 elif key == curses.KEY_UP or key == curses.KEY_LEFT:
c533b308
                     if key == curses.KEY_UP and self.tab_enabled == False:
72832a72
                         self.action_panel.navigate(-1)
                         action_result = self.action_panel.do_action()
                         if action_result.success:
                             if self.items:
                                 return self.update_menu(action_result)
                             self.hide_window()
                             return action_result
                         else:
                             if 'direction' in action_result.result:
                             #highlight the GoBack and keep going
                                 self.refresh(action_result.result['direction'], True)
                     else:
                         self.refresh(-1, True)
 
                 elif key == curses.KEY_DOWN or key == curses.KEY_RIGHT:
c533b308
                     if key == curses.KEY_DOWN and self.tab_enabled == False:
72832a72
                         self.action_panel.navigate(1)
                         action_result = self.action_panel.do_action()
                         if action_result.success:
                             if self.items:
                                 return self.update_menu(action_result)
                             self.hide_window()
                             return action_result
                         else:
                             if 'direction' in action_result.result:
                             #highlight the GoBack and keep going
                                 self.refresh(action_result.result['direction'], True)
                     else:
                         self.refresh(1, True)
 
 
     def refresh(self, n, select):
         if not self.can_go_back:
             return
         self.position += n
         if self.position < 0:
             self.position = 0
         elif self.items and self.position > len(self.items):  #add 1 for the <go back>
             self.position = len(self.items)
 
         if not self.items and not self.can_go_next:
             self.position = 0
         #add the highlight
c533b308
         newy = 5
72832a72
         if self.position == 0:   #go back
             if select:
                 self.contentwin.addstr(self.height - 3, 5, '<Go Back>', curses.color_pair(3))
             elif self.items: #show user the last selected items
                 self.contentwin.addstr(self.height - 3, 5, '<Go Back>', curses.color_pair(1))
             else: #if Go back is the only one shown, do not highlight at all
                 self.contentwin.addstr(self.height - 3, 5, '<Go Back>')
 
             newy += len('<Go Back>')
             newy += self.dist
 
             if self.items:
                 for item in self.items:
                     self.contentwin.addstr(self.height - 3, newy, item[0])
                     newy += len(item[0])
                     newy += self.dist
 
         else:
             self.contentwin.addstr(self.height - 3, 5, '<Go Back>')
             newy += len('<Go Back>')
             newy += self.dist
             index = 1
             for item in self.items:
                 if index == self.position:
                     if select:
                         self.contentwin.addstr(self.height - 3, newy, item[0], curses.color_pair(3))
                     else:
                         self.contentwin.addstr(self.height - 3, newy, item[0], curses.color_pair(1))
 
                 else:
                     self.contentwin.addstr(self.height - 3, newy, item[0])
                 newy += len(item[0])
                 newy += self.dist
                 index += 1
 
c533b308
         self.contentwin.refresh()
f4d17450
 
     def show_window(self):
         y = self.y
         x = self.x
         self.shadowpanel.top()
         self.contentpanel.top()
         self.textpanel.top()
 
         self.shadowpanel.move(y + 1, x + 1)
         self.contentpanel.move(y, x)
         self.textpanel.move(y + 2, x + 2)
 
         self.shadowpanel.show()
         self.contentpanel.show()
         self.textpanel.show()
 
         curses.panel.update_panels()
         curses.doupdate()
 
72832a72
         if self.can_go_next:
             self.position = 1
 
f4d17450
     def hide_window(self):
         self.shadowpanel.hide()
         self.contentpanel.hide()
         self.textpanel.hide()
         curses.panel.update_panels()
         curses.doupdate()
 
c533b308
     def addstr(self, y, x, str, mode=0):
f4d17450
         self.textwin.addstr(y, x, str, mode)
 
     def adderror(self, str):
         self.textwin.addstr(self.height - 7, 0, str, curses.color_pair(4))
         self.textwin.refresh()
 
     def clearerror(self):
         spaces = ' ' * (self.width - 6)
         self.textwin.addstr(self.height - 7, 0, spaces)
         self.textwin.refresh()
 
     def content_window(self):
         return self.textwin