7 from ui
.utils
import human_unit
, short_string
8 from ui
.char_matrix
import CharMatrix
, MASK
, SELECTED
9 from core
.pysize_fs_tree
import pysize_tree
13 def __init__(self
, win
, options
, args
):
15 self
.max_depth
= options
.max_depth
16 if options
.min_size
!= 'auto':
17 raise Exception, 'curses UI supports only --min-size=auto'
18 self
._set
_path
(args
[0])
21 def _init_curses(self
):
22 curses
.use_default_colors()
27 return sum(map(lambda n
: 1<<n
, positions
))
29 self
.MATRIX_TO_CURSES
= {
31 dots(3, 4, 5): curses
.ACS_HLINE
,
32 dots(1, 4, 7): curses
.ACS_VLINE
,
33 dots(1, 3, 4, 5, 7): curses
.ACS_PLUS
,
34 dots(4, 5, 7): curses
.ACS_ULCORNER
,
35 dots(3, 4, 7): curses
.ACS_URCORNER
,
36 dots(1, 4, 5): curses
.ACS_LLCORNER
,
37 dots(1, 3, 4): curses
.ACS_LRCORNER
,
38 dots(3, 4, 5, 7): curses
.ACS_TTEE
,
39 dots(1, 3, 4, 5): curses
.ACS_BTEE
,
40 dots(1, 4, 5, 7): curses
.ACS_LTEE
,
41 dots(1, 3, 4, 7): curses
.ACS_RTEE
45 self
.status_win
= curses
.newwin(0, 0)
46 self
.panel
= curses
.newwin(0, 0)
49 print 'Cannot create windows'
53 """Called when the terminal size changes."""
54 self
.height
, self
.width
= self
.window
.getmaxyx()
55 self
.height
-= 1 # Status bar
57 self
.status_win
.resize(1, self
.width
)
58 self
.status_win
.mvwin(self
.height
, 0)
59 self
.panel
.resize(self
.height
, self
.width
)
60 self
._set
_path
(self
.path
)
66 self
.tree
= pysize_tree(self
.path
, self
.max_depth
,
68 self
.need_tree
= False
69 if not self
.tree
.root
:
73 self
._draw
_matrix
(CharMatrix(self
.width
, self
.height
, self
.tree
,
77 self
.status_win
.erase()
78 self
.status_win
.hline(0, 0, ord(' ') | curses
.A_REVERSE
, self
.width
)
80 status_line
= self
.path
+ ' ' + human_unit(self
.tree
.root
.size
)
81 if len(status_line
) + len(END
) >= self
.width
:
82 status_line
= short_string(status_line
, self
.width
- 1)
85 self
.status_win
.addstr(status_line
, curses
.A_REVERSE
)
86 self
.status_win
.refresh()
93 except curses
.error
, e
:
97 def _set_path(self
, path
):
98 self
.selected_node
= None
101 self
.need_tree
= True
103 def _next_step(self
):
104 sequel
= self
.selected_node
.get_fullpath()[len(self
.path
) + 1:]
105 sequel
= sequel
.split('/', 1)[0]
106 self
._set
_path
(os
.path
.join(self
.path
, sequel
))
108 def _select(self
, function
):
109 if not self
.selected_node
:
110 if self
.tree
.root
.get_children():
111 self
.selected_node
= self
.tree
.root
.get_children()[0]
113 selected
= function(self
.selected_node
)
115 if function
== self
.tree
.get_first_child
and \
116 self
.selected_node
.is_dir():
117 # Browsing to the right
120 self
.selected_node
= selected
121 if self
.selected_node
== self
.tree
.root
:
122 # Browsing to the left
123 if len(self
.path
) > 1:
124 parent
= os
.path
.dirname(self
.path
)
125 self
._set
_path
(parent
)
127 self
.selected_node
= None
130 if self
.selected_node
and self
.selected_node
.is_dir():
131 self
._set
_path
(self
.selected_node
.get_fullpath())
134 """The main dispatcher."""
139 curses
.KEY_RESIZE
: lambda:
142 curses
.KEY_DOWN
: lambda:
143 self
._select
(self
.tree
.get_next_sibling
),
145 curses
.KEY_UP
: lambda:
146 self
._select
(self
.tree
.get_previous_sibling
),
148 curses
.KEY_LEFT
: lambda:
149 self
._select
(self
.tree
.get_parent
),
151 curses
.KEY_RIGHT
: lambda:
152 self
._select
(self
.tree
.get_first_child
),
160 c
= self
.window
.getch()
161 action
= key_bindings
.get(c
, lambda: None)
164 def _draw_matrix(self
, matrix
):
165 for (y
, line
) in enumerate(matrix
.matrix
):
166 for (x
, char
) in enumerate(line
):
167 if isinstance(char
, int):
168 selected
= (char
& SELECTED
) != 0
170 char
= self
.MATRIX_TO_CURSES
[char
]
172 char |
= curses
.A_REVERSE
173 self
.panel
.insch(y
, x
, char
)
176 char
= char
.encode('UTF-8')
177 except UnicodeDecodeError:
179 self
.panel
.insstr(y
, x
, char
)
181 def _run_curses(win
, options
, args
):
182 app
= _CursesApp(win
, options
, args
)
185 def run(options
, args
):
186 locale
.setlocale(locale
.LC_ALL
, '')
187 curses
.wrapper(_run_curses
, options
, args
)
190 return sys
.stdin
.isatty() and sys
.stdout
.isatty()