summary refs log tree commit diff stats
path: root/ranger/gui/ui.py
diff options
context:
space:
mode:
Diffstat (limited to 'ranger/gui/ui.py')
-rw-r--r--ranger/gui/ui.py710
1 files changed, 355 insertions, 355 deletions
diff --git a/ranger/gui/ui.py b/ranger/gui/ui.py
index f01b7b17..f35b11bf 100644
--- a/ranger/gui/ui.py
+++ b/ranger/gui/ui.py
@@ -14,364 +14,364 @@ MOUSEMASK = curses.ALL_MOUSE_EVENTS | curses.REPORT_MOUSE_POSITION
 
 _ASCII = ''.join(chr(c) for c in range(32, 127))
 def ascii_only(string):
-	return ''.join(c if c in _ASCII else '?' for c in string)
+    return ''.join(c if c in _ASCII else '?' for c in string)
 
 def _setup_mouse(signal):
-	if signal['value']:
-		curses.mousemask(MOUSEMASK)
-		curses.mouseinterval(0)
-
-		## this line solves this problem:
-		## If an action, following a mouse click, includes the
-		## suspension and re-initializion of the ui (e.g. running a
-		## file by clicking on its preview) and the next key is another
-		## mouse click, the bstate of this mouse event will be invalid.
-		## (atm, invalid bstates are recognized as scroll-down)
-		curses.ungetmouse(0,0,0,0,0)
-	else:
-		curses.mousemask(0)
+    if signal['value']:
+        curses.mousemask(MOUSEMASK)
+        curses.mouseinterval(0)
+
+        ## this line solves this problem:
+        ## If an action, following a mouse click, includes the
+        ## suspension and re-initializion of the ui (e.g. running a
+        ## file by clicking on its preview) and the next key is another
+        ## mouse click, the bstate of this mouse event will be invalid.
+        ## (atm, invalid bstates are recognized as scroll-down)
+        curses.ungetmouse(0,0,0,0,0)
+    else:
+        curses.mousemask(0)
 
 # TODO: progress bar
 # TODO: branch view
 class UI(DisplayableContainer):
-	is_set_up = False
-	load_mode = False
-	is_on = False
-	termsize = None
-
-	def __init__(self, env=None, fm=None):
-		self.keybuffer = KeyBuffer()
-		self.keymaps = KeyMaps(self.keybuffer)
-
-		if fm is not None:
-			self.fm = fm
-
-	def setup_curses(self):
-		os.environ['ESCDELAY'] = '25'   # don't know a cleaner way
-		try:
-			self.win = curses.initscr()
-		except _curses.error as e:
-			if e.args[0] == "setupterm: could not find terminal":
-				os.environ['TERM'] = 'linux'
-				self.win = curses.initscr()
-		self.keymaps.use_keymap('browser')
-		DisplayableContainer.__init__(self, None)
-
-	def initialize(self):
-		"""initialize curses, then call setup (at the first time) and resize."""
-		self.win.leaveok(0)
-		self.win.keypad(1)
-		self.load_mode = False
-
-		curses.cbreak()
-		curses.noecho()
-		curses.halfdelay(20)
-		try:
-			curses.curs_set(int(bool(self.settings.show_cursor)))
-		except:
-			pass
-		curses.start_color()
-		curses.use_default_colors()
-
-		self.settings.signal_bind('setopt.mouse_enabled', _setup_mouse)
-		_setup_mouse(dict(value=self.settings.mouse_enabled))
-
-		if not self.is_set_up:
-			self.is_set_up = True
-			self.setup()
-			self.win.addstr("loading...")
-			self.win.refresh()
-			curses.setupterm()
-			self._draw_title = curses.tigetflag('hs') # has_status_line
-		self.update_size()
-		self.is_on = True
-
-		if self.settings.update_tmux_title:
-			sys.stdout.write("\033kranger\033\\")
-			sys.stdout.flush()
-
-	def suspend(self):
-		"""Turn off curses"""
-		self.win.keypad(0)
-		curses.nocbreak()
-		curses.echo()
-		try:
-			curses.curs_set(1)
-		except:
-			pass
-		if self.settings.mouse_enabled:
-			_setup_mouse(dict(value=False))
-		curses.endwin()
-		self.is_on = False
-
-	def set_load_mode(self, boolean):
-		boolean = bool(boolean)
-		if boolean != self.load_mode:
-			self.load_mode = boolean
-
-			if boolean:
-				# don't wait for key presses in the load mode
-				curses.cbreak()
-				self.win.nodelay(1)
-			else:
-				self.win.nodelay(0)
-				curses.halfdelay(20)
-
-	def destroy(self):
-		"""Destroy all widgets and turn off curses"""
-		self.suspend()
-		DisplayableContainer.destroy(self)
-
-	def handle_mouse(self):
-		"""Handles mouse input"""
-		try:
-			event = MouseEvent(curses.getmouse())
-		except _curses.error:
-			return
-		if not self.console.visible:
-			DisplayableContainer.click(self, event)
-
-	def handle_key(self, key):
-		"""Handles key input"""
-
-		if hasattr(self, 'hint'):
-			self.hint()
-
-		if key < 0:
-			self.keybuffer.clear()
-
-		elif not DisplayableContainer.press(self, key):
-			self.keymaps.use_keymap('browser')
-			self.press(key)
-
-	def press(self, key):
-		keybuffer = self.keybuffer
-		self.status.clear_message()
-
-		keybuffer.add(key)
-		self.fm.hide_bookmarks()
-		self.browser.draw_hints = not keybuffer.finished_parsing \
-				and keybuffer.finished_parsing_quantifier
-
-		if keybuffer.result is not None:
-			try:
-				self.fm.execute_console(keybuffer.result,
-						wildcards=keybuffer.wildcards,
-						quantifier=keybuffer.quantifier)
-			finally:
-				if keybuffer.finished_parsing:
-					keybuffer.clear()
-		elif keybuffer.finished_parsing:
-			keybuffer.clear()
-			return False
-		return True
-
-	def handle_keys(self, *keys):
-		for key in keys:
-			self.handle_key(key)
-
-	def handle_input(self):
-		key = self.win.getch()
-		if key is 27 or key >= 128 and key < 256:
-			# Handle special keys like ALT+X or unicode here:
-			keys = [key]
-			previous_load_mode = self.load_mode
-			self.set_load_mode(True)
-			for n in range(4):
-				getkey = self.win.getch()
-				if getkey is not -1:
-					keys.append(getkey)
-			if len(keys) == 1:
-				keys.append(-1)
-			elif keys[0] == 27:
-				keys[0] = ALT_KEY
-			if self.settings.xterm_alt_key:
-				if len(keys) == 2 and keys[1] in range(127, 256):
-					if keys[0] == 195:
-						keys = [ALT_KEY, keys[1] - 64]
-					elif keys[0] == 194:
-						keys = [ALT_KEY, keys[1] - 128]
-			self.handle_keys(*keys)
-			self.set_load_mode(previous_load_mode)
-			if self.settings.flushinput and not self.console.visible:
-				curses.flushinp()
-		else:
-			# Handle simple key presses, CTRL+X, etc here:
-			if key > 0:
-				if self.settings.flushinput and not self.console.visible:
-					curses.flushinp()
-				if key == curses.KEY_MOUSE:
-					self.handle_mouse()
-				elif key == curses.KEY_RESIZE:
-					self.update_size()
-				else:
-					if not self.fm.input_is_blocked():
-						self.handle_key(key)
-
-	def setup(self):
-		"""Build up the UI by initializing widgets."""
-		from ranger.gui.widgets.browserview import BrowserView
-		from ranger.gui.widgets.titlebar import TitleBar
-		from ranger.gui.widgets.console import Console
-		from ranger.gui.widgets.statusbar import StatusBar
-		from ranger.gui.widgets.taskview import TaskView
-		from ranger.gui.widgets.pager import Pager
-
-		# Create a title bar
-		self.titlebar = TitleBar(self.win)
-		self.add_child(self.titlebar)
-
-		# Create the browser view
-		self.browser = BrowserView(self.win, self.settings.column_ratios)
-		self.settings.signal_bind('setopt.column_ratios',
-				self.browser.change_ratios)
-		self.add_child(self.browser)
-
-		# Create the process manager
-		self.taskview = TaskView(self.win)
-		self.taskview.visible = False
-		self.add_child(self.taskview)
-
-		# Create the status bar
-		self.status = StatusBar(self.win, self.browser.main_column)
-		self.add_child(self.status)
-
-		# Create the console
-		self.console = Console(self.win)
-		self.add_child(self.console)
-		self.console.visible = False
-
-		# Create the pager
-		self.pager = Pager(self.win)
-		self.pager.visible = False
-		self.add_child(self.pager)
-
-	def redraw(self):
-		"""Redraw all widgets"""
-		self.poke()
-
-		# determine which widgets are shown
-		if self.console.wait_for_command_input or self.console.question_queue:
-			self.console.focused = True
-			self.console.visible = True
-			self.status.visible = False
-		else:
-			self.console.focused = False
-			self.console.visible = False
-			self.status.visible = True
-
-		self.draw()
-		self.finalize()
-
-	def redraw_window(self):
-		"""Redraw the window. This only calls self.win.redrawwin()."""
-		self.win.erase()
-		self.win.redrawwin()
-		self.win.refresh()
-		self.win.redrawwin()
-		self.need_redraw = True
-
-	def update_size(self):
-		"""resize all widgets"""
-		self.termsize = self.win.getmaxyx()
-		y, x = self.termsize
-
-		self.browser.resize(self.settings.status_bar_on_top and 2 or 1, 0, y - 2, x)
-		self.taskview.resize(1, 0, y - 2, x)
-		self.pager.resize(1, 0, y - 2, x)
-		self.titlebar.resize(0, 0, 1, x)
-		self.status.resize(self.settings.status_bar_on_top and 1 or y-1, 0, 1, x)
-		self.console.resize(y - 1, 0, 1, x)
-
-	def draw(self):
-		"""Draw all objects in the container"""
-		self.win.touchwin()
-		DisplayableContainer.draw(self)
-		if self._draw_title and self.settings.update_title:
-			cwd = self.fm.thisdir.path
-			if cwd.startswith(self.fm.home_path):
-				cwd = '~' + cwd[len(self.fm.home_path):]
-			if self.settings.shorten_title:
-				split = cwd.rsplit(os.sep, self.settings.shorten_title)
-				if os.sep in split[0]:
-					cwd = os.sep.join(split[1:])
-			try:
-				fixed_cwd = cwd.encode('utf-8', 'surrogateescape'). \
-						decode('utf-8', 'replace')
-				sys.stdout.write("%sranger:%s%s" %
-						(curses.tigetstr('tsl').decode('latin-1'), fixed_cwd,
-						 curses.tigetstr('fsl').decode('latin-1')))
-				sys.stdout.flush()
-			except:
-				pass
-
-		self.win.refresh()
-
-	def finalize(self):
-		"""Finalize every object in container and refresh the window"""
-		DisplayableContainer.finalize(self)
-		self.win.refresh()
-
-	def close_pager(self):
-		if self.console.visible:
-			self.console.focused = True
-		self.pager.close()
-		self.pager.visible = False
-		self.pager.focused = False
-		self.browser.visible = True
-
-	def open_pager(self):
-		if self.console.focused:
-			self.console.focused = False
-		self.pager.open()
-		self.pager.visible = True
-		self.pager.focused = True
-		self.browser.visible = False
-		return self.pager
-
-	def open_embedded_pager(self):
-		self.browser.open_pager()
-		for column in self.browser.columns:
-			if column == self.browser.main_column:
-				break
-			column.level_shift(amount=1)
-		return self.browser.pager
-
-	def close_embedded_pager(self):
-		self.browser.close_pager()
-		for column in self.browser.columns:
-			column.level_restore()
-
-	def open_console(self, string='', prompt=None, position=None):
-		if self.console.open(string, prompt=prompt, position=position):
-			self.status.msg = None
-
-	def close_console(self):
-		self.console.close()
-		self.close_pager()
-
-	def open_taskview(self):
-		self.pager.close()
-		self.pager.visible = False
-		self.pager.focused = False
-		self.console.visible = False
-		self.browser.visible = False
-		self.taskview.visible = True
-		self.taskview.focused = True
-
-	def redraw_main_column(self):
-		self.browser.main_column.need_redraw = True
-
-	def close_taskview(self):
-		self.taskview.visible = False
-		self.browser.visible = True
-		self.taskview.focused = False
-
-	def throbber(self, string='.', remove=False):
-		if remove:
-			self.titlebar.throbber = type(self.titlebar).throbber
-		else:
-			self.titlebar.throbber = string
-
-	def hint(self, text=None):
-		self.status.hint = text
+    is_set_up = False
+    load_mode = False
+    is_on = False
+    termsize = None
+
+    def __init__(self, env=None, fm=None):
+        self.keybuffer = KeyBuffer()
+        self.keymaps = KeyMaps(self.keybuffer)
+
+        if fm is not None:
+            self.fm = fm
+
+    def setup_curses(self):
+        os.environ['ESCDELAY'] = '25'   # don't know a cleaner way
+        try:
+            self.win = curses.initscr()
+        except _curses.error as e:
+            if e.args[0] == "setupterm: could not find terminal":
+                os.environ['TERM'] = 'linux'
+                self.win = curses.initscr()
+        self.keymaps.use_keymap('browser')
+        DisplayableContainer.__init__(self, None)
+
+    def initialize(self):
+        """initialize curses, then call setup (at the first time) and resize."""
+        self.win.leaveok(0)
+        self.win.keypad(1)
+        self.load_mode = False
+
+        curses.cbreak()
+        curses.noecho()
+        curses.halfdelay(20)
+        try:
+            curses.curs_set(int(bool(self.settings.show_cursor)))
+        except:
+            pass
+        curses.start_color()
+        curses.use_default_colors()
+
+        self.settings.signal_bind('setopt.mouse_enabled', _setup_mouse)
+        _setup_mouse(dict(value=self.settings.mouse_enabled))
+
+        if not self.is_set_up:
+            self.is_set_up = True
+            self.setup()
+            self.win.addstr("loading...")
+            self.win.refresh()
+            curses.setupterm()
+            self._draw_title = curses.tigetflag('hs') # has_status_line
+        self.update_size()
+        self.is_on = True
+
+        if self.settings.update_tmux_title:
+            sys.stdout.write("\033kranger\033\\")
+            sys.stdout.flush()
+
+    def suspend(self):
+        """Turn off curses"""
+        self.win.keypad(0)
+        curses.nocbreak()
+        curses.echo()
+        try:
+            curses.curs_set(1)
+        except:
+            pass
+        if self.settings.mouse_enabled:
+            _setup_mouse(dict(value=False))
+        curses.endwin()
+        self.is_on = False
+
+    def set_load_mode(self, boolean):
+        boolean = bool(boolean)
+        if boolean != self.load_mode:
+            self.load_mode = boolean
+
+            if boolean:
+                # don't wait for key presses in the load mode
+                curses.cbreak()
+                self.win.nodelay(1)
+            else:
+                self.win.nodelay(0)
+                curses.halfdelay(20)
+
+    def destroy(self):
+        """Destroy all widgets and turn off curses"""
+        self.suspend()
+        DisplayableContainer.destroy(self)
+
+    def handle_mouse(self):
+        """Handles mouse input"""
+        try:
+            event = MouseEvent(curses.getmouse())
+        except _curses.error:
+            return
+        if not self.console.visible:
+            DisplayableContainer.click(self, event)
+
+    def handle_key(self, key):
+        """Handles key input"""
+
+        if hasattr(self, 'hint'):
+            self.hint()
+
+        if key < 0:
+            self.keybuffer.clear()
+
+        elif not DisplayableContainer.press(self, key):
+            self.keymaps.use_keymap('browser')
+            self.press(key)
+
+    def press(self, key):
+        keybuffer = self.keybuffer
+        self.status.clear_message()
+
+        keybuffer.add(key)
+        self.fm.hide_bookmarks()
+        self.browser.draw_hints = not keybuffer.finished_parsing \
+                and keybuffer.finished_parsing_quantifier
+
+        if keybuffer.result is not None:
+            try:
+                self.fm.execute_console(keybuffer.result,
+                        wildcards=keybuffer.wildcards,
+                        quantifier=keybuffer.quantifier)
+            finally:
+                if keybuffer.finished_parsing:
+                    keybuffer.clear()
+        elif keybuffer.finished_parsing:
+            keybuffer.clear()
+            return False
+        return True
+
+    def handle_keys(self, *keys):
+        for key in keys:
+            self.handle_key(key)
+
+    def handle_input(self):
+        key = self.win.getch()
+        if key is 27 or key >= 128 and key < 256:
+            # Handle special keys like ALT+X or unicode here:
+            keys = [key]
+            previous_load_mode = self.load_mode
+            self.set_load_mode(True)
+            for n in range(4):
+                getkey = self.win.getch()
+                if getkey is not -1:
+                    keys.append(getkey)
+            if len(keys) == 1:
+                keys.append(-1)
+            elif keys[0] == 27:
+                keys[0] = ALT_KEY
+            if self.settings.xterm_alt_key:
+                if len(keys) == 2 and keys[1] in range(127, 256):
+                    if keys[0] == 195:
+                        keys = [ALT_KEY, keys[1] - 64]
+                    elif keys[0] == 194:
+                        keys = [ALT_KEY, keys[1] - 128]
+            self.handle_keys(*keys)
+            self.set_load_mode(previous_load_mode)
+            if self.settings.flushinput and not self.console.visible:
+                curses.flushinp()
+        else:
+            # Handle simple key presses, CTRL+X, etc here:
+            if key > 0:
+                if self.settings.flushinput and not self.console.visible:
+                    curses.flushinp()
+                if key == curses.KEY_MOUSE:
+                    self.handle_mouse()
+                elif key == curses.KEY_RESIZE:
+                    self.update_size()
+                else:
+                    if not self.fm.input_is_blocked():
+                        self.handle_key(key)
+
+    def setup(self):
+        """Build up the UI by initializing widgets."""
+        from ranger.gui.widgets.browserview import BrowserView
+        from ranger.gui.widgets.titlebar import TitleBar
+        from ranger.gui.widgets.console import Console
+        from ranger.gui.widgets.statusbar import StatusBar
+        from ranger.gui.widgets.taskview import TaskView
+        from ranger.gui.widgets.pager import Pager
+
+        # Create a title bar
+        self.titlebar = TitleBar(self.win)
+        self.add_child(self.titlebar)
+
+        # Create the browser view
+        self.browser = BrowserView(self.win, self.settings.column_ratios)
+        self.settings.signal_bind('setopt.column_ratios',
+                self.browser.change_ratios)
+        self.add_child(self.browser)
+
+        # Create the process manager
+        self.taskview = TaskView(self.win)
+        self.taskview.visible = False
+        self.add_child(self.taskview)
+
+        # Create the status bar
+        self.status = StatusBar(self.win, self.browser.main_column)
+        self.add_child(self.status)
+
+        # Create the console
+        self.console = Console(self.win)
+        self.add_child(self.console)
+        self.console.visible = False
+
+        # Create the pager
+        self.pager = Pager(self.win)
+        self.pager.visible = False
+        self.add_child(self.pager)
+
+    def redraw(self):
+        """Redraw all widgets"""
+        self.poke()
+
+        # determine which widgets are shown
+        if self.console.wait_for_command_input or self.console.question_queue:
+            self.console.focused = True
+            self.console.visible = True
+            self.status.visible = False
+        else:
+            self.console.focused = False
+            self.console.visible = False
+            self.status.visible = True
+
+        self.draw()
+        self.finalize()
+
+    def redraw_window(self):
+        """Redraw the window. This only calls self.win.redrawwin()."""
+        self.win.erase()
+        self.win.redrawwin()
+        self.win.refresh()
+        self.win.redrawwin()
+        self.need_redraw = True
+
+    def update_size(self):
+        """resize all widgets"""
+        self.termsize = self.win.getmaxyx()
+        y, x = self.termsize
+
+        self.browser.resize(self.settings.status_bar_on_top and 2 or 1, 0, y - 2, x)
+        self.taskview.resize(1, 0, y - 2, x)
+        self.pager.resize(1, 0, y - 2, x)
+        self.titlebar.resize(0, 0, 1, x)
+        self.status.resize(self.settings.status_bar_on_top and 1 or y-1, 0, 1, x)
+        self.console.resize(y - 1, 0, 1, x)
+
+    def draw(self):
+        """Draw all objects in the container"""
+        self.win.touchwin()
+        DisplayableContainer.draw(self)
+        if self._draw_title and self.settings.update_title:
+            cwd = self.fm.thisdir.path
+            if cwd.startswith(self.fm.home_path):
+                cwd = '~' + cwd[len(self.fm.home_path):]
+            if self.settings.shorten_title:
+                split = cwd.rsplit(os.sep, self.settings.shorten_title)
+                if os.sep in split[0]:
+                    cwd = os.sep.join(split[1:])
+            try:
+                fixed_cwd = cwd.encode('utf-8', 'surrogateescape'). \
+                        decode('utf-8', 'replace')
+                sys.stdout.write("%sranger:%s%s" %
+                        (curses.tigetstr('tsl').decode('latin-1'), fixed_cwd,
+                         curses.tigetstr('fsl').decode('latin-1')))
+                sys.stdout.flush()
+            except:
+                pass
+
+        self.win.refresh()
+
+    def finalize(self):
+        """Finalize every object in container and refresh the window"""
+        DisplayableContainer.finalize(self)
+        self.win.refresh()
+
+    def close_pager(self):
+        if self.console.visible:
+            self.console.focused = True
+        self.pager.close()
+        self.pager.visible = False
+        self.pager.focused = False
+        self.browser.visible = True
+
+    def open_pager(self):
+        if self.console.focused:
+            self.console.focused = False
+        self.pager.open()
+        self.pager.visible = True
+        self.pager.focused = True
+        self.browser.visible = False
+        return self.pager
+
+    def open_embedded_pager(self):
+        self.browser.open_pager()
+        for column in self.browser.columns:
+            if column == self.browser.main_column:
+                break
+            column.level_shift(amount=1)
+        return self.browser.pager
+
+    def close_embedded_pager(self):
+        self.browser.close_pager()
+        for column in self.browser.columns:
+            column.level_restore()
+
+    def open_console(self, string='', prompt=None, position=None):
+        if self.console.open(string, prompt=prompt, position=position):
+            self.status.msg = None
+
+    def close_console(self):
+        self.console.close()
+        self.close_pager()
+
+    def open_taskview(self):
+        self.pager.close()
+        self.pager.visible = False
+        self.pager.focused = False
+        self.console.visible = False
+        self.browser.visible = False
+        self.taskview.visible = True
+        self.taskview.focused = True
+
+    def redraw_main_column(self):
+        self.browser.main_column.need_redraw = True
+
+    def close_taskview(self):
+        self.taskview.visible = False
+        self.browser.visible = True
+        self.taskview.focused = False
+
+    def throbber(self, string='.', remove=False):
+        if remove:
+            self.titlebar.throbber = type(self.titlebar).throbber
+        else:
+            self.titlebar.throbber = string
+
+    def hint(self, text=None):
+        self.status.hint = text