]> git.plutz.net Git - viper/commitdiff
started basic frameset support
authorpaul <paul@plutz.net>
Sat, 9 Apr 2011 20:48:20 +0000 (20:48 +0000)
committerpaul <paul@plutz.net>
Sat, 9 Apr 2011 20:48:20 +0000 (20:48 +0000)
svn path=/trunk/; revision=4

main.py
timeline.py
vframeset.py [new file with mode: 0644]

diff --git a/main.py b/main.py
index 92511f3d475f3455515a09cdd57546c93a4695a6..33c592b5ba0f29bc72702fcf5c14b7ae3712db96 100755 (executable)
--- a/main.py
+++ b/main.py
@@ -2,7 +2,7 @@
 #encoding: utf-8
 
 #Viper - Video In Python Editing Reptile, a video editor
-#Copyright 2009 - 2010 Paul Hänsch
+#Copyright 2009 - 2011 Paul Hänsch
 
 #This file is part of Viper.
 
@@ -101,27 +101,33 @@ class Main(Tk):
         call named_save_project() if no
         project directory is set yet
         """
-
-        self.named_save_project()
+       if self.subgets['timeline'].get_basedir() == None:
+           self.named_save_project()
+       else:
+           savedir = self.subgets['timeline'].get_basedir()
+            try: os.unlink(savedir + '/description.sqlite')
+           except: pass
+
+            dbcon = sqlite.connect(savedir + '/description.sqlite')
+            dbcur =  dbcon.cursor()
+            dbcur.execute('CREATE TABLE chunks (iorder INTEGER PRIMARY KEY, filename TEXT, start REAL, frames INTEGER, played INTEGER, marked BOOLEAN);')
+            dbcur.execute('CREATE TABLE filters (iorder INTEGER PRIMARY KEY, chunk INTEGER, FOREIGN KEY (chunk) REFERENCES chunks (iorder));')
+            dbcur.execute('CREATE TABLE filter_lines (iorder INTEGER PRIMARY KEY, line TEXT, filter INTEGER, FOREIGN KEY (filter) REFERENCES filters (iorder));')
+            for chunk in self.subgets['timeline'].chunks:
+                chunk.store(dbcur)
+    
+            dbcur.close()
+            dbcon.commit()
+            dbcon.close()
 
     def named_save_project(self):
         """
         Ask for directory to save to (and save project)
         """
-
         savedir = tkFileDialog.asksaveasfilename(filetypes = [('Viper Project Directory', '*.vpd')])
         os.makedirs(savedir)
-        dbcon = sqlite.connect(savedir + '/description.sqlite')
-        dbcur =  dbcon.cursor()
-        dbcur.execute('CREATE TABLE chunks (iorder INTEGER PRIMARY KEY, filename TEXT, start REAL, frames INTEGER, played INTEGER, marked BOOLEAN);')
-        dbcur.execute('CREATE TABLE filters (iorder INTEGER PRIMARY KEY, chunk INTEGER, FOREIGN KEY (chunk) REFERENCES chunks (iorder));')
-        dbcur.execute('CREATE TABLE filter_lines (iorder INTEGER PRIMARY KEY, line TEXT, filter INTEGER, FOREIGN KEY (filter) REFERENCES filters (iorder));')
-        for chunk in self.subgets['timeline'].chunks:
-            chunk.store(dbcur)
-
-        dbcur.close()
-        dbcon.commit()
-        dbcon.close()
+       self.subgets['timeline'].set_basedir(savedir)
+       self.save_project()
 
     def open_project(self):
         """
@@ -130,6 +136,7 @@ class Main(Tk):
         """
 
         opendir = tkFileDialog.askopenfilename(filetypes = [('Project Description', '*/description.sqlite')])
+       self.subgets['timeline'].set_basedir(opendir[0:-19])
 
         for chunk in self.subgets['timeline'].chunks: chunk.delete()
 
index 1ed4d5ca1061ee91ea74c4320b6d73db0f257917..548280093ca38ad5b2010505b1a34bc1264a7476 100644 (file)
@@ -1,5 +1,5 @@
 #encoding: utf-8
-#Copyright 2009 - 2010 Paul Hänsch
+#Copyright 2009 - 2011 Paul Hänsch
 
 #This file is part of Viper.
 
@@ -18,6 +18,7 @@
 
 from Tkinter import *
 from vchunk import *
+from vframeset import *
 import Pmw
 
 class Timeline(Frame):
@@ -44,6 +45,7 @@ class Timeline(Frame):
         self.chunks = []
         self.mods = []    # list of chunk modifying objects (filter and effect dialogs)
         self.view = None  # viewer widget
+       self.basedir = None  #path of project directory, required for framesets
         self.animChunks = BooleanVar(value = True)
         tooltips = Pmw.Balloon(self)
 
@@ -109,9 +111,22 @@ class Timeline(Frame):
 
     def convert(self):
         """
-        Converts marked chunks to framesets (not yet implemented)
+        Converts marked chunks to framesets
         """
-        pass
+       for vc in self.chunks:
+            if vc.marked.get():
+                index = self.chunks.index(vc)
+                new = VFrameset(self.subgets['chunklist'].interior(),
+                                vurl = vc.videofile,
+                               )
+                new.played.set(value = vc.played.get())
+                new.marked.set(value = vc.marked.get())
+                new.play()
+                new.pack(before = vc, side=LEFT)
+                self.chunks.insert(index, new)
+                self.chunks.remove(vc)
+                vc.stop()
+                vc.destroy()
 
     def playall(self):
         """
@@ -219,3 +234,10 @@ class Timeline(Frame):
 
     def set_mods(self, mods):
         self.mods = mods
+
+    def set_basedir(self, basedir):
+       self.basedir = basedir
+       self.subgets['b_frameset'].config(state = 'normal')
+
+    def get_basedir(self):
+       return self.basedir
diff --git a/vframeset.py b/vframeset.py
new file mode 100644 (file)
index 0000000..ffdc945
--- /dev/null
@@ -0,0 +1,178 @@
+#encoding: utf-8
+#Copyright 2011 Paul Hänsch
+
+#This file is part of Viper.
+
+#Viper 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.
+
+#Viper 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 Viper.  If not, see <http://www.gnu.org/licenses/>
+
+from Tkinter import *
+import Pmw
+from flic import *
+
+class VFrameset(LabelFrame, Flic):
+    """
+    Visual frameset widget
+
+    This widget represents a set of frames and provides controls for manipulating
+    and positioning it.
+
+    Properties are:
+    schedule (string)   - commands to the owning object, values can be
+                            mv left : move this chunk left
+                            mv right: move this chunk right
+                            copy    : double this chunk
+                            apply   : realize new video properties
+                            delete  : remove this chunk
+    
+    subgets             - dictionary of widgets forming this
+                          complex widget
+    played (Tk.Boolean) - indicates status of the play checkbox (use ...play.get())
+    marked (Tk.Boolean) - indicates status of the mark checkbox (use ...mark.get())
+    """
+
+    def __init__(self, master = None, vurl = '', play = True):
+        """
+        Constructor
+
+        master - the holding widget
+        """
+       self.vurl = vurl
+        self.subgets = {}
+        self.schedule = ''
+        self.animate = play
+        self.played = BooleanVar(value = True)
+        self.marked = BooleanVar(value = True)
+
+        tooltips = Pmw.Balloon()
+
+        Flic.__init__(self)
+        LabelFrame.__init__(self, master = master, text = vurl.split('/')[-1])
+        self.subgets['video'] = Frame(self, height=90, width=120, bg = '#000000')
+        self.subgets['video'].grid(column=0, row=0, rowspan=4, sticky=W)
+
+       self.subgets['b_edit'] = Button(self, text = 'Edit', command = self.edit)
+       self.subgets['b_edit'].grid(column = 1, row=1, columnspan = 4, rowspan = 2)
+        tooltips.bind(self.subgets['b_edit'], 'Select and remove single frames from frameset.')
+
+        self.subgets['b_mvbw'] = Button(self, text = '<-', command=self.mvbw)
+        self.subgets['b_mvbw'].grid(column = 1, row = 3, rowspan = 1, columnspan = 2, sticky=E)
+        tooltips.bind(self.subgets['b_mvbw'],
+                      'Swap this chunk with its left neighbour (move it left).')
+
+        self.subgets['b_copy'] = Button(self, text = 'Copy', command=self.copy)
+        self.subgets['b_copy'].grid(column = 3, columnspan = 2, row = 3, rowspan = 1)
+        tooltips.bind(self.subgets['b_copy'],
+                      'Create another chunk with the same properties as this one.')
+
+        self.subgets['b_mvfw'] = Button(self, text = '->', command=self.mvfw)
+        self.subgets['b_mvfw'].grid(column = 5, row = 3, rowspan = 1, sticky=W)
+        tooltips.bind(self.subgets['b_mvfw'],
+                      'Swap this chunk with its right neighbour (move it right).')
+
+        self.subgets['c_play'] = Checkbutton(self, text='Play', offvalue=False,
+                                             onvalue=True, variable = self.played)
+#        self.subgets['c_play'].select()
+        self.subgets['c_play'].grid(column=1, columnspan = 2, row=0)
+        tooltips.bind(self.subgets['c_play'],
+                      'Mark this chunk for playback in main window.')
+
+        self.subgets['c_mark'] = Checkbutton(self, text='Mark', offvalue=False,
+                                             onvalue=True, variable = self.marked)
+#        self.subgets['c_mark'].select()
+        self.subgets['c_mark'].grid(column=3, columnspan = 2, row=0)
+        tooltips.bind(self.subgets['c_mark'],
+                      'Mark this chunk for application of choosen filters and effects.')
+
+        self.subgets['b_del'] = Button(self, text='Del', command = self.delete)
+        self.subgets['b_del'].grid(column=5, row=0, sticky=NE)
+        tooltips.bind(self.subgets['b_del'],
+                      'Remove this chunk from the project.')
+        self.schedule = 'apply'
+
+    def load_filters(self, dbcur, num):
+        """
+        Load filter list from database
+
+        db  - sqlite database cursor
+        num - database primary key id of this chunk
+        """
+
+        dbcur.execute('SELECT iorder FROM filters ' +
+                      'WHERE chunk = ' + str(num) + ' ORDER BY iorder')
+        for filter in dbcur.fetchall():
+            dbcur.execute('SELECT line FROM filter_lines WHERE filter = ' +
+                          str(filter[0]) + ' ORDER BY iorder')
+            line = []
+            for item in dbcur.fetchall():
+                line.append(item[0])
+            self.add_filter(line)
+
+    def delete(self):
+        """
+        Scheduler for internal use
+        """
+        self.schedule = 'delete'
+
+    def mvbw(self):
+        """
+        Scheduler for internal use
+        """
+        self.schedule = 'mv left'
+
+    def mvfw(self):
+        """
+        Scheduler for internal use
+        """
+        self.schedule = 'mv right'
+
+    def copy(self):
+        """
+        Scheduler for internal use
+        """
+        self.schedule = 'copy'
+
+    def store(self, dbcur):
+        """
+        Store chunk to database
+
+        The tables "chunks", "filters" and "filter_lines"
+        must be prepared in database.
+
+        dbcur - sqlite database cursor
+        """
+        if self.played.get(): played = '1'
+        else: played = '0'
+        if self.marked.get(): marked = '1'
+        else: marked = '0'
+        dbcur.execute('INSERT INTO chunks (filename, start, frames, played, marked) ' + 
+                      'VALUES ("' + self.vurl + '", 0, 0, ' + played + ', ' + marked + ');')
+
+        dbcur.execute('SELECT last_insert_rowid();')
+        chunk_id = str(dbcur.fetchone()[0])
+
+        for filter in self.filters:
+            dbcur.execute('INSERT INTO filters (chunk) VALUES (' + chunk_id + ');')
+            dbcur.execute('SELECT last_insert_rowid();')
+            filter_id = str(dbcur.fetchone()[0])
+            for line in filter:
+                dbcur.execute('INSERT INTO filter_lines (line, filter) ' +
+                              'VALUES ("' + line + '", ' + filter_id + ')')
+    def slave_video(self):
+       return [self.vurl]
+
+    def edit(self):
+        self.schedule = 'apply'
+
+    def play(self):
+        Flic.play(self, self.subgets['video'].winfo_id(), width=120, height=90)