about summary refs log blame commit diff stats
path: root/ranger/gui/widgets/statusbar.py
blob: 41da7b06ccead0490d0d3dd29e9e5a90c379a127 (plain) (tree)






















                                                                       




                                                              






                                                                    




                                                                  


                                   


                                              


                                                      
                                            
                     
                                           








                                                                   






                                                                           



























                                                                   



                                                     











                                                                                
                                                                                            












































                                                                              
"""The StatusBar displays information about the currently selected file
in the same form as the "ls -l" command on the left side, and
some additional info about the current directory on the right side.
"""

from . import Widget
from ranger import log
from pwd import getpwuid
from grp import getgrgid
from os import getuid
from time import strftime, localtime

class StatusBar(Widget):
	__doc__ = __doc__
	owners = {}
	groups = {}
	timeformat = '%Y-%m-%d %H:%M'

	def __init__(self, win, filelist=None):
		Widget.__init__(self, win)
		self.filelist = filelist
	
	def draw(self):
		"""Draw the statusbar"""

		# each item in the returned array looks like:
		# [ list_with_color_tags,       string       ]
		# [ ['permissions', 'allowed'], '-rwxr-xr-x' ]
		left = self._get_left_part()
		right = self._get_right_part()
		self._print_result(self._combine_parts(left, right))

	def _get_left_part(self):
		part = []

		if self.filelist is not None:
			target = self.filelist.target.pointed_file
		else:
			target = self.env.at_level(0).pointed_file

		if target is None:
			return part

		if target.accessible is False:
			return part

		perms = target.get_permission_string()
		color = ['permissions']
		if getuid() == target.stat.st_uid:
			color.append('good')
		else:
			color.append('bad')
		part.append([color, perms])

		part.append([['space'], " "])
		part.append([['nlink'], str(target.stat.st_nlink)])
		part.append([['space'], " "])
		part.append([['owner'], self._get_owner(target)])
		part.append([['space'], " "])
		part.append([['group'], self._get_group(target)])
		part.append([['space'], " "])
		if target.islink:
			color = ['link']
			color.append(target.exists and 'good' or 'bad')
			part.append([color, '-> ' + target.readlink])
		else:
			part.append([['mtime'], strftime(self.timeformat, \
					localtime(target.stat.st_mtime))])
		return part
	
	def _get_owner(self, target):
		uid = target.stat.st_uid

		try:
			return self.owners[uid]
		except KeyError:
			try:
				self.owners[uid] = getpwuid(uid)[0]
				return self.owners[uid]
			except KeyError:
				return str(uid)

	def _get_group(self, target):
		gid = target.stat.st_gid

		try:
			return self.groups[gid]
		except KeyError:
			try:
				self.groups[gid] = getgrgid(gid)[0]
				return self.groups[gid]
			except KeyError:
				return str(gid)

	def _get_right_part(self):
		part = []
		if self.filelist is not None:
			target = self.filelist.target
		else:
			target = self.env.at_level(0)

		if self.filelist is not None:
			pos = target.scroll_begin
			max_pos = len(target) - self.filelist.hei

			if max_pos > 0:
				if pos == 0:
					part.append([['scroll', 'top'], 'Top'])
				elif pos >= max_pos:
					part.append([['scroll', 'bot'], 'Bot'])
				else:
					part.append([['scroll', 'percentage'], \
						'{0:0>.0f}%'.format(100.0 * pos / max_pos)])
			else:
				part.append([['scroll', 'all'], 'All'])
		return part


	def _combine_parts(self, left, right):
		"""Combines left and right, filling the middle with spaces and
removing elements which don't have enough room to fit in.
<left> will be turned into the result (which is also returned).
"""

		leftsize = sum(len(part[1]) for part in left)
		rightsize = sum(len(part[1]) for part in right)
		sumsize = leftsize + rightsize

		# remove elemets from the left until it fits
		if sumsize > self.wid:
			while len(left) > 0:
				leftsize -= len(left.pop(-1)[1])
				if leftsize + rightsize <= self.wid:
					break
			sumsize = leftsize + rightsize

			# remove elemets from the right until it fits
			if sumsize > self.wid:
				while len(right) > 0:
					rightsize -= len(right.pop(0)[1])
					if leftsize + rightsize <= self.wid:
						break
				sumsize = leftsize + rightsize

		if sumsize < self.wid:
			left.append([ ['space'], " " * (self.wid - sumsize) ])
		left.extend(right)
		return left

	def _print_result(self, result):
		import _curses
		self.win.move(self.y, self.x)
		for part in result:
			self.color('in_statusbar', *part[0])
			try:
				self.win.addstr(part[1])
			except _curses.error:
				pass