Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorolpc <olpc@xo-10-D5-61.localdomain>2010-06-22 22:37:31 (GMT)
committer olpc <olpc@xo-10-D5-61.localdomain>2010-06-22 22:37:31 (GMT)
commitb5c04ff29befec16f77f4674a95949bc0a36129f (patch)
treeba5d747749b7514da6bc64f72c280895104b1bf3
Initial commitHEADmaster
-rw-r--r--MANIFEST19
-rw-r--r--activity/activity.info8
-rw-r--r--activity/bee.svg39
-rw-r--r--cameramic.py122
-rw-r--r--canvas.glade174
-rw-r--r--canvas.py182
-rw-r--r--collectdata.py135
-rw-r--r--filetools.py3
-rw-r--r--incramentaltab.py46
-rw-r--r--interface.py49
-rw-r--r--journal.py1
-rw-r--r--lapsetab.py35
-rw-r--r--playback.py2
-rw-r--r--qualitytab.py55
-rwxr-xr-xsetup.py20
-rw-r--r--singletab.py41
-rw-r--r--storedata.py79
-rw-r--r--tabs.glade1344
-rw-r--r--timetab.py126
-rw-r--r--tlactivity.py55
20 files changed, 2535 insertions, 0 deletions
diff --git a/MANIFEST b/MANIFEST
new file mode 100644
index 0000000..ecc634a
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,19 @@
+cameramic.py
+collectdata.py
+filetools.py
+incramentaltab.py
+interface.py
+journal.py
+lapsetab.py
+playback.py
+qualitytab.py
+singletab.py
+timetab.py
+storedata.py
+tlactivity.py
+canvas.glade
+tabs.glade
+activity/activity.info
+activity/bee.svg
+setup.py
+canvas.py
diff --git a/activity/activity.info b/activity/activity.info
new file mode 100644
index 0000000..0a68c87
--- /dev/null
+++ b/activity/activity.info
@@ -0,0 +1,8 @@
+[Activity]
+name = TimeLapse
+bundle_id = org.time.lapse
+exec = sugar-activity tlactivity.TimeLapseActivity
+icon = bee
+show_launcher = yes
+activity_version = 2
+license = GPLv3+
diff --git a/activity/bee.svg b/activity/bee.svg
new file mode 100644
index 0000000..39b1a93
--- /dev/null
+++ b/activity/bee.svg
@@ -0,0 +1,39 @@
+<?xml version="1.0" ?>
+<!DOCTYPE svg
+ PUBLIC '-//W3C//DTD SVG 1.1//EN'
+ 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [
+ <!ENTITY stroke_color "#666666">
+ <!ENTITY fill_color "#ffffff">
+]>
+<svg height="55px" id="svg6397" inkscape:version="0.47pre4 r22446" sodipodi:docname="Bee-55.svg" version="1.0" viewBox="0 0 55 55" width="55px" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview bordercolor="#666666" borderopacity="1" gridtolerance="10" guidetolerance="10" id="namedview18" inkscape:current-layer="svg6397" inkscape:cx="3.6652536" inkscape:cy="27.508465" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-height="950" inkscape:window-maximized="1" inkscape:window-width="1280" inkscape:window-x="0" inkscape:window-y="25" inkscape:zoom="6.7428571" objecttolerance="10" pagecolor="#ffffff" showgrid="false"/>
+ <defs id="defs6399">
+ <inkscape:perspective id="perspective20" inkscape:persp3d-origin="180 : 93.333333 : 1" inkscape:vp_x="0 : 140 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="360 : 140 : 1" sodipodi:type="inkscape:persp3d"/>
+ </defs>
+ <metadata id="metadata6402">
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g id="layer1" style="fill:&fill_color;;fill-opacity:1;stroke:&stroke_color;;stroke-width:3.49922243000000011;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" transform="matrix(0.19629287,0,0,0.1963658,-43.456851,-57.372644)">
+ <g id="g6306" style="opacity:0.59999999999999998;fill:&fill_color;;fill-opacity:1;stroke:&stroke_color;;stroke-width:0.18181293000000001;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" transform="matrix(17.048652,0,0,21.727187,-2323.6781,-2707.9177)">
+ <path d="m 157.5,141.44 c -1.1075,1e-5 -1.9525,0.75246 -2.4688,1.625 -0.51621,0.87253 -0.8125,1.945 -0.8125,3.125 -1e-5,1.18 0.29627,2.2837 0.8125,3.1562 0.51626,0.87252 1.3612,1.625 2.4688,1.625 1.1075,1e-5 1.9838,-0.75247 2.5,-1.625 0.51624,-0.87253 0.78125,-1.9763 0.78125,-3.1562 1e-5,-1.18 -0.26503,-2.2525 -0.78125,-3.125 -0.51624,-0.87254 -1.3925,-1.625 -2.5,-1.625 z m 0,1.125 c 1.3974,0 2.5312,1.7315 2.5312,3.8438 0,2.1122 -1.1339,3.8125 -2.5312,3.8125 -1.3974,10e-6 -2.5312,-1.7003 -2.5312,-3.8125 0,-2.1122 1.1339,-3.8438 2.5312,-3.8438 z" id="path6279" style="fill:&fill_color;;fill-opacity:1;stroke:&stroke_color;;stroke-width:0.18181293000000001;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"/>
+ <path d="m 157.51,143.38 c -1.3253,0 -2.5004,0.7134 -3.218,1.8294 -0.0391,0.34998 -0.0568,0.71475 -0.0631,1.0841 0.70869,-1.0261 1.9073,-1.6939 3.2811,-1.6939 1.3592,0 2.5546,0.65205 3.2601,1.66 -0.006,-0.34634 -0.0293,-0.68708 -0.0631,-1.0164 -0.71066,-1.1243 -1.8659,-1.8633 -3.197,-1.8633 z" id="path5951" style="fill:&fill_color;;fill-opacity:1;stroke:&stroke_color;;stroke-width:0.18181293000000001;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"/>
+ <path d="m 156.95,147.81 c -0.82295,0.10739 -1.562,0.48471 -2.1793,0.99408 0.0755,0.14972 0.13941,0.32071 0.2294,0.45881 0.0766,0.11753 0.17629,0.23319 0.26763,0.3441 0.65318,-0.34002 1.4053,-0.53527 2.2176,-0.53527 0.81227,0 1.5637,0.19527 2.2176,0.53527 0.0913,-0.11091 0.19102,-0.22656 0.26763,-0.3441 0.0931,-0.14292 0.19111,-0.30348 0.26763,-0.45881 -0.74809,-0.62694 -1.7081,-0.99408 -2.7528,-0.99408 -0.18827,0 -0.35341,-0.0237 -0.53528,0 z" id="path5956" style="fill:&fill_color;;fill-opacity:1;stroke:&stroke_color;;stroke-width:0.18181293000000001;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"/>
+ <path d="m 157.49,145.54 c -1.2526,0 -2.1824,0.59147 -3.0242,1.4459 0.0479,0.35447 -0.0686,0.63944 0.0419,0.96284 0.81143,-0.62056 1.8458,-0.99409 2.9822,-0.99409 1.1365,0 2.1746,0.37353 2.9822,0.99409 0.10702,-0.3234 0.028,-0.60837 0.0731,-0.96284 -0.8369,-0.86037 -1.7953,-1.4459 -3.0554,-1.4459 z" id="path5958" style="fill:&fill_color;;fill-opacity:1;stroke:&stroke_color;;stroke-width:0.18181293000000001;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"/>
+ <path d="m 159.02108,139.29831 c 0.27063,0 0.50011,0.37344 0.50011,0.83351 0,0.46007 -0.22949,0.8335 -0.50011,0.8335 -0.27063,1e-5 -0.47629,-0.37343 -0.47629,-0.8335 0,-0.46007 0.20566,-0.83351 0.47629,-0.83351 z m -3.04596,0 c 0.27062,0 0.47629,0.37344 0.47629,0.83351 -1e-5,0.46007 -0.20567,0.8335 -0.47629,0.8335 -0.27064,1e-5 -0.50011,-0.37343 -0.50011,-0.8335 0,-0.46007 0.22949,-0.83351 0.50011,-0.83351 z M 157.51,138.08 c -1.5977,0 -2.9054,1.1091 -2.9054,2.5005 0,0.85234 0.49087,1.6145 1.2384,2.0719 0.15172,-0.36117 0.78628,-0.643 1.5718,-0.643 0.84159,0 1.5361,0.31482 1.6194,0.71444 0.81642,-0.44623 1.3574,-1.2402 1.3574,-2.1433 0,-1.3914 -1.2838,-2.5005 -2.8816,-2.5005 z" id="path5883" style="fill:&fill_color;;fill-opacity:1;stroke:&stroke_color;;stroke-width:0.18181293;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"/>
+ <g id="g6140" style="fill:&fill_color;;fill-opacity:1;stroke:&stroke_color;;stroke-width:0.14860222000000001;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" transform="matrix(1.2234873,0,0,1.2234873,-35.199248,-30.859496)">
+ <path d="m 152.47,139.31 c 0.80018,0.0566 2.0102,0.39256 3.3868,1.1873 0.12836,0.0741 0.22996,0.15798 0.35036,0.23357 -0.13259,0.11323 -0.24255,0.24209 -0.35036,0.36983 -0.0795,-0.0502 -0.15047,-0.10773 -0.23358,-0.15572 -0.81876,-0.47271 -1.6521,-0.7421 -2.3357,-0.79804 -0.68363,-0.0559 -1.2167,0.0992 -1.4404,0.48661 -0.44734,0.77484 0.71888,1.8998 2.3564,2.8452 0.11049,0.0638 0.30891,0.19156 0.42061,0.24695 -0.0154,0.0174 -0.33154,0.23609 -0.34396,0.25576 -0.11107,-0.0608 -0.21587,-0.10877 -0.33089,-0.17518 -1.3766,-0.79477 -2.2954,-1.671 -2.7445,-2.3357 -0.44911,-0.66467 -0.52651,-1.2093 -0.29197,-1.6156 0.23454,-0.40623 0.75697,-0.6016 1.5572,-0.545 z m 2.5888,4.9634 c 0.01,0.0381 0.012,0.0775 0.0195,0.11679 -0.0126,-0.006 -0.0263,-0.0138 -0.0389,-0.0195 0.0138,-0.0326 0.014,-0.0612 0.0195,-0.0973 z" id="path6132" style="fill:&fill_color;;fill-opacity:1;stroke:&stroke_color;;stroke-width:0.14860222000000001;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"/>
+ <path d="m 155.24,143.33 c -0.0239,0.0902 -0.0702,0.17466 -0.0883,0.26694 -0.006,0.003 0.002,0.022 -0.005,0.0246 -1.7447,0.69266 -2.7968,1.6517 -2.4,2.3257 0.33162,0.56334 1.557,0.76531 3.084,0.61705 0.0246,0.0332 0.0257,0.0722 0.0515,0.10496 0.0362,0.0461 0.078,0.0905 0.11736,0.13625 -0.81174,0.12183 -1.5532,0.17368 -2.1533,0.14669 -1.0704,-0.0482 -1.7999,-0.28559 -2.0556,-0.71999 -0.25571,-0.4344 0.0173,-0.97667 0.73223,-1.5324 0.58365,-0.45372 1.51,-0.94959 2.7169,-1.3697 z" id="path6134" style="fill:&fill_color;;fill-opacity:1;stroke:&stroke_color;;stroke-width:0.14860222000000001;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"/>
+ </g>
+ <g id="g6144" style="fill:&fill_color;;fill-opacity:1;stroke:&stroke_color;;stroke-width:0.14860222000000001;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" transform="matrix(-1.2234873,0,0,1.2234873,350.19925,-30.859496)">
+ <path d="m 152.47,139.31 c 0.80018,0.0566 2.0102,0.39256 3.3868,1.1873 0.12836,0.0741 0.22996,0.15798 0.35036,0.23357 -0.13259,0.11323 -0.24255,0.24209 -0.35036,0.36983 -0.0795,-0.0502 -0.15047,-0.10773 -0.23358,-0.15572 -0.81876,-0.47271 -1.6521,-0.7421 -2.3357,-0.79804 -0.68363,-0.0559 -1.2167,0.0992 -1.4404,0.48661 -0.44734,0.77484 0.71888,1.8998 2.3564,2.8452 0.11049,0.0638 0.30891,0.19156 0.42061,0.24695 -0.0154,0.0174 -0.33154,0.23609 -0.34396,0.25576 -0.11107,-0.0608 -0.21587,-0.10877 -0.33089,-0.17518 -1.3766,-0.79477 -2.2954,-1.671 -2.7445,-2.3357 -0.44911,-0.66467 -0.52651,-1.2093 -0.29197,-1.6156 0.23454,-0.40623 0.75697,-0.6016 1.5572,-0.545 z m 2.5888,4.9634 c 0.01,0.0381 0.012,0.0775 0.0195,0.11679 -0.0126,-0.006 -0.0263,-0.0138 -0.0389,-0.0195 0.0138,-0.0326 0.014,-0.0612 0.0195,-0.0973 z" id="path6146" style="fill:&fill_color;;fill-opacity:1;stroke:&stroke_color;;stroke-width:0.14860222000000001;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"/>
+ <path d="m 155.24,143.33 c -0.0239,0.0902 -0.0702,0.17466 -0.0883,0.26694 -0.006,0.003 0.002,0.022 -0.005,0.0246 -1.7447,0.69266 -2.7968,1.6517 -2.4,2.3257 0.33162,0.56334 1.557,0.76531 3.084,0.61705 0.0246,0.0332 0.0257,0.0722 0.0515,0.10496 0.0362,0.0461 0.078,0.0905 0.11736,0.13625 -0.81174,0.12183 -1.5532,0.17368 -2.1533,0.14669 -1.0704,-0.0482 -1.7999,-0.28559 -2.0556,-0.71999 -0.25571,-0.4344 0.0173,-0.97667 0.73223,-1.5324 0.58365,-0.45372 1.51,-0.94959 2.7169,-1.3697 z" id="path6148" style="fill:&fill_color;;fill-opacity:1;stroke:&stroke_color;;stroke-width:0.14860222000000001;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"/>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/cameramic.py b/cameramic.py
new file mode 100644
index 0000000..1233f80
--- /dev/null
+++ b/cameramic.py
@@ -0,0 +1,122 @@
+# This is where the actual collection of data takes place. For example,
+# it gets video and audio streams from the XO's camera and microphone.
+# Requests to collect data come from the collectdata.py file
+
+import os
+from sugar.activity import activity
+from sugar.datastore import datastore
+import gst
+import time
+import datetime
+import qualitytab
+import storedata
+import subprocess
+# type = mimetypes.types_map['.flac']
+
+# All predefined quality settings have a langth of 5 with quality low to high
+BITRATES = [16000, 20000, 24000, 32000, 48000]
+
+
+class Collect(storedata.Collection):
+ def start(self):
+ print 'qualitytab.tab in cameramic', qualitytab.tab
+ self.bitrate = BITRATES[qualitytab.tab.audio]
+ self.collecting_video, self.collecting_audio = False, False
+ if self.tab.video:
+ self.video()
+ if self.tab.audio:
+ self.audio()
+
+
+ def end(self):
+ if self.tab.video:
+ self.end_video()
+ if self.tab.audio:
+ self.end_audio()
+ if self.tab.image:
+ self.image()
+ else:
+ self.store_data()
+
+ def video(self):
+ VIDEO_GST_PIPE = ['v4l2src', 'queue', 'videorate',
+ 'video/x-raw-yuv,framerate=15/1', 'videoscale',
+ 'video/x-raw-yuv,width=%d,height=%d' % (qualitytab.tab.width, qualitytab.tab.height),
+ 'ffmpegcolorspace', 'theoraenc', 'oggmux']
+ pipe = VIDEO_GST_PIPE + ["filesink location=%s" % (self.video_temp)]
+ self.video_pipe = gst.parse_launch('!'.join(pipe))
+ self.video_pipe.set_state(gst.STATE_PLAYING)
+ print qualitytab.tab.width
+ print qualitytab.tab.height
+
+ def end_video(self):
+ self.video_pipe.set_state(gst.STATE_NULL)
+
+ def audio(self):
+ AUDIO_GST_PIPE = ["alsasrc",
+ "audio/x-raw-int,rate=%d,channels=1,depth=16" %
+ qualitytab.tab.rate, "audioconvert","flacenc"]
+ pipe = AUDIO_GST_PIPE + ["filesink location=%s" % (self.audio_temp)]
+ self.audio_pipe = gst.parse_launch('!'.join(pipe))
+ self.audio_pipe.set_state(gst.STATE_PLAYING)
+ print qualitytab.tab.rate
+
+ def end_audio(self):
+ self.audio_pipe.set_state(gst.STATE_NULL)
+
+ def image(self):
+ VIDEO_GST_PIPE = ['v4l2src', 'ffmpegcolorspace', 'pngenc']
+ pipe=VIDEO_GST_PIPE + ["filesink location=%s" % self.image_temp]
+ self.pipe=gst.parse_launch("!".join(pipe))
+ self.bus=self.pipe.get_bus()
+ self.pipe.set_state(gst.STATE_PLAYING)
+ self.bus.poll(gst.MESSAGE_EOS, -1)
+ self.pipe.set_state(gst.STATE_NULL)
+
+ self.store_data()
+
+
+
+class CollectLapse(storedata.LapseCollection):
+ def start(self):
+ print 'collecting camramic'
+ pipe = ['v4l2src', 'videorate',
+ 'video/x-raw-yuv,width=640,height=480,framerate=1/%d'
+ % self.tab.lapse_speed, 'ffmpegcolorspace', 'jpegenc',
+ 'multipartmux', 'filesink location=%s' % self.lapse_temp]
+ self.lapse_pipe = gst.parse_launch("!".join(pipe))
+ self.lapse_pipe.set_state(gst.STATE_PLAYING)
+
+ def end(self):
+ self.lapse_pipe.set_state(gst.STATE_NULL)
+ subprocess.check_call(["gst-launch", "filesrc",
+ "location=%s" %self.lapse_temp, "!",
+ "multipartdemux", "!", "jpegdec", "!",
+ "theoraenc", "!", "oggmux", "!", "filesink",
+ "location=%s" %self.convert_temp])
+ '''
+ pipe = ['filesrc location=%s' % self.lapse_temp, 'multipartdemux',
+ 'jpegdec', 'theoraenc', 'oggmux', 'filesink location=%s' %
+ self.convert_temp]
+ convert_pipe = gst.parse_launch("!".join(pipe))
+ #bus = convert_pipe.get_bus()
+ convert_pipe.set_state(gst.STATE_PLAYING)
+ #bus.poll(gst.MESSAGE_EOS, -1)
+ time.sleep(15)
+ convert_pipe.set_state(gst.STATE_NULL)
+ '''
+ self.store_data()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/canvas.glade b/canvas.glade
new file mode 100644
index 0000000..28a0362
--- /dev/null
+++ b/canvas.glade
@@ -0,0 +1,174 @@
+<?xml version="1.0"?>
+<glade-interface>
+ <!-- interface-requires gtk+ 2.16 -->
+ <!-- interface-naming-policy project-wide -->
+ <widget class="GtkWindow" id="window1">
+ <child>
+ <widget class="GtkHBox" id="canvas">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkVBox" id="vbox7">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hadjustment">0 0 62 6.2000000000000002 55.800000000000004 62</property>
+ <property name="vadjustment">0 0 628 62.800000000000004 565.20000000000005 628</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <child>
+ <widget class="GtkIconView" id="photoView">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="columns">5</property>
+ <property name="spacing">2</property>
+ <signal name="selection_changed" handler="on_photo_selected"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button4">
+ <property name="label">gtk-delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ <signal name="clicked" handler="on_delete_clicked"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox8">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <widget class="GtkFrame" id="frame12">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment14">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkEntry" id="name_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <property name="shadow_type">out</property>
+ <signal name="focus_out_event" handler="on_name_changed"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Name:&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFrame" id="frame24">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment22">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <child>
+ <widget class="GtkTextView" id="description_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="pixels_below_lines">5</property>
+ <signal name="focus_out_event" handler="on_description_changed"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label30">
+ <property name="visible">True</property>
+ <property name="xalign">0.43000000715255737</property>
+ <property name="label" translatable="yes">&lt;b&gt;Description:&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkImage" id="mainImage">
+ <property name="width_request">640</property>
+ <property name="height_request">480</property>
+ <property name="visible">True</property>
+ <property name="stock">gtk-missing-image</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button5">
+ <property name="label">gtk-media-play</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ <signal name="clicked" handler="on_play_clicked"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
diff --git a/canvas.py b/canvas.py
new file mode 100644
index 0000000..4add4c6
--- /dev/null
+++ b/canvas.py
@@ -0,0 +1,182 @@
+# Provides funcitonality to the canvas (everything below the toolbox)
+# The canvas is where collected data is managed, analized, played
+# back...
+
+import gtk
+import gtk.glade
+from sugar.datastore import datastore
+import interface
+import storedata
+import gst
+import os
+
+GLADE_FILE = "canvas.glade"
+WIDGET_NAME = "canvas"
+
+class Canvas(interface.New):
+ def setup(self):
+ self.player = gst.element_factory_make("playbin", "player")
+ fakesink = gst.element_factory_make("fakesink", "fakesink")
+ self.player.set_property("video-sink", fakesink)
+ bus = self.player.get_bus()
+ bus.add_signal_watch()
+ bus.connect("message", self.on_message)
+ self.PhotoView = self.interface.get_widget("photoView")
+ self.model = gtk.ListStore(str, gtk.gdk.Pixbuf)
+ self.PhotoView.set_model(self.model)
+ self.PhotoView.set_text_column(0)
+ self.PhotoView.set_pixbuf_column(1)
+ self.MainImage = self.interface.get_widget("mainImage")
+ self.selected_name = None
+ self.load_all_data()
+
+ def on_message(self, bus, message):
+ t = message.type
+ if t == gst.MESSAGE_EOS:
+ self.player.set_state(gst.STATE_NULL)
+ elif t == gst.MESSAGE_ERROR:
+ self.player.set_state(gst.STATE_NULL)
+ err, debug = message.parse_error()
+ print "Error: %s" % err, debug
+
+ def get_pixbuf(self, entry_title, main_image=False):
+ print 'makeing new data entry'
+ obj, num = datastore.find({'title':entry_title, 'TimeLapse':'yes',
+ 'mime_type':'image/png'})
+ if num != 0:
+ filepath = obj[0].get_file_path()
+ else:
+ return None
+ if not main_image:
+ pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(filepath, 96, 96)
+ else:
+ pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(filepath, 640, 480)
+ return pixbuf
+
+
+ def new_data_entry(self, entry_title):
+ pixbuf = self.get_pixbuf(entry_title)
+ self.model.insert(0, [entry_title, pixbuf])
+
+ def load_all_data(self):
+ try:
+ titles = datastore.get_unique_values('TimeLapsetitle')
+ except: titles = []
+ for title in titles:
+ self.new_data_entry(title)
+
+
+ def get_description_buffer(self, title):
+ objects, num = datastore.find({'title':title, 'TimeLapse':'yes'})
+ description = objects[0].metadata['description']
+ description_buffer = gtk.TextBuffer(table=None)
+ description_buffer.set_text(description)
+ return description_buffer
+
+ def on_photo_selected(self, widget):
+ self.selected_name = widget.get_cells()[0].get_property("text")
+ print self.selected_name
+ self.interface.get_widget("name_entry").set_text(self.selected_name)
+ pixbuf = self.get_pixbuf(self.selected_name, True)
+ if pixbuf == None:
+ self.MainImage.clear()
+ else:
+ self.MainImage.set_from_pixbuf(pixbuf)
+ description_buffer = self.get_description_buffer(self.selected_name)
+ self.get_widget("description_entry").set_buffer(description_buffer)
+
+ def on_name_changed(self, widget, data):
+ # not finished. Still need to get old_name and new_name and define change_name
+ new_name = self.get_widget('name_entry').get_text()
+ print new_name
+ new_name = storedata.unique_title(new_name)
+ #self.get_widget('name_entry').set_text(new_name)
+ storedata.change_name(self.selected_name, new_name)
+ for obj in self.model:
+ if obj[0] == self.selected_name:
+ obj[0] = new_name
+ self.selected_name = new_name
+
+ def on_description_changed(self, widget, event):
+ textBuffer = widget.get_buffer()
+ start = textBuffer.get_start_iter()
+ end = textBuffer.get_end_iter()
+ description = textBuffer.get_text(start, end)
+ storedata.change_description(self.selected_name, description)
+
+ def on_play_clicked(self, widget):
+ print 'playing audio'
+ if self.selected_name != None:
+ obj, num = datastore.find({'title':self.selected_name,
+ 'TimeLapse':'yes',
+ 'mime_type':'audio/ogg'})
+ print 'num of play objects:', num
+ soundfile = obj[0].get_file_path()
+ if os.path.isfile(os.path.abspath(soundfile)):
+ self.player.set_property("uri", "file://" +
+ os.path.abspath(soundfile))
+ self.player.set_state(gst.STATE_PLAYING)
+
+ def on_delete_clicked(self, widget):
+ if self.selected_name != None:
+ count = 0
+ for obj in self.model:
+ if obj[0] == self.selected_name:
+ iterator = self.model.iter_nth_child(None,count)
+ self.model.remove(iterator)
+ count += 1
+ ds_objects, num_objects = datastore.find({'title': self.selected_name, 'TimeLapse':'yes'})
+
+ for i in xrange (0, num_objects, 1):
+ print 'DELETING ' + ds_objects[i].metadata['title'] + '...'
+ ds_objects[i].destroy()
+ datastore.delete(ds_objects[i].object_id)
+ self.MainImage.clear()
+ self.get_widget('name_entry').set_text('')
+ description_buffer = gtk.TextBuffer(table=None)
+ description_buffer.set_text('')
+ self.get_widget("description_entry").set_buffer(description_buffer)
+
+
+'''
+ def on_save_clicked(self, widget):
+ #name = self.interface.get_widget("name_entry").get_text()
+ textBuffer = self.interface.get_widget("description_entry").get_buffer()
+ start = textBuffer.get_start_iter()
+ end = textBuffer.get_end_iter()
+ description = textBuffer.get_text(start, end)
+ print description
+ if self.selected_name:
+ event = self.events[self.selected_name]
+ for obj in event:
+ new_obj = datastore.create()
+ new_obj.metadata['activity'] = "TimeLapse"
+ new_obj.metadata['title'] = obj.metadata['title']
+ new_obj.metadata['mime_type'] = obj.metadata['mime_type']
+ new_obj.metadata["Description"] = description
+ obj.metadata["Description"] = description
+ new_obj.set_file_path(obj.get_file_path())
+ datastore.delete(obj.object_id)
+ datastore.write(new_obj)
+
+ def on_photo_selected(self, widget):
+ name = widget.get_cells()[0].get_property("text")
+ if name in self.events.keys():
+ event = self.events[name]
+ for obj in event:
+ if obj.metadata['mime_type'] == 'image/png':
+ obj.metadata['keep'] = 1
+ datastore.write(obj)
+ filepath = obj.get_file_path()
+ pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(filepath,
+ 500, 375)
+ self.MainImage.set_from_pixbuf(pixbuf)
+ self.interface.get_widget("name_entry").set_text(name)
+ description_buffer = gtk.TextBuffer(table=None)
+ description_buffer.set_text(obj.metadata['Description'])
+ self.interface.get_widget("description_entry").set_buffer(description_buffer)
+ self.selected_name = name
+'''
+
+
+canvas = Canvas(GLADE_FILE, WIDGET_NAME)
diff --git a/collectdata.py b/collectdata.py
new file mode 100644
index 0000000..70ea3df
--- /dev/null
+++ b/collectdata.py
@@ -0,0 +1,135 @@
+# This controls data collection. It gets data using the cameramic.py
+# file based on the requests and settings of the "tab" files. It does
+# things like starting and stoping data collection.
+
+from sugar.activity import activity
+import cameramic
+import timetab
+import tlactivity
+import gobject
+import time
+import datetime
+timetab = timetab.tab
+
+
+class Timer:
+ def __init__(self, seconds, call):
+ self.canceled = False
+ def timer_call():
+ if not self.canceled:
+ call()
+ return False
+
+ milliseconds = int(seconds * 1000) # change this to use time conversion
+ gobject.timeout_add(milliseconds, timer_call)
+
+ def cancel(self):
+ self.canceled = True
+
+
+class Collection:
+ def __init__(self, tab):
+ self.tab = tab
+ self.start_time = timetab.start
+ self.end_time = timetab.end
+
+ if self.start_time is not None:
+ self.start_time
+ wait_time = self.start_time - datetime.datetime.now()
+ wait_time = wait_time.seconds
+ print 'wait time', wait_time
+ self.starter = Timer(wait_time, self.collect)
+ else:
+ self.collect()
+
+ if self.end_time is not None:
+ wait_time = self.end_time - datetime.datetime.now()
+ wait_time = wait_time.seconds
+ self.ender = Timer(wait_time, self.end)
+
+ def end_now(self):
+ self.starter.cancel()
+ self.end()
+
+
+class Single(Collection):
+ def collect(self):
+ video, audio, image = '', '', ''
+ if self.tab.video:
+ video = 'Video '
+ if self.tab.audio:
+ audio = 'Audeo '
+ if self.tab.image:
+ image = 'Image '
+ self.tab.alert.props.title='Single Collection'
+ msg = 'Start Time: ' + str(self.start_time) + '; End Time: ' + \
+ str(self.end_time) + "; Duration: " + str(self.tab.duration) + \
+ '; Collecting: %s%s%s' %(video, audio, image)
+ self.tab.alert.props.msg = msg
+ self.tab.alert.show()
+ self.collection = cameramic.Collect(self.tab)
+ self.timer = Timer(self.tab.duration, self.end)
+ self.tab.set_tab_sensitives(False)
+
+ def end(self):
+ self.timer.cancel()
+ self.collection.end()
+ self.tab.set_tab_sensitives(True)
+ self.tab.alert.hide()
+ self.tab.collection = None
+
+class Incramental(Collection):
+ def single_collect(self):
+ self.collection = cameramic.Collect(self.tab)
+ self.stimer = Timer(self.tab.duration, self.collection.end)
+
+ def collect(self):
+ video, audio, image = '', '', ''
+ if self.tab.video:
+ video = 'Video '
+ if self.tab.audio:
+ audio = 'Audeo '
+ if self.tab.image:
+ image = 'Image '
+ self.tab.alert.props.title='Incramental Collection'
+ msg = 'Start Time: ' + str(self.start_time) + '; End Time: ' + \
+ str(self.end_time) + "; Duration: " + str(self.tab.duration) + \
+ '; Frequency:' + str(self.tab.frequency) + '; Collecting: %s%s%s' % \
+ (video, audio, image)
+ self.tab.alert.props.msg = msg
+ self.tab.alert.show()
+ self.started_time = time.time()
+ self.count = 1
+ self.incrament()
+
+ def incrament(self):
+ self.single_collect()
+ start_time = self.started_time + self.tab.frequency * self.count
+ wait_time = start_time - time.time()
+ print "wait time:", wait_time
+ self.itimer = Timer(wait_time, self.incrament)
+ self.count += 1
+
+ def end(self):
+ self.itimer.cancel()
+ self.collection.end()
+ self.tab.alert.hide()
+ self.tab.collection = None
+
+class Lapse(Collection):
+ def collect(self):
+ self.tab.alert.props.title='Time Lapse Collection'
+ msg = 'Start Time: ' + str(self.start_time) + '; End Time: ' + \
+ str(self.end_time) +' Collecting one frame every %s seconds.' % (
+ self.tab.lapse_speed)
+ self.tab.alert.props.msg = msg
+ self.tab.alert.show()
+ print 'collecting collectdata'
+ self.collection = cameramic.CollectLapse(self.tab)
+ #self.timer = Timer(30, self.end)
+
+ def end(self):
+ print "lapse collection ending"
+ self.collection.end()
+ self.tab.alert.hide()
+ self.tab.collection = None
diff --git a/filetools.py b/filetools.py
new file mode 100644
index 0000000..f5a41ae
--- /dev/null
+++ b/filetools.py
@@ -0,0 +1,3 @@
+# Here functionality is provided for all of the buttons in the lower
+# left corner of the canvas. These buttons deal with managing data
+# after it has been collected. Copying data, deleteing data...
diff --git a/incramentaltab.py b/incramentaltab.py
new file mode 100644
index 0000000..7f16fb5
--- /dev/null
+++ b/incramentaltab.py
@@ -0,0 +1,46 @@
+# This maneges the interface of and provides functionality for the
+# "Incramental Collection" tab.
+
+import interface
+import collectdata
+
+TAB_NAME = "Incremental Collection"
+WIDGET_NAME = "incramental_collection"
+
+
+class Tab(interface.NewTab):
+ def make(self):
+ self.duration = 5
+ self.frequency = 15
+ self.jurnal_name = ''
+
+ def on_begin_pushed(self, widget):
+ self.collection = collectdata.Incramental(self)
+
+ def on_name_changed(self, widget):
+ self.jurnal_name = widget.get_text()
+
+ def on_video_toggled(self, widget):
+ self.video = widget.get_active()
+
+ def on_audio_toggled(self, widget):
+ self.audio = widget.get_active()
+
+ def on_image_toggled(self, widget):
+ self.image = widget.get_active()
+
+ def on_duration_changed(self, widget):
+ self.duration = widget.get_value()
+
+ def on_frequency_min_changed(self, widget):
+ self.frequency = widget.get_value() * 60
+ hours = self.interface.get_widget('frequency_hour').get_value()
+ self.frequency += hours * 3600
+
+ def on_frequency_hour_changed(self, widget):
+ self.frequency = widget.get_value() * 3600
+ minutes = self.interface.get_widget('frequency_min').get_value()
+ self.frequency += minutes * 60
+
+
+tab = Tab(interface.GLADE_TABS, WIDGET_NAME, TAB_NAME)
diff --git a/interface.py b/interface.py
new file mode 100644
index 0000000..819f322
--- /dev/null
+++ b/interface.py
@@ -0,0 +1,49 @@
+# This provides funcionality that is common to all or many of the tabs
+# and the canvas.
+
+import gtk
+import gtk.glade
+import tlactivity
+
+
+GLADE_TABS = "tabs.glade"
+GLADE_FILE = "canvas.glade"
+
+
+class New:
+ """Initializes the interface for a tab or canvas."""
+ def __init__(self, glade_file, widget_name, tab_name=None):
+ self.interface = gtk.glade.XML(glade_file, widget_name)
+ self.get_widget = self.interface.get_widget
+ self.interface.signal_autoconnect(self)
+ self.widget = self.interface.get_widget(widget_name)
+ if tab_name is not None:
+ self.tab_name = tab_name
+ self.setup()
+
+
+class NewTab(New):
+ def setup(self):
+ self.store_name = None
+ self.duration, self.frequency, self.lapse_speed = None, None, None
+ self.video, self.audio, self.image = True, True, True
+ self.make()
+ self.collection = None
+
+ def set_tab_sensitives(self, sensitive=True):
+ tabs = tlactivity.tabs
+ if sensitive:
+ for tab in tabs:
+ tab.widget.set_sensitive(True)
+ else:
+ for tab in tabs:
+ tab.widget.set_sensitive(False)
+
+ def set_alert(self, alert):
+ self.alert = alert
+
+ def stop(self, alert, response_id):
+ if response_id is gtk.RESPONSE_CANCEL:
+ if self.collection != None:
+ self.collection.end()
+
diff --git a/journal.py b/journal.py
new file mode 100644
index 0000000..8cd52e2
--- /dev/null
+++ b/journal.py
@@ -0,0 +1 @@
+# This controls interactions with the Sugar Journal
diff --git a/lapsetab.py b/lapsetab.py
new file mode 100644
index 0000000..ff13e5e
--- /dev/null
+++ b/lapsetab.py
@@ -0,0 +1,35 @@
+# This maneges the interface of and provides functionality for the
+# "Time-Lapse Collection" tab.
+
+import interface
+import collectdata
+
+TAB_NAME = "Time Lapse Collection"
+WIDGET_NAME = "time_lapse_collection"
+
+
+class Tab(interface.NewTab):
+ def make(self):
+ self.lapse_speed = 30
+ self.jurnal_name = ''
+
+ def on_begin_collecting(self, widget):
+ print 'collecting tltab'
+ self.collection = collectdata.Lapse(self)
+
+ def on_name_changed(self, widget):
+ # this along with others could be moved to NewTab class
+ self.jurnal_name = widget.get_text()
+
+ def on_speed_changed(self, widget):
+ hours = self.get_widget('hour_speed').get_value()
+ mins = self.get_widget('min_speed').get_value()
+ secs = self.get_widget('sec_speed').get_value()
+ # I should do this a nicer non math way
+ self.lapse_speed = int(hours * 3600 + mins * 60 + secs)
+ print "lapse speed changed: ", self.lapse_speed
+
+
+
+
+tab = Tab(interface.GLADE_TABS, WIDGET_NAME, TAB_NAME)
diff --git a/playback.py b/playback.py
new file mode 100644
index 0000000..8153a69
--- /dev/null
+++ b/playback.py
@@ -0,0 +1,2 @@
+# Provides funcitonality to play back stored data. Requests to play
+# data come from the play buttons in the canvas.
diff --git a/qualitytab.py b/qualitytab.py
new file mode 100644
index 0000000..a2790f9
--- /dev/null
+++ b/qualitytab.py
@@ -0,0 +1,55 @@
+# This maneges the interface of and provides functionality for the
+# "Quality" tab.
+
+import interface
+import cameramic
+
+TAB_NAME = "Quality"
+WIDGET_NAME = "data_quality"
+
+
+class Tab(interface.NewTab):
+ def make(self):
+ # change these to glade callbacks later.
+ self.video, self.audio, self.image, self.lapse, self.width, self.height, self.rate = 4, 4, 4, 4, 100, 75, 12000
+
+ def on_video_changed(self, widget):
+ self.video = widget.get_value()
+ print "video quality", self.video
+ if self.video < 1.50:
+ self.width = 100
+ self.height = 75
+ if self.video >= 1.50 and self.video < 2.50:
+ self.width = 200
+ self.height = 150
+ print "optimal"
+ if self.video >= 2.50 and self.video < 3.50:
+ self.width = 256
+ self.height = 192
+ if self.video >= 3.50 and self.video < 4.50:
+ self.width = 320
+ self.height = 240
+ if self.video >= 4.50 and self.video < 5.50:
+ self.width = 400
+ self.width = 300
+ if self.video >= 5.50 and self.video <= 6.00:
+ self.width = 512
+ self.height = 384
+
+ def on_audio_changed(self, widget):
+ self.audio = widget.get_value()
+ print "audio quality", self.audio
+ if self.audio < 1.50:
+ self.rate = 12000
+ if self.audio >= 1.50 and self.video < 2.50:
+ self.rate = 18000
+ if self.audio >= 2.50 and self.video < 3.50:
+ self.rate = 24000
+ if self.audio >= 3.50 and self.video < 4.50:
+ self.rate = 30000
+ if self.audio >= 4.50 and self.video < 5.50:
+ self.rate = 36000
+ if self.audio >= 5.50 and self.video <= 6.00:
+ self.rate = 48000
+
+tab = Tab(interface.GLADE_TABS, WIDGET_NAME, TAB_NAME)
diff --git a/setup.py b/setup.py
new file mode 100755
index 0000000..1a961a4
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2006, Red Hat, Inc.
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from sugar.activity import bundlebuilder
+bundlebuilder.start()
diff --git a/singletab.py b/singletab.py
new file mode 100644
index 0000000..e0d20d6
--- /dev/null
+++ b/singletab.py
@@ -0,0 +1,41 @@
+# This maneges the interface of and provides functionality for the
+# "Single Collection" tab.
+
+import interface
+import collectdata
+
+TAB_NAME = "Single Collection"
+WIDGET_NAME = "single_collection"
+
+
+class Tab(interface.NewTab):
+ def make(self):
+ self.duration = 15
+ self.jurnal_name = self.interface.get_widget('single_name').get_text()
+ def set_canvas(self, canvas):
+ self.canvas = canvas
+
+
+ def on_collect_pushed(self, widget):
+ print "collect pushed"
+ self.collection = collectdata.Single(self)
+ #self.canvas.addEvent()
+
+ def on_name_changed(self, widget):
+ self.jurnal_name = widget.get_text()
+ print "jurnal name:", self.jurnal_name
+
+ def on_video_toggled(self, widget):
+ self.video = widget.get_active()
+
+ def on_audio_toggled(self, widget):
+ self.audio = widget.get_active()
+
+ def on_image_toggled(self, widget):
+ self.image = widget.get_active()
+
+ def on_duration_changed(self, widget):
+ self.duration = int(widget.get_value())
+
+
+tab = Tab(interface.GLADE_TABS, WIDGET_NAME, TAB_NAME)
diff --git a/storedata.py b/storedata.py
new file mode 100644
index 0000000..d3eb14e
--- /dev/null
+++ b/storedata.py
@@ -0,0 +1,79 @@
+# Deals with storage of data and metadata.
+from sugar.datastore import datastore
+from canvas import canvas
+import time
+
+def unique_title(name):
+ if name == '':
+ name = 'Untitled'
+ objs, num_objects = datastore.find({'title':name, 'TimeLapse':'yes'})
+ if num_objects == 0:
+ return name
+ i = 1
+ while num_objects != 0:
+ i += 1
+ objs, num_objects = datastore.find({'title':name + str(i),
+ 'TimeLapse':'yes'})
+ return name + str(i)
+
+def change_description(title, new_discription):
+ dsobjects, num = datastore.find({'title':title, 'TimeLapse':'yes'})
+ for dsobject in dsobjects:
+ dsobject.metadata['description'] = new_discription
+ datastore.write(dsobject)
+ dsobject.destroy()
+
+def change_name(old_name, new_name):
+ dsobjects, num = datastore.find({'title':old_name, 'TimeLapse':'yes'})
+ for dsobject in dsobjects:
+ dsobject.metadata['title'] = new_name
+ dsobject.metadata['TimeLapsetitle'] = new_name
+ datastore.write(dsobject)
+ dsobject.destroy()
+
+
+def store_data(entry_title, mime_type, file_path):
+ file_dsobject = datastore.create()
+ file_dsobject.metadata['TimeLapse'] = 'yes'
+ file_dsobject.metadata['TimeLapsetitle'] = entry_title
+ file_dsobject.metadata['title'] = entry_title
+ file_dsobject.metadata['mime_type'] = mime_type
+ file_dsobject.metadata['description'] = ''
+ file_dsobject.set_file_path(file_path)
+ datastore.write(file_dsobject)
+ file_dsobject.destroy()
+
+class Collection:
+ def __init__(self, tab):
+ self.tab = tab
+ self.entry_title = unique_title(tab.jurnal_name)
+ if tab.video:
+ self.video_temp = "/tmp/tmp" + str(time.time()) + '.ogv'
+ if tab.audio:
+ self.audio_temp = "/tmp/tmp" + str(time.time()) + '.flac'
+ if tab.image:
+ self.image_temp = "/tmp/tmp" + str(time.time()) + '.png'
+ self.start()
+
+ def store_data(self):
+ if self.tab.video:
+ store_data(self.entry_title, 'video/ogg', self.video_temp)
+ if self.tab.audio:
+ store_data(self.entry_title, 'audio/ogg', self.audio_temp)
+ if self.tab.image:
+ store_data(self.entry_title, 'image/png', self.image_temp)
+ canvas.new_data_entry(self.entry_title)
+
+
+
+class LapseCollection:
+ def __init__(self, tab):
+ self.tab = tab
+ self.entry_title = unique_title(tab.jurnal_name)
+ self.lapse_temp = "/tmp/tmp" + str(time.time()) + '.mjpeg'
+ self.convert_temp = "/tmp/tmp" + str(time.time()) + '.ogg'
+ self.start()
+
+ def store_data(self):
+ store_data(self.entry_title, 'video/ogg', self.convert_temp)
+ canvas.new_data_entry(self.entry_title)
diff --git a/tabs.glade b/tabs.glade
new file mode 100644
index 0000000..1b25bb3
--- /dev/null
+++ b/tabs.glade
@@ -0,0 +1,1344 @@
+<?xml version="1.0"?>
+<glade-interface>
+ <!-- interface-requires gtk+ 2.16 -->
+ <!-- interface-naming-policy project-wide -->
+ <widget class="GtkWindow" id="window1">
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkToolbar" id="single_collection">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkToolItem" id="toolbutton1">
+ <property name="visible">True</property>
+ <property name="is_important">True</property>
+ <child>
+ <widget class="GtkButton" id="button8">
+ <property name="label" translatable="yes">Collect</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <signal name="clicked" handler="on_collect_pushed"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolItem" id="toolbutton2">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkFrame" id="frame13">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment16">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkEntry" id="single_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <signal name="changed" handler="on_name_changed"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Name:&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSeparatorToolItem" id="toolbutton3">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolItem" id="toolbutton4">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkHBox" id="hbox6">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkCheckButton" id="now_video_checkbox1">
+ <property name="label" translatable="yes">Video</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_video_toggled"/>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="now_audio_checkbox1">
+ <property name="label" translatable="yes">Audio</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_audio_toggled"/>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="now_image_checkbox1">
+ <property name="label" translatable="yes">Image</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_image_toggled"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSeparatorToolItem" id="toolbutton5">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolItem" id="toolbutton6">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkFrame" id="frame16">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment17">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkSpinButton" id="spinbutton21">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <property name="adjustment">15 1 9999 1 10 10</property>
+ <signal name="value_changed" handler="on_duration_changed"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Duration&lt;/b&gt; (Sec)</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolbar" id="incramental_collection">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkToolItem" id="toolbutton7">
+ <property name="visible">True</property>
+ <property name="is_important">True</property>
+ <child>
+ <widget class="GtkButton" id="button9">
+ <property name="label" translatable="yes">Begin
+Collecting</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <signal name="clicked" handler="on_begin_pushed"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolItem" id="toolbutton8">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkFrame" id="frame17">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment24">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkEntry" id="incremental_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <signal name="changed" handler="on_name_changed"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Name:&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSeparatorToolItem" id="toolbutton9">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolItem" id="toolbutton10">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkHBox" id="hbox10">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkVBox" id="vbox4">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkCheckButton" id="now_video_checkbox2">
+ <property name="label" translatable="yes">Video</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_video_toggled"/>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="now_audio_checkbox2">
+ <property name="label" translatable="yes">Audio</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_audio_toggled"/>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="now_image_checkbox2">
+ <property name="label" translatable="yes">Image</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_image_toggled"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSeparatorToolItem" id="toolbutton11">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolItem" id="toolbutton12">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkFrame" id="frame18">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment25">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkSpinButton" id="spinbutton20">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <property name="xalign">0.10000000149011612</property>
+ <property name="adjustment">5 1 9999 1 10 10</property>
+ <signal name="value_changed" handler="on_duration_changed"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label13">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Duration&lt;/b&gt; (Sec)</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSeparatorToolItem" id="toolbutton13">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolItem" id="toolbutton14">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkFrame" id="frame19">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment26">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkHBox" id="hbox3">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkSpinButton" id="frequency_hour">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <property name="adjustment">1 0 100 1 10 10</property>
+ <signal name="value_changed" handler="on_frequency_hour_changed"/>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label38">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">:</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="frequency_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <property name="adjustment">0 0 59 1 10 10</property>
+ <signal name="value_changed" handler="on_frequency_min_changed"/>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label14">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Frequency&lt;/b&gt; (Hour:Min)</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolbar" id="time_lapse_collection">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkToolItem" id="toolbutton15">
+ <property name="visible">True</property>
+ <property name="is_important">True</property>
+ <child>
+ <widget class="GtkButton" id="button10">
+ <property name="label" translatable="yes">Begin
+Collecting</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <signal name="clicked" handler="on_begin_collecting"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolItem" id="toolbutton16">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkFrame" id="frame27">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment28">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkEntry" id="lapse_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <signal name="changed" handler="on_name_changed"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label45">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Name:&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSeparatorToolItem" id="toolbutton17">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolItem" id="toolbutton19">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkFrame" id="frame26">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment27">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkHBox" id="hbox4">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkSpinButton" id="hour_speed">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <property name="adjustment">0 0 999 1 10 10</property>
+ <signal name="value_changed" handler="on_speed_changed"/>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label39">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">:</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="min_speed">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <property name="adjustment">0 0 59 1 10 10</property>
+ <signal name="value_changed" handler="on_speed_changed"/>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label40">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">:</property>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="sec_speed">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <property name="adjustment">30 0 59 1 10 10</property>
+ <signal name="value_changed" handler="on_speed_changed"/>
+ </widget>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label20">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Collection Speed&lt;/b&gt; (Hour:Min:Sec)</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolbar" id="start_end_time">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkToolItem" id="toolbutton18">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="width_request">350</property>
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkAspectFrame" id="aspectframe1">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <widget class="GtkVBox" id="vbox13">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkToggleButton" id="start_time_toggle">
+ <property name="label" translatable="yes">Start Time:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <signal name="toggled" handler="on_start_toggled"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="no_start_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;No start time set.&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="padding">10</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToggleButton" id="start_adjustment_toggle">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <signal name="toggled" handler="on_change_start_toggled"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">5</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="start_time_adjustment">
+ <signal name="focus_out_event" handler="on_start_ajustment_unfocus"/>
+ <child>
+ <widget class="GtkHBox" id="hbox7">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkVBox" id="vbox5">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Hour:</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox9">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkSpinButton" id="start_hour">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <property name="adjustment">0 0 23 1 10 10</property>
+ <signal name="value_changed" handler="on_start_time_changed"/>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label15">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;:&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="padding">2</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox7">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Min:</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox12">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkSpinButton" id="start_min">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <property name="adjustment">0 0 59 1 10 10</property>
+ <signal name="value_changed" handler="on_start_time_changed"/>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label16">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;:&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="padding">2</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox8">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Sec:</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="start_sec">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <property name="adjustment">0 0 59 10 10 10</property>
+ <signal name="value_changed" handler="on_start_time_changed"/>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCalendar" id="start_cal">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="year">2010</property>
+ <property name="day">9</property>
+ <signal name="day_selected" handler="on_start_time_changed"/>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSeparatorToolItem" id="toolbutton20">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolItem" id="toolbutton21">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkVBox" id="vbox6">
+ <property name="width_request">350</property>
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkAspectFrame" id="aspectframe3">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <property name="yalign">0</property>
+ <child>
+ <widget class="GtkVBox" id="vbox14">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkToggleButton" id="end_time_toggle">
+ <property name="label" translatable="yes">End Time:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <signal name="toggled" handler="on_end_toggled"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox16">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="no_end_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;No end time set.&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="padding">10</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToggleButton" id="end_adjustment_toggle">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <signal name="toggled" handler="on_change_end_toggled"/>
+ </widget>
+ <packing>
+ <property name="padding">5</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="end_time_adjustment">
+ <child>
+ <widget class="GtkHBox" id="hbox13">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkVBox" id="vbox10">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label17">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Hour:</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox14">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkSpinButton" id="end_hour">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <property name="adjustment">0 0 23 1 10 10</property>
+ <signal name="value_changed" handler="on_end_time_changed"/>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label18">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;:&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="padding">2</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox11">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label19">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Min:</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox15">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkSpinButton" id="end_min">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <property name="adjustment">0 0 59 1 10 10</property>
+ <signal name="value_changed" handler="on_end_time_changed"/>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label21">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;:&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="padding">2</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox12">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label22">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Sec:</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="end_sec">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <property name="adjustment">0 0 59 10 10 10</property>
+ <signal name="value_changed" handler="on_end_time_changed"/>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCalendar" id="end_cal">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="year">2010</property>
+ <property name="day">9</property>
+ <signal name="day_selected" handler="on_end_time_changed"/>
+ <signal name="focus_in_event" handler="on_date_focus"/>
+ <signal name="focus_out_event" handler="on_date_unfocus"/>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSeparatorToolItem" id="toolbutton26">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolItem" id="toolbutton28">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkAspectFrame" id="aspectframe2">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <property name="xalign">1</property>
+ <property name="yalign">0</property>
+ <child>
+ <widget class="GtkVBox" id="vbox9">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label23">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Current Time:&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="time">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="yalign">0</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolbar" id="data_quality">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkToolItem" id="toolbutton22">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkFrame" id="frame34">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment35">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Low</property>
+ </widget>
+ <packing>
+ <property name="padding">5</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHScale" id="hscale1">
+ <property name="width_request">200</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">2 0 6 1 1 0</property>
+ <property name="draw_value">False</property>
+ <signal name="value_changed" handler="on_video_changed"/>
+ <signal name="move_slider" handler="on_video_changed"/>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">High</property>
+ </widget>
+ <packing>
+ <property name="padding">5</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label57">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Video Quality&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSeparatorToolItem" id="toolbutton23">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolItem" id="toolbutton24">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkFrame" id="frame35">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment36">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkHBox" id="hbox8">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Low</property>
+ </widget>
+ <packing>
+ <property name="padding">5</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHScale" id="hscale2">
+ <property name="width_request">200</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="update_policy">discontinuous</property>
+ <property name="adjustment">6 0 6 1 1 0</property>
+ <property name="draw_value">False</property>
+ <signal name="move_slider" handler="on_audio_changed"/>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">High</property>
+ </widget>
+ <packing>
+ <property name="padding">5</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label58">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Audio Quality&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
diff --git a/timetab.py b/timetab.py
new file mode 100644
index 0000000..6a6b717
--- /dev/null
+++ b/timetab.py
@@ -0,0 +1,126 @@
+# This maneges the interface of and provides functionality for the
+# "Start/End Time" tab.
+
+'''
+Fixing this file... redundecy needs to be eleminated readablility needs to be improved
+Ideas:
+1. use a class that start and end implament
+2. use a class for start and end that stores the widgets
+3. create a class that does everything start and end time need to do and take the start/end out of it
+'''
+
+import interface
+import datetime
+import gobject
+
+TAB_NAME = "Start/End Time"
+WIDGET_NAME = "start_end_time"
+
+
+class Tab(interface.NewTab):
+
+ def make(self):
+
+ self.start_calendar = self.get_widget('start_cal')
+ self.end_calendar = self.get_widget('end_cal')
+ self.start_hour = self.get_widget('start_hour')
+ self.end_hour = self.get_widget('end_hour')
+ self.start_min = self.get_widget('start_min')
+ self.end_min = self.get_widget('end_min')
+ self.start_sec = self.get_widget('start_sec')
+ self.end_sec = self.get_widget('end_sec')
+ self.start_adjustment_frame = self.get_widget('start_time_adjustment')
+ self.end_adjustment_frame = self.get_widget('end_time_adjustment')
+ self.no_start_time_text = self.get_widget('no_start_label')
+ self.no_end_time_text = self.get_widget('no_end_label')
+ self.start_time_toggle = self.get_widget('start_time_toggle')
+ self.end_time_toggle = self.get_widget('end_time_toggle')
+ self.start_adjuster_toggle = self.get_widget('start_adjustment_toggle')
+ self.end_adjuster_toggle = self.get_widget('end_adjustment_toggle')
+
+ time = datetime.datetime.now()
+ if time.hour == 23:
+ hour = 0
+ # I know, day could be pushed over to 32, causing this program to
+ # not function in the last hour of the last day of every month.
+ # I need to fix this.
+ day = time.day + 1
+ else:
+ day = time.day
+ hour = time.hour + 1
+ self.end_calendar.select_month(time.month - 1, time.year)
+ self.end_calendar.select_day(day + 1)
+ self.end_hour.set_value(hour)
+ self.start_hour.set_value(hour)
+ self.start_calendar.select_month(time.month - 1, time.year)
+ self.start_calendar.select_day(day)
+ self.set_start_time()
+ self.set_end_time()
+ gobject.timeout_add(1000, self.update_time)
+
+ def update_time(self):
+ self.current_time = datetime.datetime.now().ctime()
+ self.get_widget('time').set_text(self.current_time)
+ return True
+
+ def set_time(self, calendar, hour, minute, second, adjuster_toggle, time_toggle):
+ print 'setting end time'
+ date = calendar.get_date()
+ time = datetime.datetime(date[0], date[1] + 1, date[2],
+ int(hour.get_value()),
+ int(minute.get_value()),
+ int(second.get_value()))
+ adjuster_toggle.set_label(time.ctime())
+ if not time_toggle.get_active():
+ time = None
+ return time
+
+ def set_start_time(self):
+ self.start = self.set_time(self.start_calendar, self.start_hour,
+ self.start_min, self.start_sec,
+ self.start_adjuster_toggle,
+ self.start_time_toggle)
+
+ def set_end_time(self):
+ self.end = self.set_time(self.end_calendar, self.end_hour,
+ self.end_min, self.end_sec,
+ self.end_adjuster_toggle,
+ self.end_time_toggle)
+
+ def time_toggled(self, widget, adjuster_toggle, no_time_text):
+ if widget.get_active():
+ adjuster_toggle.show()
+ no_time_text.hide()
+ else:
+ adjuster_toggle.hide()
+ no_time_text.show()
+ adjuster_toggle.set_active(False)
+
+ def change_time_toggled(self, widget, adjustment_frame):
+ if widget.get_active():
+ adjustment_frame.show()
+ else:
+ adjustment_frame.hide()
+
+ def on_start_time_changed(self, widget):
+ self.set_start_time()
+
+ def on_end_time_changed(self, widget):
+ self.set_end_time()
+
+ def on_start_toggled(self, widget):
+ self.time_toggled(widget, self.start_adjuster_toggle,
+ self.no_start_time_text)
+
+ def on_end_toggled(self, widget):
+ self.time_toggled(widget, self.end_adjuster_toggle,
+ self.no_end_time_text)
+
+ def on_change_start_toggled(self, widget):
+ self.change_time_toggled(widget, self.start_adjustment_frame)
+
+ def on_change_end_toggled(self, widget):
+ self.change_time_toggled(widget, self.end_adjustment_frame)
+
+
+tab = Tab(interface.GLADE_TABS, WIDGET_NAME, TAB_NAME)
diff --git a/tlactivity.py b/tlactivity.py
new file mode 100644
index 0000000..a2ac804
--- /dev/null
+++ b/tlactivity.py
@@ -0,0 +1,55 @@
+# This is where the TimeLapse activity starts up. The actual TimeLapse
+# window gets created here, among other things.
+
+from threading import Timer
+from sugar.activity import activity
+import singletab, incramentaltab, lapsetab, timetab, qualitytab
+import playback
+import canvas
+from sugar.graphics.alert import Alert
+from sugar.graphics.icon import Icon
+import gtk
+
+
+canvas = canvas.canvas
+singletab = singletab.tab
+singletab.set_canvas(canvas)
+incramentaltab = incramentaltab.tab
+lapsetab = lapsetab.tab
+timetab = timetab.tab
+qualitytab = qualitytab.tab
+print 'qualitytab.tab in tlactivity:', qualitytab
+tabs = [singletab, incramentaltab, lapsetab, timetab, qualitytab]
+
+
+class TimeLapseActivity(activity.Activity):
+ def __init__(self, handle):
+ activity.Activity.__init__(self, handle)
+ self.set_canvas(canvas.widget)
+ toolbox = activity.ActivityToolbox(self)
+ self.set_toolbox(toolbox)
+ toolbox.show()
+
+ alert = Alert()
+ # Populate the title and text body of the alert.
+ alert.props.title='Current Recording'
+ alert.props.msg = 'recording information goes here'
+ stop_icon = Icon(icon_name='dialog-cancel')
+ stop_icon.set_pixel_size(50)
+ alert.add_button(gtk.RESPONSE_CANCEL, 'End', stop_icon)
+ stop_icon.show()
+ alert.connect('response', singletab.stop)
+ alert.connect('response', incramentaltab.stop)
+ alert.connect('response', lapsetab.stop)
+ # Call the add_alert() method (inherited via the sugar.graphics.Window superclass of Activity)
+ # to add this alert to the activity window.
+ self.add_alert(alert)
+ alert.hide()
+
+ for tab in tabs:
+ toolbox.add_toolbar(tab.tab_name, tab.widget)
+ tab.set_alert(alert)
+
+
+
+