summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Back <fredericback@gmail.com>2006-10-02 12:59:27 +0000
committerFrederic Back <fredericback@gmail.com>2006-10-02 12:59:27 +0000
commit4dae0aaa6d348b7961c3620e0ded88d560aef4af (patch)
treef14d53fd736c4b5933e52b8e2a63e28e533bcc39
parent9f61b0f1bc9393b6d8b92f62f4b82fb91a5b314b (diff)
* Added SumList as a dummy class again to be able to create pointers to
subfolders. This will allow fast switching to subfolders. * Removed all walkers except the gnomevfs one * Added status message when hovering parent button git-svn-id: file:///home/lennart/svn/public/fring/trunk@51 d0d2c35f-0a1e-0410-abeb-dabff30a67ee
-rw-r--r--src/fringlib/fringrenderer.py57
-rw-r--r--src/fringlib/fringui.py78
-rw-r--r--src/fringlib/fringwalker.py97
3 files changed, 107 insertions, 125 deletions
diff --git a/src/fringlib/fringrenderer.py b/src/fringlib/fringrenderer.py
index c5fd5ee..59ea2a3 100644
--- a/src/fringlib/fringrenderer.py
+++ b/src/fringlib/fringrenderer.py
@@ -6,26 +6,29 @@ import os
class Hotspot:
- def __init__(self, is_dir, path, size, value):
+ def __init__(self, is_dir, path, sumlist, value):
self.is_dir = is_dir
self.path = path
- self.size = size
+ self.sumlist = sumlist
self.value = value
self.percentage = value*100
+
class SideLink(Hotspot):
- def __init__(self, is_dir, path, size, value, minpos, maxpos):
- Hotspot.__init__(self, is_dir, path, size, value)
+ def __init__(self, is_dir, path, sumlist, value, minpos, maxpos):
+ Hotspot.__init__(self, is_dir, path, sumlist, value)
self.minx,self.miny = minpos
self.maxx,self.maxy = maxpos
+
class Segment(Hotspot):
- def __init__(self, is_dir, path, size, start, end):
- Hotspot.__init__(self, is_dir, path, size, end-start)
+ def __init__(self, is_dir, path, sumlist, start, end):
+ Hotspot.__init__(self, is_dir, path, sumlist, end-start)
self.start, self.end = start, end
+
class FringRenderer:
@@ -59,13 +62,8 @@ class FringRenderer:
self.linklayout.set_font_description(pango.FontDescription("sans 8"))
def draw_segment(self,ctx, ring, start_angle, end_angle, start_hue, end_hue, data, previouspath=""):
-
if data is None: return
- dataname = data[0]
- datacontents = data[1]
- datasize = data[2]
-
if ring == 0:
self.lookup_data = []
self.side_links = []
@@ -76,27 +74,26 @@ class FringRenderer:
CENTERX, CENTERY = self.WIDTH/2, self.HEIGHT/2
ctx.move_to(CENTERX, CENTERY)
- n = len(datacontents)
+ n = len(data.children)
i = 0
accumulated = 0
last = start_angle
- for entry in datacontents:
- fn, contents, value = entry
+ for entry in data.children:
- hasContents = contents != None
+ hasContents = entry.children != None
start = last
- accumulated += value
+ accumulated += entry.size
- if datasize == 0: continue
- end = start_angle+(end_angle - start_angle)*1.0*accumulated/datasize
+ if data.size == 0: continue
+ end = start_angle+(end_angle - start_angle)*1.0*accumulated/data.size
if end-start >= .005:
- p = previouspath+os.sep+fn
- self.lookup_data[ring].append( Segment(hasContents , p, value, start, end) )
+ p = previouspath+os.sep+entry.name
+ self.lookup_data[ring].append( Segment(hasContents , p, entry, start, end) )
color = self._choose_color(start_hue + (end_hue-start_hue)*1.0*i/n, ring)
@@ -117,7 +114,7 @@ class FringRenderer:
self.draw_segment(ctx, ring+1, start, end,
start_hue + (end_hue-start_hue)*1.0*i/n,
start_hue + (end_hue-start_hue)*1.0*(i+1)/n, entry,
- previouspath+os.sep+fn)
+ previouspath+os.sep+entry.name)
r += self.RING_RADIUS/2
middle = CENTERX+r*cos((start+end)*pi), CENTERY+r*sin((start+end)*pi)
@@ -149,12 +146,18 @@ class FringRenderer:
else: ctx.set_source_rgb(*self.FILE_LABEL_COLOR)
# todo: cut down label size if longer than WIDTH/2 - ring*ringradius - innerradius
- label = fn
+ label = entry.name
width,height = self._draw_centered_text(ctx, label, align_x)
if align_x == 0: width *= -1 #TODO change this...
- self.__register_side_link(hasContents,p,value,end-start,x,y+(height/2),x+(width),y-(height/2))
+
+ self.__register_side_link(
+ hasContents,
+ p,
+ entry,
+ end-start,
+ x,y+(height/2),x+(width),y-(height/2))
# draw line
ctx.move_to(*point_a)
@@ -172,7 +175,7 @@ class FringRenderer:
ctx.set_source_rgb(0, 0, 0)
percent = (end-start)*100
if percent >= 8:
- #self._draw_centered_text2(ctx, "%.0f%%" % ((end-start)*100), pretty_size(value))
+ #self._draw_centered_text2(ctx, "%.0f%%" % ((end-start)*100), pretty_size(entry.size))
self._draw_centered_text(ctx, "%.0f%%" %percent)
last = end
@@ -180,7 +183,7 @@ class FringRenderer:
if ring == 0:
ctx.set_source_rgb(.3,.3,.3)
- i = format_disk_space(datasize)
+ i = format_disk_space(data.size)
ctx.move_to(CENTERX, CENTERY)
width,height = self._draw_centered_text(ctx, i[0], .5, 1 )
ctx.move_to(CENTERX, CENTERY+height)
@@ -239,10 +242,10 @@ class FringRenderer:
p = np # Funny!
- def __register_side_link(self,is_dir,path,size,value,x0,y0,x1,y1):
+ def __register_side_link(self,is_dir,path,sumlist,value,x0,y0,x1,y1):
if x1 < x0: x0,x1 = x1,x0 # swap
if y1 < y0: y0,y1 = y1,y0
- self.side_links.append(SideLink(is_dir, path, size, value, (x0,y0), (x1,y1)))
+ self.side_links.append(SideLink(is_dir, path, sumlist, value, (x0,y0), (x1,y1)))
def hsv2rgb(self,h,s,v):
if s<=0:
diff --git a/src/fringlib/fringui.py b/src/fringlib/fringui.py
index a6c606d..068fd97 100644
--- a/src/fringlib/fringui.py
+++ b/src/fringlib/fringui.py
@@ -37,14 +37,6 @@ ui = """
<separator />
<menuitem action="Quit"/>
</menu>
-
- <menu action="TreeWalker">
- <menuitem action="Python"/>
- <menuitem action="Python gnomevfs"/>
- <menuitem action="c++"/>
- </menu>
-
-
<menu action="View">
<menuitem action="Show Hidden Files"/>
<separator />
@@ -71,6 +63,7 @@ class UI( gtk.Window ):
self.zoomfactor = 1.0
self.renderer = FringRenderer()
self.walker = FringWalker();
+ self.scan_active = False
# create gui
gtk.Window.__init__(self)
@@ -91,7 +84,6 @@ class UI( gtk.Window ):
self.add_accel_group(accelgroup)
ag_global = gtk.ActionGroup('ag_global')
ag_global.add_actions([
- ('TreeWalker', None, "TreeWalker"),
('FRing', None, "_Folder"),
('View', None, "_View"),
('Help', None, "_Help"),
@@ -108,15 +100,6 @@ class UI( gtk.Window ):
action.set_active(True)
action.connect("toggled",self.__hidden_files_toggled)
ag_global.add_action(action)
-
- # add a menu with radio buttons to choose the walking method
- ag_global.add_radio_actions([
- ('Python', None, "Python", None, None, WALKER_CLASSIC),
- ('Python gnomevfs', None, "Python gnomevfs", None, None, WALKER_GNOMEVFS),
- ('c++', None, "c++", None, None, WALKER_CPP),
- ], 1)
- self.methodaction = ag_global.get_action("c++")
-
uimanager.insert_action_group(ag_global, 0)
uimanager.add_ui_from_string(ui)
menubar = uimanager.get_widget('/MenuBar')
@@ -130,6 +113,8 @@ class UI( gtk.Window ):
b.set_property("image", img)
uimanager.get_action("/MenuBar/FRing/OpenParent").connect_proxy(b)
toolbar.pack_start( b, False )
+ b.connect("enter-notify-event",self.__enter_parent_button)
+ b.connect("leave-notify-event",self.__leave_parent_button)
b = gtk.FileChooserButton('Select a Folder')
b.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
@@ -194,9 +179,7 @@ class UI( gtk.Window ):
gtk.main_quit()
def open_parent(self,widget):
- p = os.path.split(self.uri)
- p = os.path.join(p[:-1])
- self.open_folder(p[0])
+ self.open_folder(self.__get_parent(self.uri))
def zoom(self,widget,factor):
self.zoomfactor += factor
@@ -242,12 +225,19 @@ class UI( gtk.Window ):
#----------------------------------------------------------- private methods
+ def __get_parent(self,uri):
+ """ Get the parent folder from an uri """
+ p = os.path.split(uri)
+ p = os.path.join(p[:-1])
+ return p[0]
+
def __set_uri(self,uri):
""" Set a path and start parsing. Also used to refresh or reset. """
self.uri = uri
self.walker.stop()
if uri:
- self.walker.walk(uri,self.methodaction.get_current_value())
+ self.walker.walk(uri)
+ self.scan_active = True
self.__show_busy_cursor(1)
def __selectfolder(self,widget):
@@ -263,27 +253,30 @@ class UI( gtk.Window ):
self.walker.showhidden = widget.get_active()
self.__set_uri(self.uri)
- def __move_event(self, widget, event):
-
+ def __move_event(self, widget, event):
f = self.renderer.get_hotspot_at(event.x, event.y)
- if f is None:
- self.label.set_text("Ready.")
- else:
- self.label.set_markup("Path <b>%s</b>, %s, %0.1f%%" % (f.path, pretty_size(f.size), f.value*100))
+ self.label.set_text("")
+ if f:
+
+ markup = "<b>%s</b>, %s, %0.1f%%" % (f.path, pretty_size(f.sumlist.size), f.value*100)
+ self.label.set_markup(markup)
- if f is None or not f.is_dir:
- if self.busy_cursor > 0: cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
- else: cursor = None
- self.eventbox.window.set_cursor(cursor)
- else:
- # always display a hand when hovering a link
- self.eventbox.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND1))
+ if f.sumlist.children is not None:
+ self.eventbox.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND1))
+ return
+
+ self.eventbox.window.set_cursor(None)
def __click_event(self, widget, event):
f = self.renderer.get_hotspot_at(event.x, event.y)
- if f is not None:
- if f.is_dir:
- self.open_folder(f.path)
+ if f and f.sumlist.children:
+
+ #if self.scan_active:
+ # if we are still walking the tree, start a new scan on the path
+ self.__set_uri(f.path)
+ #else:
+ # if we are sure that the sumlist is complete, jump there directly
+ #self.__list_changed(None,f.sumlist)
def __scroll_event(self, widget, event):
if event.direction is gtk.gdk.SCROLL_UP:
@@ -306,11 +299,11 @@ class UI( gtk.Window ):
def __list_changed(self,widget,data):
self.data = data
self.redraw()
- #print data.name
def __walker_finished(self, widget, data):
self.__list_changed(widget, data)
self.__show_busy_cursor(-1)
+ self.scan_active = False
def __on_resize(self, widget, event):
r = self.eventbox.get_allocation()
@@ -321,13 +314,16 @@ class UI( gtk.Window ):
def __show_busy_cursor(self, value):
if self.busy_cursor <= 0 and self.busy_cursor+value >= 0:
if self.window: self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
- self.label.set_markup("Busy...")
elif self.busy_cursor > 0 and self.busy_cursor+value <= 0:
if self.window: self.window.set_cursor(None)
- self.label.set_text("Ready.")
self.busy_cursor += value
#print "busy state:",self.busy_cursor
+ def __enter_parent_button(self,widget,event):
+ markup = "<b>%s</b>" %self.__get_parent(self.uri)
+ self.label.set_markup(markup)
+ def __leave_parent_button(self,widget,event):
+ self.label.set_markup("")
diff --git a/src/fringlib/fringwalker.py b/src/fringlib/fringwalker.py
index d897123..cede5af 100644
--- a/src/fringlib/fringwalker.py
+++ b/src/fringlib/fringwalker.py
@@ -7,25 +7,38 @@ import gobject, gtk
from gnomevfs import *
try: import fringtools
-except: print 'Error: Could not find "fringtools" extension module'
+except: pass
-WALKER_CLASSIC = 0
-WALKER_GNOMEVFS = 1
-WALKER_CPP = 2
+class SumList:
+
+ def __init__(self, name, children, size):
+ self.name = name
+ self.children = children
+ self.size = size
+
+ def __getitem__(self, key):
+ if key == 0: return self.name
+ if key == 1: return self.children
+ if key == 2: return self.size
+
+ def __len__(self):
+ return 3
-def print_tree( treearray, tab=0 ):
+
+def print_tree( sumlist, tab=0 ):
""" An utility function to print out a tree array """
- fn, data, size = treearray
- print " "*tab,"%s (%i)"%(fn,size)
- if not data: return
+ print " "*tab,"%s (%i)"%(sumlist.name,sumlist.size)
+ if not sumlist.children: return
if tab > 1: return
- for e in data:
+ for e in sumlist.children:
print_tree(e,tab+1)
+
def treearray_cmp_by_size( b, a ):
return cmp(a[2], b[2]) # compare sizes
+
def treearray_cmp_fn( b, a ):
""" a and b are tuples describing a directory tree. Compare first by directory
status, then by size, and finally by name. """
@@ -66,9 +79,9 @@ class FringWalker( gobject.GObject ):
self.thread = None
self.showhidden = False
- def walk(self,uri,method=WALKER_GNOMEVFS):
+ def walk(self,uri):
self.stop()
- self.thread = WalkThread(self,uri,self.showhidden,method)
+ self.thread = WalkThread(self,uri,self.showhidden)
self.thread.start()
def stop(self):
@@ -97,14 +110,13 @@ class WalkThread( threading.Thread ):
""" A separate class for the thread. """
- def __init__(self, master, uri, showhidden, method=WALKER_CLASSIC):
+ def __init__(self, master, uri, showhidden):
""" Parameters: A FringWalker instance, a string with the path and a bool """
threading.Thread.__init__(self)
self.stopsignal = False
self.master = master
self.uri = URI(uri)
self.showhidden = showhidden
- self.method = method
self.max_recursion_sort = 3
@@ -114,24 +126,6 @@ class WalkThread( threading.Thread ):
f = posixpath.split( f )[-1]
return f
- def build_tree_python(self, path):
- l = []
- total = 0
- for fn in os.listdir(path):
- if self.stopsignal: return (None,None,0)
- if not self.showhidden and fn[0] == ".": continue
- try: p = os.path.join(path, fn)
- except: continue
- s = os.lstat(p)
- if stat.S_ISDIR(s.st_mode):
- sub = self.build_tree_python(p)
- l.append( sub )
- total += sub[2]
- elif stat.S_ISREG(s.st_mode):
- l.append( (fn, None, s.st_size) )
- total += s.st_size
- return (os.path.split(path)[-1], l, total)
-
def build_tree_gnomevfs(self, uri, recursionlvl=0):
@@ -156,14 +150,14 @@ class WalkThread( threading.Thread ):
l.append( sub )
total += sub[2]
else:
- l.append( (d.name, None, d.size) )
+ l.append( SumList(d.name, None, d.size) )
total += d.size
except StopIteration: pass
if recursionlvl <= self.max_recursion_sort:
l.sort(treearray_cmp_by_size)
- return (self.__uri_tail(uri), l, total)
+ return SumList(self.__uri_tail(uri), l, total)
def run(self):
@@ -172,9 +166,6 @@ class WalkThread( threading.Thread ):
# write some debug information
starttime = time.time()
print "start walking",self.uri,
- if self.method == WALKER_CPP: print "(using c++ extension)"
- elif self.method == WALKER_GNOMEVFS: print "(using python and gnomevfs)"
- else: print "(using classic python)"
# scan root directory first (using gnomevfs)
try: h = DirectoryHandle(self.uri)
@@ -197,47 +188,39 @@ class WalkThread( threading.Thread ):
if d.type == 2: # directory
subdirectories.append( d.name );
else:
- l.append( (d.name, None, d.size) )
+ l.append( SumList(d.name, None, d.size) )
total += d.size
except StopIteration: pass
# emit an intermediate version to fill up the screen while waiting
- self.master._progress_fn(self,
- 0, len(subdirectories),
- (self.__uri_tail(self.uri), l, total))
+ sumlist = SumList(self.__uri_tail(self.uri), l, total)
+ self.master._progress_fn(self, 0, len(subdirectories), sumlist)
- # now walk the subdirectories with the faster extension function
+ # walk the subdirectories
c = 0
-
for directory in subdirectories:
c += 1
- if self.method == WALKER_CPP:
- path = get_local_path_from_uri(str(self.uri))+os.sep+directory
- sub = fringtools.build_tree(path, self.showhidden)
- elif self.method == WALKER_GNOMEVFS:
- uri = self.uri
- sub = self.build_tree_gnomevfs(uri.append_path(directory))
- else:
- path = get_local_path_from_uri(str(self.uri))+os.sep+directory
- sub = self.build_tree_python(path)
+ uri = self.uri
+ sub = self.build_tree_gnomevfs(uri.append_path(directory))
if self.stopsignal: return
- total += sub[2]
- l.append( (directory,sub[1],sub[2]) );
+ total += sub.size
+ sub.name = directory
+ l.append( sub );
l.sort(treearray_cmp_fn)
# emit an intermediate version after each directory
- self.master._progress_fn(self,
- c, len(subdirectories),
- (self.__uri_tail(self.uri), l, total))
+ sumlist = SumList(self.__uri_tail(self.uri), l, total)
+ self.master._progress_fn(self, c, len(subdirectories), sumlist)
l.sort(treearray_cmp_fn)
# emit final signal
- self.master._finished_fn(self,(self.__uri_tail(self.uri), l, total))
+ sumlist = SumList(self.__uri_tail(self.uri), l, total)
+ self.master._finished_fn(self,sumlist)
print "finished walking",self.uri,"(time=%s)"%round(time.time()-starttime,2)