diff options
author | olpc <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) |
commit | b5c04ff29befec16f77f4674a95949bc0a36129f (patch) | |
tree | ba5d747749b7514da6bc64f72c280895104b1bf3 |
-rw-r--r-- | MANIFEST | 19 | ||||
-rw-r--r-- | activity/activity.info | 8 | ||||
-rw-r--r-- | activity/bee.svg | 39 | ||||
-rw-r--r-- | cameramic.py | 122 | ||||
-rw-r--r-- | canvas.glade | 174 | ||||
-rw-r--r-- | canvas.py | 182 | ||||
-rw-r--r-- | collectdata.py | 135 | ||||
-rw-r--r-- | filetools.py | 3 | ||||
-rw-r--r-- | incramentaltab.py | 46 | ||||
-rw-r--r-- | interface.py | 49 | ||||
-rw-r--r-- | journal.py | 1 | ||||
-rw-r--r-- | lapsetab.py | 35 | ||||
-rw-r--r-- | playback.py | 2 | ||||
-rw-r--r-- | qualitytab.py | 55 | ||||
-rwxr-xr-x | setup.py | 20 | ||||
-rw-r--r-- | singletab.py | 41 | ||||
-rw-r--r-- | storedata.py | 79 | ||||
-rw-r--r-- | tabs.glade | 1344 | ||||
-rw-r--r-- | timetab.py | 126 | ||||
-rw-r--r-- | tlactivity.py | 55 |
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">●</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"><b>Name:</b></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"><b>Description:</b></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">●</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"><b>Name:</b></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">●</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"><b>Duration</b> (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">●</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"><b>Name:</b></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">●</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"><b>Duration</b> (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">●</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">●</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"><b>Frequency</b> (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">●</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"><b>Name:</b></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">●</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">●</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">●</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"><b>Collection Speed</b> (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"><b>No start time set.</b></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">●</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"><b>:</b></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">●</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"><b>:</b></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">●</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"><b>No end time set.</b></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">●</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"><b>:</b></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">●</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"><b>:</b></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">●</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"><b>Current Time:</b></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"><b>Video Quality</b></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"><b>Audio Quality</b></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) + + + + |