VFile.py: fix bogus getrandomframe().
Vedit.py, VeditForm.fd: added scroll bar, Trunc, layout rearrangement.
Viewer.py: added random access, qinfo() function.
diff --git a/Demo/sgi/video/VFile.py b/Demo/sgi/video/VFile.py
index 9e1eb36..c61ac04 100755
--- a/Demo/sgi/video/VFile.py
+++ b/Demo/sgi/video/VFile.py
@@ -978,8 +978,8 @@
 
 	def getrandomframe(self, i):
 		t, ds, cs = self.getrandomframeheader(i)
-		data, cdata = self.getnextframedata()
-		return t, ds, cs
+		data, cdata = self.getnextframedata(ds, cs)
+		return t, data, cdata
 
 	def getrandomframeheader(self, i):
 		if i < 0: raise ValueError, 'negative frame index'
diff --git a/Demo/sgi/video/Vedit.py b/Demo/sgi/video/Vedit.py
index 4d763b0..d5ef365 100755
--- a/Demo/sgi/video/Vedit.py
+++ b/Demo/sgi/video/Vedit.py
@@ -19,6 +19,11 @@
 import Viewer
 import getopt
 import string
+import watchcursor
+
+ARROW = 0
+WATCH = 1
+watchcursor.defwatch(WATCH)
 
 
 def main():
@@ -57,6 +62,14 @@
 			if self.vout:
 				self.vout.redraw(val)
 
+	def busy(self):
+		gl.winset(self.form.window)
+		gl.setcursor(WATCH, 0, 0)
+
+	def ready(self):
+		gl.winset(self.form.window)
+		gl.setcursor(ARROW, 0, 0)
+
 
 	def iocheck(self):
 		self.msg('')
@@ -98,7 +111,18 @@
 
 	def cb_in_back(self, *args):
 		if not self.icheck(): return
-		if not self.vin.backup(): self.err('Input buffer exhausted')
+		if not self.vin.backup(): self.err('Begin of input file')
+		self.ishow()
+
+	def cb_in_slider(self, *args):
+		if not self.icheck(): return
+		left, pos, right = self.vin.qinfo()
+		i = int(self.in_slider.get_slider_value())
+		i = max(i, left)
+		i = min(i, right)
+		if i == pos: return
+		if not self.vin.seek(i):
+			self.err('Input seek failed')
 		self.ishow()
 
 	def cb_in_rewind(self, *args):
@@ -128,7 +152,7 @@
 			return
 		self.oshow()
 		if not self.vin.backup():
-			self.err('Input buffer exhausted')
+			self.err('Begin of input file')
 			return
 		self.ishow()
 
@@ -154,6 +178,23 @@
 		if not self.vout.backup(): self.err('Output buffer exhausted')
 		self.oshow()
 
+	def cb_out_slider(self, *args):
+		if not self.ocheck(): return
+		i = int(self.out_slider.get_slider_value())
+		left, pos, right = self.vout.qinfo()
+		i = int(self.out_slider.get_slider_value())
+		i = max(i, left)
+		i = min(i, right)
+		if i == pos: return
+		if not self.vout.seek(i):
+			self.err('Output seek failed')
+		self.oshow()
+
+	def cb_out_trunc(self, *arcs):
+		if not self.ocheck(): return
+		self.vout.trunc()
+		self.oshow()
+
 	def cb_out_rewind(self, *args):
 		if not self.ocheck(): return
 		self.vout.rewind()
@@ -171,8 +212,7 @@
 		basename = os.path.split(filename)[1]
 		title = 'in: ' + basename
 		try:
-			vin = Viewer.InputViewer().init(filename, \
-				title, self.qsize)
+			vin = Viewer.InputViewer().init(filename, title)
 		except:
 			self.err('Can\'t open input file', filename)
 			return
@@ -183,8 +223,10 @@
 
 	def close_input(self):
 		if self.vin:
+			self.busy()
 			self.msg('Closing input file...')
 			self.vin.close()
+			self.ready()
 		self.msg('')
 		self.vin = None
 		self.in_file.label = '(none)'
@@ -213,8 +255,10 @@
 
 	def close_output(self):
 		if self.vout:
+			self.busy()
 			self.msg('Closing output file...')
 			self.vout.close()
+			self.ready()
 		self.msg('')
 		self.vout = None
 		self.out_file.label = '(none)'
@@ -238,13 +282,15 @@
 		if v == None:
 			left = right = pos = 0
 		else:
-			left, right = v.qsizes()
-			pos = v.tell()
-			left = pos - left
-			right = pos + right
+			left, pos, right = v.qinfo()
 		getattr(self, io + '_info1').label = `left`
 		getattr(self, io + '_info2').label = `pos`
 		getattr(self, io + '_info3').label = `right`
+		sl = getattr(self, io + '_slider')
+		sl.freeze_object()
+		sl.set_slider_bounds(left, right)
+		sl.set_slider_value(pos)
+		sl.unfreeze_object()
 
 
 try:
diff --git a/Demo/sgi/video/VeditForm.fd b/Demo/sgi/video/VeditForm.fd
index 0f1359d..ba59de4 100644
--- a/Demo/sgi/video/VeditForm.fd
+++ b/Demo/sgi/video/VeditForm.fd
@@ -7,14 +7,14 @@
 
 =============== FORM ===============
 Name: form
-Width: 480.000000
-Height: 290.000000
-Number of Objects: 23
+Width: 510.000000
+Height: 350.000000
+Number of Objects: 28
 
 --------------------
 class: 1
 type: 1
-box: 0.000000 0.000000 480.000000 290.000000
+box: 0.000000 0.000000 510.000000 350.000000
 boxtype: 1
 colors: 47 47
 alignment: 4
@@ -27,9 +27,54 @@
 argument: 
 
 --------------------
+class: 1
+type: 6
+box: 10.000000 130.000000 240.000000 209.999985
+boxtype: 6
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: 
+name: 
+callback: 
+argument: 
+
+--------------------
+class: 1
+type: 6
+box: 260.000000 130.000000 240.000000 209.999985
+boxtype: 6
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: 
+name: 
+callback: 
+argument: 
+
+--------------------
+class: 2
+type: 0
+box: 10.000000 10.000000 430.000000 30.000000
+boxtype: 6
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: CMIF Video Editor, by Guido van Rossum
+name: msg_area
+callback: 
+argument: 
+
+--------------------
 class: 11
 type: 4
-box: 180.000000 70.000000 120.000000 40.000000
+box: 200.000000 90.000000 120.000000 30.000000
 boxtype: 1
 colors: 47 47
 alignment: 4
@@ -44,7 +89,7 @@
 --------------------
 class: 11
 type: 4
-box: 90.000000 50.000000 60.000000 60.000000
+box: 210.000000 220.000000 30.000000 30.000000
 boxtype: 1
 colors: 47 47
 alignment: 4
@@ -59,14 +104,14 @@
 --------------------
 class: 11
 type: 0
-box: 10.000000 10.000000 140.000000 30.000000
+box: 20.000000 140.000000 220.000000 30.000000
 boxtype: 1
 colors: 47 47
 alignment: 4
 style: 0
 size: 11.000000
 lcol: 0
-label: Rewind input
+label: Rewind
 name: 
 callback: cb_in_rewind
 argument: 0
@@ -74,14 +119,14 @@
 --------------------
 class: 11
 type: 0
-box: 330.000000 10.000000 140.000000 30.000000
+box: 270.000000 140.000000 100.000000 30.000000
 boxtype: 1
 colors: 47 47
 alignment: 4
 style: 0
 size: 11.000000
 lcol: 0
-label: Clear output
+label: Reset
 name: 
 callback: cb_out_rewind
 argument: 0
@@ -89,14 +134,14 @@
 --------------------
 class: 11
 type: 0
-box: 10.000000 210.000000 80.000000 30.000000
+box: 20.000000 260.000000 160.000000 30.000000
 boxtype: 1
 colors: 47 47
 alignment: 4
 style: 0
 size: 11.000000
 lcol: 0
-label: Input file...
+label: New input file...
 name: 
 callback: cb_in_new
 argument: 0
@@ -104,14 +149,14 @@
 --------------------
 class: 11
 type: 0
-box: 330.000000 210.000000 80.000000 30.000000
+box: 330.000000 260.000000 160.000000 30.000000
 boxtype: 1
 colors: 47 47
 alignment: 4
 style: 0
 size: 11.000000
 lcol: 0
-label: Output file...
+label: New output file...
 name: 
 callback: cb_out_new
 argument: 0
@@ -119,7 +164,7 @@
 --------------------
 class: 2
 type: 0
-box: 10.000000 170.000000 140.000000 30.000000
+box: 20.000000 300.000000 220.000000 30.000000
 boxtype: 6
 colors: 47 47
 alignment: 4
@@ -134,7 +179,7 @@
 --------------------
 class: 2
 type: 0
-box: 330.000000 170.000000 140.000000 30.000000
+box: 270.000000 300.000000 220.000000 30.000000
 boxtype: 6
 colors: 47 47
 alignment: 4
@@ -147,24 +192,9 @@
 argument: 
 
 --------------------
-class: 2
-type: 0
-box: 10.000000 130.000000 30.000000 30.000000
-boxtype: 6
-colors: 47 47
-alignment: 4
-style: 0
-size: 8.000000
-lcol: 0
-label: 
-name: in_info1
-callback: 
-argument: 
-
---------------------
 class: 11
 type: 0
-box: 170.000000 210.000000 140.000000 30.000000
+box: 450.000000 10.000000 50.000000 30.000000
 boxtype: 1
 colors: 47 47
 alignment: 4
@@ -179,7 +209,7 @@
 --------------------
 class: 11
 type: 4
-box: 330.000000 50.000000 60.000000 60.000000
+box: 270.000000 220.000000 30.000000 30.000000
 boxtype: 1
 colors: 47 47
 alignment: 4
@@ -194,7 +224,7 @@
 --------------------
 class: 11
 type: 4
-box: 10.000000 50.000000 60.000000 60.000000
+box: 20.000000 220.000000 30.000000 30.000000
 boxtype: 1
 colors: 47 47
 alignment: 4
@@ -209,7 +239,7 @@
 --------------------
 class: 11
 type: 4
-box: 410.000000 50.000000 60.000000 60.000000
+box: 460.000000 220.000000 30.000000 30.000000
 boxtype: 1
 colors: 47 47
 alignment: 4
@@ -224,7 +254,7 @@
 --------------------
 class: 11
 type: 4
-box: 180.000000 20.000000 120.000000 40.000000
+box: 200.000000 50.000000 120.000000 30.000000
 boxtype: 1
 colors: 47 47
 alignment: 4
@@ -239,7 +269,7 @@
 --------------------
 class: 11
 type: 0
-box: 100.000000 210.000000 50.000000 30.000000
+box: 190.000000 260.000000 50.000000 30.000000
 boxtype: 1
 colors: 47 47
 alignment: 4
@@ -254,7 +284,7 @@
 --------------------
 class: 11
 type: 0
-box: 420.000000 210.000000 50.000000 30.000000
+box: 270.000000 260.000000 50.000000 30.000000
 boxtype: 1
 colors: 47 47
 alignment: 4
@@ -267,24 +297,54 @@
 argument: 0
 
 --------------------
+class: 21
+type: 1
+box: 60.000000 220.000000 140.000000 30.000000
+boxtype: 2
+colors: 47 47
+alignment: 1
+style: 0
+size: 11.000000
+lcol: 0
+label: 
+name: in_slider
+callback: cb_in_slider
+argument: 0
+
+--------------------
+class: 21
+type: 1
+box: 310.000000 220.000000 140.000000 30.000000
+boxtype: 2
+colors: 47 47
+alignment: 1
+style: 0
+size: 11.000000
+lcol: 0
+label: 
+name: out_slider
+callback: cb_out_slider
+argument: 0
+
+--------------------
 class: 2
 type: 0
-box: 10.000000 250.000000 460.000000 30.000000
+box: 20.000000 180.000000 30.000000 30.000000
 boxtype: 6
 colors: 47 47
 alignment: 4
 style: 0
-size: 11.000000
+size: 8.000000
 lcol: 0
-label: CMIF Video Editor, by Guido van Rossum
-name: msg_area
+label: 
+name: in_info1
 callback: 
 argument: 
 
 --------------------
 class: 2
 type: 0
-box: 50.000000 130.000000 60.000004 30.000000
+box: 100.000000 180.000000 60.000004 30.000000
 boxtype: 6
 colors: 47 47
 alignment: 4
@@ -299,7 +359,7 @@
 --------------------
 class: 2
 type: 0
-box: 120.000000 130.000000 30.000000 30.000000
+box: 210.000000 180.000000 30.000000 30.000000
 boxtype: 6
 colors: 47 47
 alignment: 4
@@ -314,7 +374,7 @@
 --------------------
 class: 2
 type: 0
-box: 330.000000 130.000000 30.000000 30.000000
+box: 270.000000 180.000000 30.000000 30.000000
 boxtype: 6
 colors: 47 47
 alignment: 4
@@ -329,7 +389,7 @@
 --------------------
 class: 2
 type: 0
-box: 370.000000 130.000000 60.000004 30.000000
+box: 350.000000 180.000000 60.000004 30.000000
 boxtype: 6
 colors: 47 47
 alignment: 4
@@ -344,7 +404,7 @@
 --------------------
 class: 2
 type: 0
-box: 440.000000 130.000000 30.000000 30.000000
+box: 460.000000 180.000000 30.000000 30.000000
 boxtype: 6
 colors: 47 47
 alignment: 4
@@ -356,5 +416,20 @@
 callback: 
 argument: 
 
+--------------------
+class: 11
+type: 0
+box: 390.000000 140.000000 100.000000 30.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: Truncate
+name: 
+callback: cb_out_trunc
+argument: 0
+
 ==============================
 create_the_forms
diff --git a/Demo/sgi/video/Viewer.py b/Demo/sgi/video/Viewer.py
index 2a7b2eb..2b9607b 100755
--- a/Demo/sgi/video/Viewer.py
+++ b/Demo/sgi/video/Viewer.py
@@ -5,16 +5,17 @@
 
 class InputViewer:
 
-	def init(self, filename, title, qsize):
+	def init(self, filename, title, *args):
 		try:
 			self.vin = VFile.VinFile().init(filename)
 		except (EOFError, VFile.Error):
 			raise IOError, 'bad video input file'
+		self.vin.warmcache()
 		if not title:
 			title = os.path.split(filename)[1]
 		self.filename = filename
 		self.title = title
-		self.qsize = qsize
+		self.qsize = len(self.vin.index)
 		gl.foreground()
 		gl.prefsize(self.vin.width, self.vin.height)
 		self.wid = -1
@@ -39,27 +40,7 @@
 			gl.winset(self.wid)
 			gl.clear()
 			self.vin.initcolormap()
-		self.queue = []
 		self.qindex = 0
-		self.lost = 0
-		self.lastt = 0
-		self.eofread = 0
-
-	# Internal
-	def fillq(self):
-		if self.qindex < len(self.queue) or self.eofread: return
-		try:
-			t, d, cd = self.vin.getnextframe()
-		except EOFError:
-			self.eofread = 1
-			return
-		dt = t - self.lastt
-		self.lastt = t
-		self.queue.append(dt, d, cd)
-		while len(self.queue) > self.qsize:
-			del self.queue[0]
-			self.qindex = self.qindex - 1
-			self.lost = self.lost + 1
 
 	def show(self):
 		if self.wid < 0:
@@ -68,12 +49,11 @@
 			self.wid = gl.winopen(self.title)
 			gl.clear()
 			self.vin.initcolormap()
-		self.fillq()
 		gl.winset(self.wid)
-		if self.qindex >= len(self.queue):
+		if self.qindex >= self.qsize:
 			self.vin.clear()
 			return
-		dt, d, cd = self.queue[self.qindex]
+		dt, d, cd = self.vin.getrandomframe(self.qindex)
 		self.vin.showframe(d, cd)
 
 	def redraw(self, wid):
@@ -84,13 +64,16 @@
 			self.show()
 
 	def get(self):
-		if self.qindex >= len(self.queue):
-			self.fillq()
-			if self.eofread:
-				return None
-		item = self.queue[self.qindex]
+		if self.qindex >= self.qsize:
+			return None
+		if self.qindex > 0:
+			prevt, ds, cs = \
+				  self.vin.getrandomframeheader(self.qindex-1)
+		else:
+			prevt = 0
+		t, data, cdata = self.vin.getrandomframe(self.qindex)
 		self.qindex = self.qindex + 1
-		return item
+		return t-prevt, data, cdata
 
 	def backup(self):
 		if self.qindex == 0:
@@ -98,11 +81,20 @@
 		self.qindex = self.qindex - 1
 		return 1
 
+	def seek(self, i):
+		if not 0 <= i <= self.qsize:
+			return 0
+		self.qindex = i
+		return 1
+
 	def tell(self):
-		return self.lost + self.qindex
+		return self.qindex
 
 	def qsizes(self):
-		return self.qindex, len(self.queue) - self.qindex
+		return self.qindex, self.qsize - self.qindex
+
+	def qinfo(self):
+		return 0, self.qindex, self.qsize
 
 
 class OutputViewer:
@@ -206,12 +198,33 @@
 		while len(self.queue) > self.qsize:
 			self.flushq()
 
+	def seek(self, i):
+		i = i - self.written
+		if not 0 <= i <= len(self.queue) + len(self.spares):
+			return 0
+		while i < len(self.queue):
+			if not self.backup():
+				return 0
+		while i > len(self.queue):
+			if not self.forward():
+				return 0
+		return 1
+
+	def trunc(self):
+		del self.spares[:]
+
 	def tell(self):
 		return self.written + len(self.queue)
 
 	def qsizes(self):
 		return len(self.queue), len(self.spares)
 
+	def qinfo(self):
+		first = self.written
+		pos = first + len(self.queue)
+		last = pos + len(self.spares)
+		return first, pos, last
+
 
 def test():
 	import sys