summary refs log tree commit diff stats
path: root/ranger/gui/widgets/browsercolumn.py
diff options
context:
space:
mode:
Diffstat (limited to 'ranger/gui/widgets/browsercolumn.py')
-rw-r--r--ranger/gui/widgets/browsercolumn.py125
1 files changed, 72 insertions, 53 deletions
diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py
index e9c08439..1cb943d2 100644
--- a/ranger/gui/widgets/browsercolumn.py
+++ b/ranger/gui/widgets/browsercolumn.py
@@ -1,20 +1,9 @@
 # -*- encoding: utf8 -*-
 # Copyright (C) 2009, 2010, 2011  Roman Zimbelmann <romanz@lavabit.com>
-#
-# 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 <http://www.gnu.org/licenses/>.
+# This software is distributed under the terms of the GNU GPL version 3.
 
 """The BrowserColumn widget displays the contents of a directory or file."""
+import curses
 import stat
 from time import time
 
@@ -32,7 +21,7 @@ class BrowserColumn(Pager):
 	ellipsis = { False: '~', True: '…' }
 
 	old_dir = None
-	old_cf = None
+	old_thisfile = None
 
 	def __init__(self, win, level):
 		"""
@@ -86,7 +75,7 @@ class BrowserColumn(Pager):
 						if clicked_file.is_directory:
 							self.fm.enter_dir(clicked_file.path)
 						elif self.level == 0:
-							self.fm.env.cwd.move_to_obj(clicked_file)
+							self.fm.thisdir.move_to_obj(clicked_file)
 							self.fm.execute_file(clicked_file)
 					except:
 						pass
@@ -97,6 +86,22 @@ class BrowserColumn(Pager):
 
 		return True
 
+	def execute_curses_batch(self, line, commands):
+		"""
+		Executes a list of "commands" which can be easily cached.
+
+		"commands" is a list of lists.  Each element contains
+		a text and an attribute.  First, the attribute will be
+		set with attrset, then the text is printed.
+
+		Example:
+		execute_curses_batch(0, [["hello ", 0], ["world", curses.A_BOLD]])
+		"""
+		self.win.move(line, 0)
+		for entry in commands:
+			text, attr = entry
+			self.addstr(text, attr)
+
 	def has_preview(self):
 		if self.target is None:
 			return False
@@ -113,7 +118,7 @@ class BrowserColumn(Pager):
 
 	def poke(self):
 		Widget.poke(self)
-		self.target = self.env.at_level(self.level)
+		self.target = self.fm.thistab.at_level(self.level)
 
 	def draw(self):
 		"""Call either _draw_file() or _draw_directory()"""
@@ -126,9 +131,9 @@ class BrowserColumn(Pager):
 
 		if self.target and self.target.is_directory \
 				and (self.level <= 0 or self.settings.preview_directories):
-			if self.target.pointed_obj != self.old_cf:
+			if self.target.pointed_obj != self.old_thisfile:
 				self.need_redraw = True
-				self.old_cf = self.target.pointed_obj
+				self.old_thisfile = self.target.pointed_obj
 
 			if self.target.load_content_if_outdated() \
 			or self.target.sort_if_outdated() \
@@ -200,31 +205,45 @@ class BrowserColumn(Pager):
 
 		self._set_scroll_begin()
 
-		copied = [f.path for f in self.env.copy]
+		copied = [f.path for f in self.fm.copy_buffer]
 		ellipsis = self.ellipsis[self.settings.unicode_ellipsis]
 
 		selected_i = self.target.pointer
 		for line in range(self.hei):
 			i = line + self.scroll_begin
+			if line > self.hei:
+				break
 
 			try:
 				drawn = self.target.files[i]
 			except IndexError:
 				break
 
+			tagged = self.fm.tags and drawn.realpath in self.fm.tags
+			if tagged:
+				tagged_marker = self.fm.tags.marker(drawn.realpath)
+			else:
+				tagged_marker = " "
+
+			key = (self.wid, selected_i == i, drawn.marked, self.main_column,
+					drawn.path in copied, tagged_marker, drawn.infostring)
+
+			if key in drawn.display_data:
+				self.execute_curses_batch(line, drawn.display_data[key])
+				self.color_reset()
+				continue
+
+			display_data = []
+			drawn.display_data[key] = display_data
+
 			if self.display_infostring and drawn.infostring \
 					and self.settings.display_size_in_main_column:
 				infostring = str(drawn.infostring) + " "
 			else:
 				infostring = ""
 
-			bad_info_color = None
 			this_color = base_color + list(drawn.mimetype_tuple)
 			text = drawn.basename
-			tagged = self.fm.tags and drawn.realpath in self.fm.tags
-
-			if tagged:
-				tagged_marker = self.fm.tags.marker(drawn.realpath)
 
 			space = self.wid - len(infostring)
 			if self.main_column:
@@ -232,9 +251,6 @@ class BrowserColumn(Pager):
 			elif self.settings.display_tags_in_all_columns:
 				space -= 1
 
-#			if len(text) > space:
-#				text = text[:space-1] + self.ellipsis
-
 			if i == selected_i:
 				this_color.append('selected')
 
@@ -245,8 +261,6 @@ class BrowserColumn(Pager):
 
 			if tagged:
 				this_color.append('tagged')
-				if self.main_column or self.settings.display_tags_in_all_columns:
-					text = tagged_marker + text
 
 			if drawn.is_directory:
 				this_color.append('directory')
@@ -265,40 +279,45 @@ class BrowserColumn(Pager):
 					this_color.append('device')
 
 			if drawn.path in copied:
-				this_color.append('cut' if self.env.cut else 'copied')
+				this_color.append('cut' if self.fm.do_cut else 'copied')
 
 			if drawn.is_link:
 				this_color.append('link')
 				this_color.append(drawn.exists and 'good' or 'bad')
 
-			wtext = WideString(text)
-			if len(wtext) > space:
-				wtext = wtext[:space - 1] + ellipsis
-			if self.main_column or self.settings.display_tags_in_all_columns:
-				if tagged:
-					self.addstr(line, 0, str(wtext))
-				elif self.wid > 1:
-					self.addstr(line, 1, str(wtext))
-			else:
-				self.addstr(line, 0, str(wtext))
-
-			if infostring:
-				x = self.wid - 1 - len(infostring)
-				if infostring is BAD_INFO:
-					bad_info_color = (x, len(infostring))
-				if x > 0:
-					self.addstr(line, x, infostring)
-
-			self.color_at(line, 0, self.wid, tuple(this_color))
-			if bad_info_color:
-				start, wid = bad_info_color
-				self.color_at(line, start, wid, tuple(this_color), 'badinfo')
+			attr = self.settings.colorscheme.get_attr(*this_color)
 
 			if (self.main_column or self.settings.display_tags_in_all_columns) \
 					and tagged and self.wid > 2:
 				this_color.append('tag_marker')
-				self.color_at(line, 0, len(tagged_marker), tuple(this_color))
+				tag_attr = self.settings.colorscheme.get_attr(*this_color)
+				display_data.append([tagged_marker, tag_attr])
+			else:
+				text = " " + text
+
+			wtext = WideString(text)
+			if len(wtext) > space:
+				wtext = wtext[:max(0, space - 1)] + ellipsis
+			text = str(wtext)
+
+			display_data.append([text, attr])
+
+			padding = self.wid - len(wtext)
+			if tagged and (self.main_column or \
+					self.settings.display_tags_in_all_columns):
+				padding -= 1
+			if infostring:
+				if len(text) + 1 + len(infostring) > self.wid:
+					pass
+				else:
+					padding -= len(infostring)
+					padding = max(0, padding)
+					infostring = (" " * padding) + infostring
+					display_data.append([infostring, attr])
+			else:
+				display_data.append([" " * max(0, padding), attr])
 
+			self.execute_curses_batch(line, display_data)
 			self.color_reset()
 
 	def _get_scroll_begin(self):