# Copyright (C) 2009, 2010 Roman Zimbelmann # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import os import sys import curses import _curses from .displayable import DisplayableContainer from ranger.gui.curses_shortcuts import ascii_only from .mouse_event import MouseEvent from ranger.ext.keybinding_parser import ALT_KEY TERMINALS_WITH_TITLE = ("xterm", "xterm-256color", "rxvt", "rxvt-256color", "rxvt-unicode", "aterm", "Eterm", "screen", "screen-256color") MOUSEMASK = curses.ALL_MOUSE_EVENTS | curses.REPORT_MOUSE_POSITION 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) class UI(DisplayableContainer): is_set_up = False load_mode = False is_on = False def __init__(self, env=None, fm=None): self._draw_title = os.environ["TERM"] in TERMINALS_WITH_TITLE os.environ['ESCDELAY'] = '25' # don't know a cleaner way if env is not None: self.env = env if fm is not None: self.fm = fm self.win = curses.initscr() self.env.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.update_size() self.is_on = True 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:
discard """
  disabled: "posix"
"""

# bug 10952, UNC paths
import os

doAssert r"\\hostname\foo\bar" / "baz" == r"\\hostname\foo\bar\baz"
doAssert r"\\?\C:\foo" / "bar"