From 7564597666a078d00ec7072d2abe2440e224e9c0 Mon Sep 17 00:00:00 2001 From: Aleksey Lim Date: Fri, 17 Apr 2009 14:20:39 +0000 Subject: Replate tabs by spaces --- diff --git a/button.py b/button.py index 460139d..14b9700 100644 --- a/button.py +++ b/button.py @@ -12,97 +12,97 @@ from constants import Constants import utils class RecdButton(TrayButton, gobject.GObject): - def __init__(self, ui, recd): - TrayButton.__init__(self) - self.ui = ui - self.recd = recd + def __init__(self, ui, recd): + TrayButton.__init__(self) + self.ui = ui + self.recd = recd - img = self.getImg( ) - self.set_icon_widget( img ) + img = self.getImg( ) + self.set_icon_widget( img ) - self.ACTIVATE_COPY_ID = 0 - self.ACTIVATE_REMOVE_ID = 0 - self.setup_rollover_options( recd.title ) + self.ACTIVATE_COPY_ID = 0 + self.ACTIVATE_REMOVE_ID = 0 + self.setup_rollover_options( recd.title ) - def getImg( self ): - img = gtk.Image() - ipb = self.recd.getThumbPixbuf() - xoff = 8 - yoff = 8 - pb = None - if (self.recd.type == Constants.TYPE_PHOTO): - if (self.recd.buddy): - thumbPhotoSvg = utils.loadSvg(Constants.thumbPhotoSvgData, self.recd.colorStroke.hex, self.recd.colorFill.hex) - pb = thumbPhotoSvg.get_pixbuf() - else: - pb = Constants.thumbPhotoSvg.get_pixbuf() + def getImg( self ): + img = gtk.Image() + ipb = self.recd.getThumbPixbuf() + xoff = 8 + yoff = 8 + pb = None + if (self.recd.type == Constants.TYPE_PHOTO): + if (self.recd.buddy): + thumbPhotoSvg = utils.loadSvg(Constants.thumbPhotoSvgData, self.recd.colorStroke.hex, self.recd.colorFill.hex) + pb = thumbPhotoSvg.get_pixbuf() + else: + pb = Constants.thumbPhotoSvg.get_pixbuf() - elif (self.recd.type == Constants.TYPE_VIDEO): - if (self.recd.buddy): - thumbVideoSvg = utils.loadSvg(Constants.thumbVideoSvgData, self.recd.colorStroke.hex, self.recd.colorFill.hex) - pb = thumbVideoSvg.get_pixbuf() - else: - pb = Constants.thumbVideoSvg.get_pixbuf() + elif (self.recd.type == Constants.TYPE_VIDEO): + if (self.recd.buddy): + thumbVideoSvg = utils.loadSvg(Constants.thumbVideoSvgData, self.recd.colorStroke.hex, self.recd.colorFill.hex) + pb = thumbVideoSvg.get_pixbuf() + else: + pb = Constants.thumbVideoSvg.get_pixbuf() - elif (self.recd.type == Constants.TYPE_AUDIO): - if (self.recd.buddy): - thumbAudioSvg = utils.loadSvg(Constants.thumbAudioSvgData, self.recd.colorStroke.hex, self.recd.colorFill.hex) - pb = thumbAudioSvg.get_pixbuf() - else: - pb = Constants.thumbAudioSvg.get_pixbuf() + elif (self.recd.type == Constants.TYPE_AUDIO): + if (self.recd.buddy): + thumbAudioSvg = utils.loadSvg(Constants.thumbAudioSvgData, self.recd.colorStroke.hex, self.recd.colorFill.hex) + pb = thumbAudioSvg.get_pixbuf() + else: + pb = Constants.thumbAudioSvg.get_pixbuf() - img.set_from_pixbuf(pb) - img.show() - ipb.composite(pb, xoff, yoff, ipb.get_width(), ipb.get_height(), xoff, yoff, 1, 1, gtk.gdk.INTERP_BILINEAR, 255) - img.set_from_pixbuf(pb) + img.set_from_pixbuf(pb) + img.show() + ipb.composite(pb, xoff, yoff, ipb.get_width(), ipb.get_height(), xoff, yoff, 1, 1, gtk.gdk.INTERP_BILINEAR, 255) + img.set_from_pixbuf(pb) - gc.collect() + gc.collect() - return img + return img - def setButtClickedId( self, id ): - self.BUTT_CLICKED_ID = id + def setButtClickedId( self, id ): + self.BUTT_CLICKED_ID = id - def getButtClickedId( self ): - return self.BUTT_CLICKED_ID + def getButtClickedId( self ): + return self.BUTT_CLICKED_ID - def setup_rollover_options( self, info ): - palette = Palette(info) - self.set_palette(palette) + def setup_rollover_options( self, info ): + palette = Palette(info) + self.set_palette(palette) - self.rem_menu_item = gtk.MenuItem( Constants.istrRemove ) - self.ACTIVATE_REMOVE_ID = self.rem_menu_item.connect('activate', self._itemRemoveCb) - palette.menu.append(self.rem_menu_item) - self.rem_menu_item.show() + self.rem_menu_item = gtk.MenuItem( Constants.istrRemove ) + self.ACTIVATE_REMOVE_ID = self.rem_menu_item.connect('activate', self._itemRemoveCb) + palette.menu.append(self.rem_menu_item) + self.rem_menu_item.show() - self.addCopyMenuItem() + self.addCopyMenuItem() - def addCopyMenuItem( self ): - if (self.recd.buddy and not self.recd.downloadedFromBuddy): - return - if (self.ACTIVATE_COPY_ID != 0): - return + def addCopyMenuItem( self ): + if (self.recd.buddy and not self.recd.downloadedFromBuddy): + return + if (self.ACTIVATE_COPY_ID != 0): + return - self.copy_menu_item = gtk.MenuItem( Constants.istrCopyToClipboard ) - self.ACTIVATE_COPY_ID = self.copy_menu_item.connect('activate', self._itemCopyToClipboardCb) - self.get_palette().menu.append(self.copy_menu_item) - self.copy_menu_item.show() + self.copy_menu_item = gtk.MenuItem( Constants.istrCopyToClipboard ) + self.ACTIVATE_COPY_ID = self.copy_menu_item.connect('activate', self._itemCopyToClipboardCb) + self.get_palette().menu.append(self.copy_menu_item) + self.copy_menu_item.show() - def cleanUp( self ): - self.rem_menu_item.disconnect( self.ACTIVATE_REMOVE_ID ) - if (self.ACTIVATE_COPY_ID != 0): - self.copy_menu_item.disconnect( self.ACTIVATE_COPY_ID ) + def cleanUp( self ): + self.rem_menu_item.disconnect( self.ACTIVATE_REMOVE_ID ) + if (self.ACTIVATE_COPY_ID != 0): + self.copy_menu_item.disconnect( self.ACTIVATE_COPY_ID ) - def _itemRemoveCb(self, widget): - self.ui.deleteThumbSelection( self.recd ) + def _itemRemoveCb(self, widget): + self.ui.deleteThumbSelection( self.recd ) - def _itemCopyToClipboardCb(self, widget): - self.ui.copyToClipboard( self.recd ) \ No newline at end of file + def _itemCopyToClipboardCb(self, widget): + self.ui.copyToClipboard( self.recd ) \ No newline at end of file diff --git a/color.py b/color.py index 3a9b954..f544405 100644 --- a/color.py +++ b/color.py @@ -22,50 +22,50 @@ import gtk class Color: - def __init__(self): - pass + def __init__(self): + pass - def init_rgba(self, r, g, b, a): - self._ro = r - self._go = g - self._bo = b - self._ao = a; - self._r = self._ro / 255.0 - self._g = self._go / 255.0 - self._b = self._bo / 255.0 - self._a = self._ao / 255.0 + def init_rgba(self, r, g, b, a): + self._ro = r + self._go = g + self._bo = b + self._ao = a; + self._r = self._ro / 255.0 + self._g = self._go / 255.0 + self._b = self._bo / 255.0 + self._a = self._ao / 255.0 - self._opaque = False - if (self._a == 1): - self.opaque = True + self._opaque = False + if (self._a == 1): + self.opaque = True - rgb_tup = ( self._ro, self._go, self._bo ) - self.hex = self.rgb_to_hex( rgb_tup ) - self.gColor = gtk.gdk.color_parse( self.hex ) + rgb_tup = ( self._ro, self._go, self._bo ) + self.hex = self.rgb_to_hex( rgb_tup ) + self.gColor = gtk.gdk.color_parse( self.hex ) - def init_gdk(self, col): - self.init_hex( col.get_html() ) + def init_gdk(self, col): + self.init_hex( col.get_html() ) - def init_hex(self, hex): - cTup = self.hex_to_rgb( hex ) - self.init_rgba( cTup[0], cTup[1], cTup[2], 255 ) + def init_hex(self, hex): + cTup = self.hex_to_rgb( hex ) + self.init_rgba( cTup[0], cTup[1], cTup[2], 255 ) - def get_int(self): - return int(self._a * 255) + (int(self._b * 255) << 8) + (int(self._g * 255) << 16) + (int(self._r * 255) << 24) + def get_int(self): + return int(self._a * 255) + (int(self._b * 255) << 8) + (int(self._g * 255) << 16) + (int(self._r * 255) << 24) - def rgb_to_hex(self, rgb_tup): - hexcolor = '#%02x%02x%02x' % rgb_tup - return hexcolor + def rgb_to_hex(self, rgb_tup): + hexcolor = '#%02x%02x%02x' % rgb_tup + return hexcolor - def hex_to_rgb(self, h): - c = eval('0x' + h[1:]) - r = (c >> 16) & 0xFF - g = (c >> 8) & 0xFF - b = c & 0xFF - return (int(r), int(g), int(b)) \ No newline at end of file + def hex_to_rgb(self, h): + c = eval('0x' + h[1:]) + r = (c >> 16) & 0xFF + g = (c >> 8) & 0xFF + b = c & 0xFF + return (int(r), int(g), int(b)) \ No newline at end of file diff --git a/constants.py b/constants.py index e24227d..0498b27 100644 --- a/constants.py +++ b/constants.py @@ -17,338 +17,338 @@ import pangocairo class Constants: - VERSION = 54 - - SERVICE = "org.laptop.Record" - IFACE = SERVICE - PATH = "/org/laptop/Record" - activityId = None - - recdTitle = "title" - recdTags = "tags" - recdTime = "time" - recdRecorderName = "photographer" - recdRecorderHash = "recorderHash" - recdColorStroke = "colorStroke" - recdColorFill = "colorFill" - recdHashKey = "hashKey" - recdBuddy = "buddy" - recdMediaMd5 = "mediaMd5" - recdThumbMd5 = "thumbMd5" - recdMediaBytes = "mediaBytes" - recdThumbBytes = "thumbBytes" - recdBase64Thumb = "base64Thumb" - recdDatastoreId = "datastoreId" - recdAudioImage = "audioImage" - recdAlbum = "album" - recdType = "type" - recdRecd = "recd" - recdRecordVersion = "version" - - keyName = "name" - keyMime = "mime" - keyExt = "ext" - keyIstr = "istr" - - MODE_PHOTO = 0 - MODE_VIDEO = 1 - MODE_AUDIO = 2 - TYPE_PHOTO = MODE_PHOTO - TYPE_VIDEO = MODE_VIDEO - TYPE_AUDIO = MODE_AUDIO - - TIMER_0 = 0 - TIMER_5 = 5 - TIMER_10 = 10 - TIMERS = [] - TIMERS.append(TIMER_0) - TIMERS.append(TIMER_5) - TIMERS.append(TIMER_10) - - DURATION_2 = 2 - DURATION_4 = 4 - DURATION_6 = 6 - DURATIONS = [] - DURATIONS.append(DURATION_2) - DURATIONS.append(DURATION_4) - DURATIONS.append(DURATION_6) - - colorBlack = Color() - colorBlack.init_rgba( 0, 0, 0, 255 ) - colorWhite = Color() - colorWhite.init_rgba( 255, 255, 255, 255 ) - colorRed = Color() - colorRed.init_rgba( 255, 0, 0, 255) - colorGreen = Color() - colorGreen.init_rgba( 0, 255, 0, 255) - colorBlue = Color() - colorBlue.init_rgba( 0, 0, 255, 255) - colorButton = Color() - colorButton.init_gdk( sugar.graphics.style.COLOR_BUTTON_GREY ) - - gfxPath = os.path.join(activity.get_bundle_path(), "gfx") - soundClick = os.path.join(gfxPath, 'photoShutter.wav') - - - #defensive method against variables not translated correctly - def _(s): - #todo: permanent variable - istrsTest = {} - for i in range (0,4): - istrsTest[str(i)] = str(i) - - i = s - try: - #test translating the string with many replacements - i = gt(s) - test = i % istrsTest - except: - #if it doesn't work, revert - i = s - - return i - - - istrActivityName = _('Record') - istrPhoto = _('Photo') - istrVideo = _('Video') - istrAudio = _('Audio') - istrTimelapse = _('Time Lapse') - istrAnimation = _('Animation') - istrPanorama = _('Panorama') - istrInterview= _('Interview') - #TRANS: photo by photographer, e.g., "Photo by Mary" - istrBy = _("%(1)s by %(2)s") - istrTitle = _('Title:') - istrRecorder = _('Recorder:') - istrDate = _('Date:') - istrTags = _('Tags:') - istrSaving = _('Saving') - istrFinishedRecording = _("Finished recording") - istrHoursMinutesSecondsRemaining = _("%(1)s hours, %(2)s minutes, %(3)s seconds remaining") - istrMinutesSecondsRemaining = _("%(1)s minutes, %(2)s seconds remaining") - istrHoursRemaining = _("%(1)s hours remaining") - istrMinutesRemaining = _("%(1)s minutes remaining") - istrSecondsRemaining = _("%(1)s seconds remaining") - istrHours = _("%(1)s hours") - istrMinutes = _("%(1)s minutes") - istrSeconds = _("%(1)s seconds") - istrRemove = _("Remove") - istrStoppedRecording = _("Stopped recording") - istrCopyToClipboard = _("Copy to clipboard") - istrTimer = _("Timer:") - istrDuration = _("Duration:") - istrNow = _("Immediate") - istrPlay = _("Play") - istrPause = _("Pause") - istrAddFrame = _("Add frame") - istrRemoveFrame = _("Remove frame") - istrFramesPerSecond = _("%(1)s frames per second") - istrQuality = _("Quality") - istrDefault = _("Default") - istrBestQuality = _("Best") - istrHighQuality = _("High") - istrLowQuality = _("Low") - istrLargeFile = _("Large file") - istrSmallFile = _("Small file") - istrSilent = _("Silent") - istrRotate = _("Rotate") - istrWidth = _("Width") - istrHeight = _("Height") - istrClickToTakePicture = _("Click to take picture") - istrClickToAddPicture = _("Click to add picture") - #TRANS: Downloading Photo from Mary - istrDownloadingFrom = _("Downloading %(1)s from %(2)s") - #TRANS: Cannot download this Photo - istrCannotDownload = _("Cannot download this %(1)s") - #TRANS: Save Photo to: - istrSaveTo = _("Save %(1)s to:") - istrYourDiskIsFull = _("Your %(1)s is full") - istrJournal = _("Journal") - istrUSB = _("USB") - istrCompactFlash = _("SD Card") - istrPreferences = _("Preferences") - istrFreeSpace = _("Free space:") - #TRANS: 7 photos - istrNumPhotos = _("%(1)s photos") - istrBitrate = _("Bitrate") - istrMaxBitrate = _("Maximum Bitrate") - istrMinBitrate = _("Minumum Bitrate") - istrManageBitrate = _("Manage Bitrate") - istrBorder = _("Border") - istrCenter = _("Center") - istrFrames = _("Frames") - istrKeyframeAuto = _("Automatic keyframe detection") - istrKeyframeForce = _("Force keyframe") - istrKeyframeFrequency = _("Keyframe frequency") - istrKeyframeMinDist = _("Keyframe minimum distance") - istrKeyframeThreshold = _("Keyframe threshold") - istrNoiseSensitivity = _("Noise Sensitivity") - istrQuick = _("Quick") - istrSharpness = _("Sharpness") - istrCapacity = _("Capacity") - - mediaTypes = {} - mediaTypes[TYPE_PHOTO] = {keyName:"photo", keyMime:"image/jpeg", keyExt:"jpg", keyIstr:istrPhoto} - mediaTypes[TYPE_VIDEO] = {keyName:"video", keyMime:"video/ogg", keyExt:"ogg", keyIstr:istrVideo} - mediaTypes[TYPE_AUDIO] = {keyName:"audio", keyMime:"audio/ogg", keyExt:"ogg", keyIstr:istrAudio} - - thumbPhotoSvgData = None - thumbPhotoSvg = None - thumbVideoSvg = None - maxEnlargeSvg = None - maxReduceSvg = None - infoOnSvg = None - xoGuySvgData = None - - recImg = None - recRedImg = None - recCircleCairo = None - recInsensitiveImg = None - recPlayImg = None - recPauseImg = None - countdownImgs = {} - - dim_CONTROLBAR_HT = 55 - - keepFreeKbOnXo = 200000 - - def __init__( self, ca ): - self.__class__.activityId = ca._activity_id - - thumbPhotoSvgPath = os.path.join(self.__class__.gfxPath, 'object-photo.svg') - thumbPhotoSvgFile = open(thumbPhotoSvgPath, 'r') - self.__class__.thumbPhotoSvgData = thumbPhotoSvgFile.read() - self.__class__.thumbPhotoSvg = utils.loadSvg(self.__class__.thumbPhotoSvgData, Instance.colorStroke.hex, Instance.colorFill.hex) - thumbPhotoSvgFile.close() - - thumbVideoSvgPath = os.path.join(self.__class__.gfxPath, 'object-video.svg') - thumbVideoSvgFile = open(thumbVideoSvgPath, 'r') - self.__class__.thumbVideoSvgData = thumbVideoSvgFile.read() - self.__class__.thumbVideoSvg = utils.loadSvg(self.__class__.thumbVideoSvgData, Instance.colorStroke.hex, Instance.colorFill.hex) - thumbVideoSvgFile.close() - - thumbAudioSvgPath = os.path.join(self.__class__.gfxPath, 'object-audio.svg') - thumbAudioSvgFile = open(thumbAudioSvgPath, 'r') - self.__class__.thumbAudioSvgData = thumbAudioSvgFile.read() - self.__class__.thumbAudioSvg = utils.loadSvg(self.__class__.thumbAudioSvgData, Instance.colorStroke.hex, Instance.colorFill.hex) - thumbAudioSvgFile.close() - - maxEnlargeSvgPath = os.path.join(self.__class__.gfxPath, 'max-enlarge.svg') - maxEnlargeSvgFile = open(maxEnlargeSvgPath, 'r') - maxEnlargeSvgData = maxEnlargeSvgFile.read() - self.__class__.maxEnlargeSvg = utils.loadSvg(maxEnlargeSvgData, None, None ) - maxEnlargeSvgFile.close() - - maxReduceSvgPath = os.path.join(self.__class__.gfxPath, 'max-reduce.svg') - maxReduceSvgFile = open(maxReduceSvgPath, 'r') - maxReduceSvgData = maxReduceSvgFile.read() - self.__class__.maxReduceSvg = utils.loadSvg(maxReduceSvgData, None, None ) - maxReduceSvgFile.close() - - infoOnSvgPath = os.path.join(self.__class__.gfxPath, 'corner-info.svg') - infoOnSvgFile = open(infoOnSvgPath, 'r') - infoOnSvgData = infoOnSvgFile.read() - self.__class__.infoOnSvg = utils.loadSvg(infoOnSvgData, None, None ) - infoOnSvgFile.close() - - xoGuySvgPath = os.path.join(self.__class__.gfxPath, 'xo-guy.svg') - xoGuySvgFile = open(xoGuySvgPath, 'r') - self.__class__.xoGuySvgData = xoGuySvgFile.read() - xoGuySvgFile.close() - - recFile = os.path.join(self.__class__.gfxPath, 'media-record.png') - recPixbuf = gtk.gdk.pixbuf_new_from_file(recFile) - self.__class__.recImg = gtk.Image() - self.__class__.recImg.set_from_pixbuf( recPixbuf ) - - recRedFile = os.path.join(self.__class__.gfxPath, 'media-record-red.png') - recRedPixbuf = gtk.gdk.pixbuf_new_from_file(recRedFile) - self.__class__.recRedImg = gtk.Image() - self.__class__.recRedImg.set_from_pixbuf( recRedPixbuf ) - - recCircleFile = os.path.join(self.__class__.gfxPath, 'media-circle.png') - recCirclePixbuf = gtk.gdk.pixbuf_new_from_file(recCircleFile) - self.__class__.recCircleCairo = camerac.cairo_surface_from_gdk_pixbuf(recCirclePixbuf) - - recInsFile = os.path.join(self.__class__.gfxPath, 'media-insensitive.png') - recInsPixbuf = gtk.gdk.pixbuf_new_from_file(recInsFile) - self.__class__.recInsensitiveImg = gtk.Image() - self.__class__.recInsensitiveImg.set_from_pixbuf( recInsPixbuf ) - - fullInsFile = os.path.join(self.__class__.gfxPath, 'full-insensitive.png') - fullInsPixbuf = gtk.gdk.pixbuf_new_from_file(fullInsFile) - self.__class__.fullInsensitiveImg = gtk.Image() - self.__class__.fullInsensitiveImg.set_from_pixbuf( fullInsPixbuf ) - - recPlayFile = os.path.join(self.__class__.gfxPath, 'media-play.png') - recPlayPixbuf = gtk.gdk.pixbuf_new_from_file(recPlayFile) - self.__class__.recPlayImg = gtk.Image() - self.__class__.recPlayImg.set_from_pixbuf( recPlayPixbuf ) - - recPauseFile = os.path.join(self.__class__.gfxPath, 'media-pause.png') - recPausePixbuf = gtk.gdk.pixbuf_new_from_file(recPauseFile) - self.__class__.recPauseImg = gtk.Image() - self.__class__.recPauseImg.set_from_pixbuf( recPausePixbuf ) - - self._ts = self.__class__.TIMERS - longestTime = self._ts[len(self._ts)-1] - for i in range (0, longestTime): - self.createCountdownPng( i ) - - - def createCountdownPng(self, num): - todisk = True - - rendered = False - if (todisk): - path = os.path.join(Instance.dataPath, str(num)+".png") - if (os.path.exists(path)): - rendered = True - - - if (not rendered): - w = self.__class__.dim_CONTROLBAR_HT - h = w - if (todisk): - cimg = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h) - ctx = cairo.Context(cimg) - else: - pixmap = gtk.gdk.Pixmap(None, w, h, 24) - ctx = pixmap.cairo_create() - ctx.rectangle(0, 0, w, h) - ctx.set_source_rgb(0, 0, 0) - ctx.fill() - x = 0 - y = 4 - ctx.translate(x,y) - ctx.set_source_surface (self.__class__.recCircleCairo, 0, 0) - ctx.paint() - ctx.translate(-x,-y) - - ctx.set_source_rgb(255, 255, 255) - pctx = pangocairo.CairoContext(ctx) - play = pctx.create_layout() - font = pango.FontDescription("sans 30") - play.set_font_description(font) - play.set_text( ""+str(num) ) - dim = play.get_pixel_extents() - ctx.translate( -dim[0][0], -dim[0][1] ) - xoff = (w-dim[0][2])/2 - yoff = (h-dim[0][3])/2 - ctx.translate( xoff, yoff ) - ctx.translate( -3, 0 ) - pctx.show_layout(play) - - img = gtk.Image() - if (todisk): - path = os.path.join(Instance.dataPath, str(num)+".png") - if (not rendered): - path = utils.getUniqueFilepath(path, 0) - cimg.write_to_png(path) - numPixbuf = gtk.gdk.pixbuf_new_from_file(path) - img.set_from_pixbuf( numPixbuf ) - else: - img.set_from_pixmap(pixmap, None) - - self.__class__.countdownImgs[int(num)] = img + VERSION = 54 + + SERVICE = "org.laptop.Record" + IFACE = SERVICE + PATH = "/org/laptop/Record" + activityId = None + + recdTitle = "title" + recdTags = "tags" + recdTime = "time" + recdRecorderName = "photographer" + recdRecorderHash = "recorderHash" + recdColorStroke = "colorStroke" + recdColorFill = "colorFill" + recdHashKey = "hashKey" + recdBuddy = "buddy" + recdMediaMd5 = "mediaMd5" + recdThumbMd5 = "thumbMd5" + recdMediaBytes = "mediaBytes" + recdThumbBytes = "thumbBytes" + recdBase64Thumb = "base64Thumb" + recdDatastoreId = "datastoreId" + recdAudioImage = "audioImage" + recdAlbum = "album" + recdType = "type" + recdRecd = "recd" + recdRecordVersion = "version" + + keyName = "name" + keyMime = "mime" + keyExt = "ext" + keyIstr = "istr" + + MODE_PHOTO = 0 + MODE_VIDEO = 1 + MODE_AUDIO = 2 + TYPE_PHOTO = MODE_PHOTO + TYPE_VIDEO = MODE_VIDEO + TYPE_AUDIO = MODE_AUDIO + + TIMER_0 = 0 + TIMER_5 = 5 + TIMER_10 = 10 + TIMERS = [] + TIMERS.append(TIMER_0) + TIMERS.append(TIMER_5) + TIMERS.append(TIMER_10) + + DURATION_2 = 2 + DURATION_4 = 4 + DURATION_6 = 6 + DURATIONS = [] + DURATIONS.append(DURATION_2) + DURATIONS.append(DURATION_4) + DURATIONS.append(DURATION_6) + + colorBlack = Color() + colorBlack.init_rgba( 0, 0, 0, 255 ) + colorWhite = Color() + colorWhite.init_rgba( 255, 255, 255, 255 ) + colorRed = Color() + colorRed.init_rgba( 255, 0, 0, 255) + colorGreen = Color() + colorGreen.init_rgba( 0, 255, 0, 255) + colorBlue = Color() + colorBlue.init_rgba( 0, 0, 255, 255) + colorButton = Color() + colorButton.init_gdk( sugar.graphics.style.COLOR_BUTTON_GREY ) + + gfxPath = os.path.join(activity.get_bundle_path(), "gfx") + soundClick = os.path.join(gfxPath, 'photoShutter.wav') + + + #defensive method against variables not translated correctly + def _(s): + #todo: permanent variable + istrsTest = {} + for i in range (0,4): + istrsTest[str(i)] = str(i) + + i = s + try: + #test translating the string with many replacements + i = gt(s) + test = i % istrsTest + except: + #if it doesn't work, revert + i = s + + return i + + + istrActivityName = _('Record') + istrPhoto = _('Photo') + istrVideo = _('Video') + istrAudio = _('Audio') + istrTimelapse = _('Time Lapse') + istrAnimation = _('Animation') + istrPanorama = _('Panorama') + istrInterview= _('Interview') + #TRANS: photo by photographer, e.g., "Photo by Mary" + istrBy = _("%(1)s by %(2)s") + istrTitle = _('Title:') + istrRecorder = _('Recorder:') + istrDate = _('Date:') + istrTags = _('Tags:') + istrSaving = _('Saving') + istrFinishedRecording = _("Finished recording") + istrHoursMinutesSecondsRemaining = _("%(1)s hours, %(2)s minutes, %(3)s seconds remaining") + istrMinutesSecondsRemaining = _("%(1)s minutes, %(2)s seconds remaining") + istrHoursRemaining = _("%(1)s hours remaining") + istrMinutesRemaining = _("%(1)s minutes remaining") + istrSecondsRemaining = _("%(1)s seconds remaining") + istrHours = _("%(1)s hours") + istrMinutes = _("%(1)s minutes") + istrSeconds = _("%(1)s seconds") + istrRemove = _("Remove") + istrStoppedRecording = _("Stopped recording") + istrCopyToClipboard = _("Copy to clipboard") + istrTimer = _("Timer:") + istrDuration = _("Duration:") + istrNow = _("Immediate") + istrPlay = _("Play") + istrPause = _("Pause") + istrAddFrame = _("Add frame") + istrRemoveFrame = _("Remove frame") + istrFramesPerSecond = _("%(1)s frames per second") + istrQuality = _("Quality") + istrDefault = _("Default") + istrBestQuality = _("Best") + istrHighQuality = _("High") + istrLowQuality = _("Low") + istrLargeFile = _("Large file") + istrSmallFile = _("Small file") + istrSilent = _("Silent") + istrRotate = _("Rotate") + istrWidth = _("Width") + istrHeight = _("Height") + istrClickToTakePicture = _("Click to take picture") + istrClickToAddPicture = _("Click to add picture") + #TRANS: Downloading Photo from Mary + istrDownloadingFrom = _("Downloading %(1)s from %(2)s") + #TRANS: Cannot download this Photo + istrCannotDownload = _("Cannot download this %(1)s") + #TRANS: Save Photo to: + istrSaveTo = _("Save %(1)s to:") + istrYourDiskIsFull = _("Your %(1)s is full") + istrJournal = _("Journal") + istrUSB = _("USB") + istrCompactFlash = _("SD Card") + istrPreferences = _("Preferences") + istrFreeSpace = _("Free space:") + #TRANS: 7 photos + istrNumPhotos = _("%(1)s photos") + istrBitrate = _("Bitrate") + istrMaxBitrate = _("Maximum Bitrate") + istrMinBitrate = _("Minumum Bitrate") + istrManageBitrate = _("Manage Bitrate") + istrBorder = _("Border") + istrCenter = _("Center") + istrFrames = _("Frames") + istrKeyframeAuto = _("Automatic keyframe detection") + istrKeyframeForce = _("Force keyframe") + istrKeyframeFrequency = _("Keyframe frequency") + istrKeyframeMinDist = _("Keyframe minimum distance") + istrKeyframeThreshold = _("Keyframe threshold") + istrNoiseSensitivity = _("Noise Sensitivity") + istrQuick = _("Quick") + istrSharpness = _("Sharpness") + istrCapacity = _("Capacity") + + mediaTypes = {} + mediaTypes[TYPE_PHOTO] = {keyName:"photo", keyMime:"image/jpeg", keyExt:"jpg", keyIstr:istrPhoto} + mediaTypes[TYPE_VIDEO] = {keyName:"video", keyMime:"video/ogg", keyExt:"ogg", keyIstr:istrVideo} + mediaTypes[TYPE_AUDIO] = {keyName:"audio", keyMime:"audio/ogg", keyExt:"ogg", keyIstr:istrAudio} + + thumbPhotoSvgData = None + thumbPhotoSvg = None + thumbVideoSvg = None + maxEnlargeSvg = None + maxReduceSvg = None + infoOnSvg = None + xoGuySvgData = None + + recImg = None + recRedImg = None + recCircleCairo = None + recInsensitiveImg = None + recPlayImg = None + recPauseImg = None + countdownImgs = {} + + dim_CONTROLBAR_HT = 55 + + keepFreeKbOnXo = 200000 + + def __init__( self, ca ): + self.__class__.activityId = ca._activity_id + + thumbPhotoSvgPath = os.path.join(self.__class__.gfxPath, 'object-photo.svg') + thumbPhotoSvgFile = open(thumbPhotoSvgPath, 'r') + self.__class__.thumbPhotoSvgData = thumbPhotoSvgFile.read() + self.__class__.thumbPhotoSvg = utils.loadSvg(self.__class__.thumbPhotoSvgData, Instance.colorStroke.hex, Instance.colorFill.hex) + thumbPhotoSvgFile.close() + + thumbVideoSvgPath = os.path.join(self.__class__.gfxPath, 'object-video.svg') + thumbVideoSvgFile = open(thumbVideoSvgPath, 'r') + self.__class__.thumbVideoSvgData = thumbVideoSvgFile.read() + self.__class__.thumbVideoSvg = utils.loadSvg(self.__class__.thumbVideoSvgData, Instance.colorStroke.hex, Instance.colorFill.hex) + thumbVideoSvgFile.close() + + thumbAudioSvgPath = os.path.join(self.__class__.gfxPath, 'object-audio.svg') + thumbAudioSvgFile = open(thumbAudioSvgPath, 'r') + self.__class__.thumbAudioSvgData = thumbAudioSvgFile.read() + self.__class__.thumbAudioSvg = utils.loadSvg(self.__class__.thumbAudioSvgData, Instance.colorStroke.hex, Instance.colorFill.hex) + thumbAudioSvgFile.close() + + maxEnlargeSvgPath = os.path.join(self.__class__.gfxPath, 'max-enlarge.svg') + maxEnlargeSvgFile = open(maxEnlargeSvgPath, 'r') + maxEnlargeSvgData = maxEnlargeSvgFile.read() + self.__class__.maxEnlargeSvg = utils.loadSvg(maxEnlargeSvgData, None, None ) + maxEnlargeSvgFile.close() + + maxReduceSvgPath = os.path.join(self.__class__.gfxPath, 'max-reduce.svg') + maxReduceSvgFile = open(maxReduceSvgPath, 'r') + maxReduceSvgData = maxReduceSvgFile.read() + self.__class__.maxReduceSvg = utils.loadSvg(maxReduceSvgData, None, None ) + maxReduceSvgFile.close() + + infoOnSvgPath = os.path.join(self.__class__.gfxPath, 'corner-info.svg') + infoOnSvgFile = open(infoOnSvgPath, 'r') + infoOnSvgData = infoOnSvgFile.read() + self.__class__.infoOnSvg = utils.loadSvg(infoOnSvgData, None, None ) + infoOnSvgFile.close() + + xoGuySvgPath = os.path.join(self.__class__.gfxPath, 'xo-guy.svg') + xoGuySvgFile = open(xoGuySvgPath, 'r') + self.__class__.xoGuySvgData = xoGuySvgFile.read() + xoGuySvgFile.close() + + recFile = os.path.join(self.__class__.gfxPath, 'media-record.png') + recPixbuf = gtk.gdk.pixbuf_new_from_file(recFile) + self.__class__.recImg = gtk.Image() + self.__class__.recImg.set_from_pixbuf( recPixbuf ) + + recRedFile = os.path.join(self.__class__.gfxPath, 'media-record-red.png') + recRedPixbuf = gtk.gdk.pixbuf_new_from_file(recRedFile) + self.__class__.recRedImg = gtk.Image() + self.__class__.recRedImg.set_from_pixbuf( recRedPixbuf ) + + recCircleFile = os.path.join(self.__class__.gfxPath, 'media-circle.png') + recCirclePixbuf = gtk.gdk.pixbuf_new_from_file(recCircleFile) + self.__class__.recCircleCairo = camerac.cairo_surface_from_gdk_pixbuf(recCirclePixbuf) + + recInsFile = os.path.join(self.__class__.gfxPath, 'media-insensitive.png') + recInsPixbuf = gtk.gdk.pixbuf_new_from_file(recInsFile) + self.__class__.recInsensitiveImg = gtk.Image() + self.__class__.recInsensitiveImg.set_from_pixbuf( recInsPixbuf ) + + fullInsFile = os.path.join(self.__class__.gfxPath, 'full-insensitive.png') + fullInsPixbuf = gtk.gdk.pixbuf_new_from_file(fullInsFile) + self.__class__.fullInsensitiveImg = gtk.Image() + self.__class__.fullInsensitiveImg.set_from_pixbuf( fullInsPixbuf ) + + recPlayFile = os.path.join(self.__class__.gfxPath, 'media-play.png') + recPlayPixbuf = gtk.gdk.pixbuf_new_from_file(recPlayFile) + self.__class__.recPlayImg = gtk.Image() + self.__class__.recPlayImg.set_from_pixbuf( recPlayPixbuf ) + + recPauseFile = os.path.join(self.__class__.gfxPath, 'media-pause.png') + recPausePixbuf = gtk.gdk.pixbuf_new_from_file(recPauseFile) + self.__class__.recPauseImg = gtk.Image() + self.__class__.recPauseImg.set_from_pixbuf( recPausePixbuf ) + + self._ts = self.__class__.TIMERS + longestTime = self._ts[len(self._ts)-1] + for i in range (0, longestTime): + self.createCountdownPng( i ) + + + def createCountdownPng(self, num): + todisk = True + + rendered = False + if (todisk): + path = os.path.join(Instance.dataPath, str(num)+".png") + if (os.path.exists(path)): + rendered = True + + + if (not rendered): + w = self.__class__.dim_CONTROLBAR_HT + h = w + if (todisk): + cimg = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h) + ctx = cairo.Context(cimg) + else: + pixmap = gtk.gdk.Pixmap(None, w, h, 24) + ctx = pixmap.cairo_create() + ctx.rectangle(0, 0, w, h) + ctx.set_source_rgb(0, 0, 0) + ctx.fill() + x = 0 + y = 4 + ctx.translate(x,y) + ctx.set_source_surface (self.__class__.recCircleCairo, 0, 0) + ctx.paint() + ctx.translate(-x,-y) + + ctx.set_source_rgb(255, 255, 255) + pctx = pangocairo.CairoContext(ctx) + play = pctx.create_layout() + font = pango.FontDescription("sans 30") + play.set_font_description(font) + play.set_text( ""+str(num) ) + dim = play.get_pixel_extents() + ctx.translate( -dim[0][0], -dim[0][1] ) + xoff = (w-dim[0][2])/2 + yoff = (h-dim[0][3])/2 + ctx.translate( xoff, yoff ) + ctx.translate( -3, 0 ) + pctx.show_layout(play) + + img = gtk.Image() + if (todisk): + path = os.path.join(Instance.dataPath, str(num)+".png") + if (not rendered): + path = utils.getUniqueFilepath(path, 0) + cimg.write_to_png(path) + numPixbuf = gtk.gdk.pixbuf_new_from_file(path) + img.set_from_pixbuf( numPixbuf ) + else: + img.set_from_pixmap(pixmap, None) + + self.__class__.countdownImgs[int(num)] = img diff --git a/glive.py b/glive.py index ae7480c..7b7619f 100644 --- a/glive.py +++ b/glive.py @@ -40,519 +40,519 @@ import utils import ui class Glive: - def __init__(self, pca): - self.window = None - self.ca = pca - self._eos_cb = None + def __init__(self, pca): + self.window = None + self.ca = pca + self._eos_cb = None - self.playing = False - self.picExposureOpen = False + self.playing = False + self.picExposureOpen = False - self.AUDIO_TRANSCODE_ID = 0 - self.TRANSCODE_ID = 0 - self.VIDEO_TRANSCODE_ID = 0 + self.AUDIO_TRANSCODE_ID = 0 + self.TRANSCODE_ID = 0 + self.VIDEO_TRANSCODE_ID = 0 - self.PHOTO_MODE_PHOTO = 0 - self.PHOTO_MODE_AUDIO = 1 + self.PHOTO_MODE_PHOTO = 0 + self.PHOTO_MODE_AUDIO = 1 - self.TRANSCODE_UPDATE_INTERVAL = 200 + self.TRANSCODE_UPDATE_INTERVAL = 200 - self.VIDEO_WIDTH_SMALL = 160 - self.VIDEO_HEIGHT_SMALL = 120 - self.VIDEO_FRAMERATE_SMALL = 10 + self.VIDEO_WIDTH_SMALL = 160 + self.VIDEO_HEIGHT_SMALL = 120 + self.VIDEO_FRAMERATE_SMALL = 10 - self.VIDEO_WIDTH_LARGE = 200 - self.VIDEO_HEIGHT_LARGE = 150 - self.VIDEO_FRAMERATE_SMALL = 10 + self.VIDEO_WIDTH_LARGE = 200 + self.VIDEO_HEIGHT_LARGE = 150 + self.VIDEO_FRAMERATE_SMALL = 10 - self.pipeline = gst.Pipeline("my-pipeline") - self.createPhotoBin() - self.createAudioBin() - self.createVideoBin() - self.createPipeline() + self.pipeline = gst.Pipeline("my-pipeline") + self.createPhotoBin() + self.createAudioBin() + self.createVideoBin() + self.createPipeline() - self.thumbPipes = [] - self.muxPipes = [] + self.thumbPipes = [] + self.muxPipes = [] - bus = self.pipeline.get_bus() - bus.enable_sync_message_emission() - bus.add_signal_watch() - self.SYNC_ID = bus.connect('sync-message::element', self._onSyncMessageCb) - self.MESSAGE_ID = bus.connect('message', self._onMessageCb) + bus = self.pipeline.get_bus() + bus.enable_sync_message_emission() + bus.add_signal_watch() + self.SYNC_ID = bus.connect('sync-message::element', self._onSyncMessageCb) + self.MESSAGE_ID = bus.connect('message', self._onMessageCb) - def createPhotoBin ( self ): - queue = gst.element_factory_make("queue", "pbqueue") - queue.set_property("leaky", True) - queue.set_property("max-size-buffers", 1) + def createPhotoBin ( self ): + queue = gst.element_factory_make("queue", "pbqueue") + queue.set_property("leaky", True) + queue.set_property("max-size-buffers", 1) - colorspace = gst.element_factory_make("ffmpegcolorspace", "pbcolorspace") - jpeg = gst.element_factory_make("jpegenc", "pbjpeg") + colorspace = gst.element_factory_make("ffmpegcolorspace", "pbcolorspace") + jpeg = gst.element_factory_make("jpegenc", "pbjpeg") - sink = gst.element_factory_make("fakesink", "pbsink") - self.HANDOFF_ID = sink.connect("handoff", self.copyPic) - sink.set_property("signal-handoffs", True) + sink = gst.element_factory_make("fakesink", "pbsink") + self.HANDOFF_ID = sink.connect("handoff", self.copyPic) + sink.set_property("signal-handoffs", True) - self.photobin = gst.Bin("photobin") - self.photobin.add(queue, colorspace, jpeg, sink) + self.photobin = gst.Bin("photobin") + self.photobin.add(queue, colorspace, jpeg, sink) - gst.element_link_many(queue, colorspace, jpeg, sink) + gst.element_link_many(queue, colorspace, jpeg, sink) - pad = queue.get_static_pad("sink") - self.photobin.add_pad(gst.GhostPad("sink", pad)) + pad = queue.get_static_pad("sink") + self.photobin.add_pad(gst.GhostPad("sink", pad)) - def createAudioBin ( self ): - src = gst.element_factory_make("alsasrc", "absrc") - srccaps = gst.Caps("audio/x-raw-int,rate=16000,channels=1,depth=16") + def createAudioBin ( self ): + src = gst.element_factory_make("alsasrc", "absrc") + srccaps = gst.Caps("audio/x-raw-int,rate=16000,channels=1,depth=16") - enc = gst.element_factory_make("wavenc", "abenc") + enc = gst.element_factory_make("wavenc", "abenc") - sink = gst.element_factory_make("filesink", "absink") - sink.set_property("location", os.path.join(Instance.instancePath, "output.wav")) + sink = gst.element_factory_make("filesink", "absink") + sink.set_property("location", os.path.join(Instance.instancePath, "output.wav")) - self.audiobin = gst.Bin("audiobin") - self.audiobin.add(src, enc, sink) + self.audiobin = gst.Bin("audiobin") + self.audiobin.add(src, enc, sink) - src.link(enc, srccaps) - enc.link(sink) + src.link(enc, srccaps) + enc.link(sink) - def createVideoBin ( self ): - queue = gst.element_factory_make("queue", "vbqueue") + def createVideoBin ( self ): + queue = gst.element_factory_make("queue", "vbqueue") - rate = gst.element_factory_make("videorate", "vbrate") - ratecaps = gst.Caps('video/x-raw-yuv,framerate='+str(self.VIDEO_FRAMERATE_SMALL)+'/1') + rate = gst.element_factory_make("videorate", "vbrate") + ratecaps = gst.Caps('video/x-raw-yuv,framerate='+str(self.VIDEO_FRAMERATE_SMALL)+'/1') - scale = gst.element_factory_make("videoscale", "vbscale") - scalecaps = gst.Caps('video/x-raw-yuv,width='+str(self.VIDEO_WIDTH_SMALL)+',height='+str(self.VIDEO_HEIGHT_SMALL)) + scale = gst.element_factory_make("videoscale", "vbscale") + scalecaps = gst.Caps('video/x-raw-yuv,width='+str(self.VIDEO_WIDTH_SMALL)+',height='+str(self.VIDEO_HEIGHT_SMALL)) - colorspace = gst.element_factory_make("ffmpegcolorspace", "vbcolorspace") + colorspace = gst.element_factory_make("ffmpegcolorspace", "vbcolorspace") - enc = gst.element_factory_make("theoraenc", "vbenc") - enc.set_property("quality", 16) + enc = gst.element_factory_make("theoraenc", "vbenc") + enc.set_property("quality", 16) - mux = gst.element_factory_make("oggmux", "vbmux") + mux = gst.element_factory_make("oggmux", "vbmux") - sink = gst.element_factory_make("filesink", "vbfile") - sink.set_property("location", os.path.join(Instance.instancePath, "output.ogg")) + sink = gst.element_factory_make("filesink", "vbfile") + sink.set_property("location", os.path.join(Instance.instancePath, "output.ogg")) - self.videobin = gst.Bin("videobin") - self.videobin.add(queue, rate, scale, colorspace, enc, mux, sink) + self.videobin = gst.Bin("videobin") + self.videobin.add(queue, rate, scale, colorspace, enc, mux, sink) - queue.link(rate) - rate.link(scale, ratecaps) - scale.link(colorspace, scalecaps) - gst.element_link_many(colorspace, enc, mux, sink) + queue.link(rate) + rate.link(scale, ratecaps) + scale.link(colorspace, scalecaps) + gst.element_link_many(colorspace, enc, mux, sink) - pad = queue.get_static_pad("sink") - self.videobin.add_pad(gst.GhostPad("sink", pad)) + pad = queue.get_static_pad("sink") + self.videobin.add_pad(gst.GhostPad("sink", pad)) - def createPipeline ( self ): - src = gst.element_factory_make("v4l2src", "camsrc") - try: - # old gst-plugins-good does not have this property - src.set_property("queue-size", 2) - except: - pass + def createPipeline ( self ): + src = gst.element_factory_make("v4l2src", "camsrc") + try: + # old gst-plugins-good does not have this property + src.set_property("queue-size", 2) + except: + pass - tee = gst.element_factory_make("tee", "tee") - queue = gst.element_factory_make("queue", "dispqueue") - xvsink = gst.element_factory_make("xvimagesink", "xvsink") - self.pipeline.add(src, tee, queue, xvsink) - gst.element_link_many(src, tee, queue, xvsink) + tee = gst.element_factory_make("tee", "tee") + queue = gst.element_factory_make("queue", "dispqueue") + xvsink = gst.element_factory_make("xvimagesink", "xvsink") + self.pipeline.add(src, tee, queue, xvsink) + gst.element_link_many(src, tee, queue, xvsink) - def thumbPipe(self): - return self.thumbPipes[ len(self.thumbPipes)-1 ] + def thumbPipe(self): + return self.thumbPipes[ len(self.thumbPipes)-1 ] - def thumbEl(self, name): - return self.thumbPipe().get_by_name(name) + def thumbEl(self, name): + return self.thumbPipe().get_by_name(name) - def muxPipe(self): - return self.muxPipes[ len(self.muxPipes)-1 ] + def muxPipe(self): + return self.muxPipes[ len(self.muxPipes)-1 ] - def muxEl(self, name): - return self.muxPipe().get_by_name(name) + def muxEl(self, name): + return self.muxPipe().get_by_name(name) - def play(self): - self.pipeline.set_state(gst.STATE_PLAYING) - self.playing = True + def play(self): + self.pipeline.set_state(gst.STATE_PLAYING) + self.playing = True - def pause(self): - self.pipeline.set_state(gst.STATE_PAUSED) - self.playing = False + def pause(self): + self.pipeline.set_state(gst.STATE_PAUSED) + self.playing = False - def stop(self): - self.pipeline.set_state(gst.STATE_NULL) - self.playing = False + def stop(self): + self.pipeline.set_state(gst.STATE_NULL) + self.playing = False - def is_playing(self): - return self.playing + def is_playing(self): + return self.playing - def idlePlayElement(self, element): - element.set_state(gst.STATE_PLAYING) - return False + def idlePlayElement(self, element): + element.set_state(gst.STATE_PLAYING) + return False - def stopRecordingAudio( self ): - self.audiobin.set_state(gst.STATE_NULL) - self.pipeline.remove(self.audiobin) - gobject.idle_add( self.stoppedRecordingAudio ) - - - def stoppedRecordingVideo(self): - if ( len(self.thumbPipes) > 0 ): - thumbline = self.thumbPipes[len(self.thumbPipes)-1] - thumbline.get_by_name('thumbFakesink').disconnect(self.THUMB_HANDOFF_ID) - - oggFilepath = os.path.join(Instance.instancePath, "output.ogg") #ogv - if (not os.path.exists(oggFilepath)): - self.record = False - self.ca.m.cannotSaveVideo() - self.ca.m.stoppedRecordingVideo() - return - oggSize = os.path.getsize(oggFilepath) - if (oggSize <= 0): - self.record = False - self.ca.m.cannotSaveVideo() - self.ca.m.stoppedRecordingVideo() - return - - line = 'filesrc location=' + str(oggFilepath) + ' name=thumbFilesrc ! oggdemux name=thumbOggdemux ! theoradec name=thumbTheoradec ! tee name=thumbTee ! queue name=thumbQueue ! ffmpegcolorspace name=thumbFfmpegcolorspace ! jpegenc name=thumbJPegenc ! fakesink name=thumbFakesink' - thumbline = gst.parse_launch(line) - thumbQueue = thumbline.get_by_name('thumbQueue') - thumbQueue.set_property("leaky", True) - thumbQueue.set_property("max-size-buffers", 1) - thumbTee = thumbline.get_by_name('thumbTee') - thumbFakesink = thumbline.get_by_name('thumbFakesink') - self.THUMB_HANDOFF_ID = thumbFakesink.connect("handoff", self.copyThumbPic) - thumbFakesink.set_property("signal-handoffs", True) - self.thumbPipes.append(thumbline) - self.thumbExposureOpen = True - gobject.idle_add( self.idlePlayElement, thumbline ) - - - def stoppedRecordingAudio( self ): - record.Record.log.debug("stoppedRecordingAudio") - if (self.audioPixbuf != None): - audioFilepath = os.path.join(Instance.instancePath, "output.wav")#self.el("audioFilesink").get_property("location") - if (not os.path.exists(audioFilepath)): - self.record = False - self.audio = False - self.ca.m.cannotSaveVideo() - return - wavSize = os.path.getsize(audioFilepath) - if (wavSize <= 0): - self.record = False - self.ca.m.cannotSaveVideo() - return - - self.ca.ui.setPostProcessPixBuf(self.audioPixbuf) - - line = 'filesrc location=' + str(audioFilepath) + ' name=audioFilesrc ! wavparse name=audioWavparse ! audioconvert name=audioAudioconvert ! vorbisenc name=audioVorbisenc ! oggmux name=audioOggmux ! filesink name=audioFilesink' - audioline = gst.parse_launch(line) - - taglist = self.getTags(Constants.TYPE_AUDIO) - base64AudioSnapshot = utils.getStringFromPixbuf(self.audioPixbuf) - taglist[gst.TAG_EXTENDED_COMMENT] = "coverart="+str(base64AudioSnapshot) - vorbisEnc = audioline.get_by_name('audioVorbisenc') - vorbisEnc.merge_tags(taglist, gst.TAG_MERGE_REPLACE_ALL) - - audioFilesink = audioline.get_by_name('audioFilesink') - audioOggFilepath = os.path.join(Instance.instancePath, "output.ogg") - audioFilesink.set_property("location", audioOggFilepath ) - - audioBus = audioline.get_bus() - audioBus.add_signal_watch() - self.AUDIO_TRANSCODE_ID = audioBus.connect('message', self._onMuxedAudioMessageCb, audioline) - self.TRANSCODE_ID = gobject.timeout_add(self.TRANSCODE_UPDATE_INTERVAL, self._transcodeUpdateCb, audioline) - gobject.idle_add( self.idlePlayElement, audioline ) - else: - self.record = False - self.audio = False - self.ca.m.cannotSaveVideo() - - - def getTags( self, type ): - tl = gst.TagList() - tl[gst.TAG_ARTIST] = str(Instance.nickName) - tl[gst.TAG_COMMENT] = "olpc" - #this is unfortunately, unreliable - #record.Record.log.debug("self.ca.metadata['title']->" + str(self.ca.metadata['title']) ) - tl[gst.TAG_ALBUM] = "olpc" #self.ca.metadata['title'] - tl[gst.TAG_DATE] = utils.getDateString(int(time.time())) - stringType = Constants.mediaTypes[type][Constants.keyIstr] - tl[gst.TAG_TITLE] = Constants.istrBy % {"1":stringType, "2":str(Instance.nickName)} - return tl - - def blockedCb(self, x, y, z): - pass - - def _takePhoto(self): - if self.picExposureOpen: - return - - self.picExposureOpen = True - pad = self.photobin.get_static_pad("sink") - pad.set_blocked_async(True, self.blockedCb, None) - self.pipeline.add(self.photobin) - self.photobin.set_state(gst.STATE_PLAYING) - self.pipeline.get_by_name("tee").link(self.photobin) - pad.set_blocked_async(False, self.blockedCb, None) - - def takePhoto(self): - self.photoMode = self.PHOTO_MODE_PHOTO - self._takePhoto() - - def copyPic(self, fsink, buffer, pad, user_data=None): - if not self.picExposureOpen: - return - - pad = self.photobin.get_static_pad("sink") - pad.set_blocked_async(True, self.blockedCb, None) - self.pipeline.get_by_name("tee").unlink(self.photobin) - self.pipeline.remove(self.photobin) - pad.set_blocked_async(False, self.blockedCb, None) - - self.picExposureOpen = False - pic = gtk.gdk.pixbuf_loader_new_with_mime_type("image/jpeg") - pic.write( buffer ) - pic.close() - pixBuf = pic.get_pixbuf() - del pic - - self.savePhoto( pixBuf ) - - - def savePhoto(self, pixbuf): - if self.photoMode == self.PHOTO_MODE_AUDIO: - self.audioPixbuf = pixbuf - else: - self.ca.m.savePhoto(pixbuf) - - - def startRecordingVideo(self): - self.record = True - self.audio = True - - # It would be nicer to connect the video/audio-recording elements - # without stopping the pipeline. However, that seems to cause a - # very long delay at the start of the video recording where the first - # frame is 'frozen' for several seconds. MikeS from #gstreamer - # suggested that the videorate element might not be receiving a - # "new segment" signal soon enough. - # - # Stopping the pipeline while we reshuffle neatly works around this - # with minimal user experience impact. - self.pipeline.set_state(gst.STATE_NULL) - self.pipeline.add(self.videobin) - self.pipeline.get_by_name("tee").link(self.videobin) - self.pipeline.add(self.audiobin) - self.pipeline.set_state(gst.STATE_PLAYING) - - def startRecordingAudio(self): - self.audioPixbuf = None - - self.photoMode = self.PHOTO_MODE_AUDIO - self._takePhoto() - - self.record = True - self.pipeline.add(self.audiobin) - self.audiobin.set_state(gst.STATE_PLAYING) - - def stopRecordingVideo(self): - # Similarly to as when we start recording, we also stop the pipeline - # while we are adjusting the pipeline to stop recording. If we do - # it on-the-fly, the following video live feed to the screen becomes - # several seconds delayed. Weird! - self._eos_cb = self.stopRecordingVideoEOS - self.pipeline.get_by_name('camsrc').send_event(gst.event_new_eos()) - self.audiobin.get_by_name('absrc').send_event(gst.event_new_eos()) - - def stopRecordingVideoEOS(self): - self.pipeline.set_state(gst.STATE_NULL) - self.pipeline.get_by_name("tee").unlink(self.videobin) - self.pipeline.remove(self.videobin) - self.pipeline.remove(self.audiobin) - self.pipeline.set_state(gst.STATE_PLAYING) - gobject.idle_add( self.stoppedRecordingVideo ) - - - def copyThumbPic(self, fsink, buffer, pad, user_data=None): - if (self.thumbExposureOpen): - self.thumbExposureOpen = False - pic = gtk.gdk.pixbuf_loader_new_with_mime_type("image/jpeg") - pic.write(buffer) - pic.close() - self.thumbBuf = pic.get_pixbuf() - del pic - self.thumbEl('thumbTee').unlink(self.thumbEl('thumbQueue')) - - oggFilepath = os.path.join(Instance.instancePath, "output.ogg") #ogv - if (self.audio): - self.ca.ui.setPostProcessPixBuf(self.thumbBuf) - - wavFilepath = os.path.join(Instance.instancePath, "output.wav") - muxFilepath = os.path.join(Instance.instancePath, "mux.ogg") #ogv - - muxline = gst.parse_launch('filesrc location=' + str(oggFilepath) + ' name=muxVideoFilesrc ! oggdemux name=muxOggdemux ! theoradec name=muxTheoradec ! theoraenc name=muxTheoraenc ! oggmux name=muxOggmux ! filesink location=' + str(muxFilepath) + ' name=muxFilesink filesrc location=' + str(wavFilepath) + ' name=muxAudioFilesrc ! wavparse name=muxWavparse ! audioconvert name=muxAudioconvert ! vorbisenc name=muxVorbisenc ! muxOggmux.') - taglist = self.getTags(Constants.TYPE_VIDEO) - vorbisEnc = muxline.get_by_name('muxVorbisenc') - vorbisEnc.merge_tags(taglist, gst.TAG_MERGE_REPLACE_ALL) - - muxBus = muxline.get_bus() - muxBus.add_signal_watch() - self.VIDEO_TRANSCODE_ID = muxBus.connect('message', self._onMuxedVideoMessageCb, muxline) - self.muxPipes.append(muxline) - #add a listener here to monitor % of transcoding... - self.TRANSCODE_ID = gobject.timeout_add(self.TRANSCODE_UPDATE_INTERVAL, self._transcodeUpdateCb, muxline) - muxline.set_state(gst.STATE_PLAYING) - else: - self.record = False - self.audio = False - self.ca.m.saveVideo(self.thumbBuf, str(oggFilepath), self.VIDEO_WIDTH_SMALL, self.VIDEO_HEIGHT_SMALL) - self.ca.m.stoppedRecordingVideo() - - - def _transcodeUpdateCb( self, pipe ): - position, duration = self.queryPosition( pipe ) - if position != gst.CLOCK_TIME_NONE: - value = position * 100.0 / duration - value = value/100.0 - self.ca.ui.progressWindow.updateProgress(value, Constants.istrSaving) - return True - - - def queryPosition( self, pipe ): - try: - position, format = pipe.query_position(gst.FORMAT_TIME) - except: - position = gst.CLOCK_TIME_NONE - - try: - duration, format = pipe.query_duration(gst.FORMAT_TIME) - except: - duration = gst.CLOCK_TIME_NONE - - return (position, duration) - - - def _onMuxedVideoMessageCb(self, bus, message, pipe): - t = message.type - if (t == gst.MESSAGE_EOS): - self.record = False - self.audio = False - gobject.source_remove(self.VIDEO_TRANSCODE_ID) - self.VIDEO_TRANSCODE_ID = 0 - gobject.source_remove(self.TRANSCODE_ID) - self.TRANSCODE_ID = 0 - pipe.set_state(gst.STATE_NULL) - pipe.get_bus().remove_signal_watch() - pipe.get_bus().disable_sync_message_emission() - - wavFilepath = os.path.join(Instance.instancePath, "output.wav") - oggFilepath = os.path.join(Instance.instancePath, "output.ogg") #ogv - muxFilepath = os.path.join(Instance.instancePath, "mux.ogg") #ogv - os.remove( wavFilepath ) - os.remove( oggFilepath ) - self.ca.m.saveVideo(self.thumbBuf, str(muxFilepath), self.VIDEO_WIDTH_SMALL, self.VIDEO_HEIGHT_SMALL) - self.ca.m.stoppedRecordingVideo() - return False - else: - return True - - - def _onMuxedAudioMessageCb(self, bus, message, pipe): - t = message.type - if (t == gst.MESSAGE_EOS): - record.Record.log.debug("audio gst.MESSAGE_EOS") - self.record = False - self.audio = False - gobject.source_remove(self.AUDIO_TRANSCODE_ID) - self.AUDIO_TRANSCODE_ID = 0 - gobject.source_remove(self.TRANSCODE_ID) - self.TRANSCODE_ID = 0 - pipe.set_state(gst.STATE_NULL) - pipe.get_bus().remove_signal_watch() - pipe.get_bus().disable_sync_message_emission() - - wavFilepath = os.path.join(Instance.instancePath, "output.wav") - oggFilepath = os.path.join(Instance.instancePath, "output.ogg") - os.remove( wavFilepath ) - self.ca.m.saveAudio(oggFilepath, self.audioPixbuf) - return False - else: - return True - - - def _onSyncMessageCb(self, bus, message): - if message.structure is None: - return - if message.structure.get_name() == 'prepare-xwindow-id': - self.window.set_sink(message.src) - message.src.set_property('force-aspect-ratio', True) - - - def _onMessageCb(self, bus, message): - t = message.type - if t == gst.MESSAGE_EOS: - if self._eos_cb: - cb = self._eos_cb - self._eos_cb = None - cb() - elif t == gst.MESSAGE_ERROR: - #todo: if we come out of suspend/resume with errors, then get us back up and running... - #todo: handle "No space left on the resource.gstfilesink.c" - #err, debug = message.parse_error() - pass - - def abandonMedia(self): - self.stop() - - if (self.AUDIO_TRANSCODE_ID != 0): - gobject.source_remove(self.AUDIO_TRANSCODE_ID) - self.AUDIO_TRANSCODE_ID = 0 - if (self.TRANSCODE_ID != 0): - gobject.source_remove(self.TRANSCODE_ID) - self.TRANSCODE_ID = 0 - if (self.VIDEO_TRANSCODE_ID != 0): - gobject.source_remove(self.VIDEO_TRANSCODE_ID) - self.VIDEO_TRANSCODE_ID = 0 - - wavFilepath = os.path.join(Instance.instancePath, "output.wav") - if (os.path.exists(wavFilepath)): - os.remove(wavFilepath) - oggFilepath = os.path.join(Instance.instancePath, "output.ogg") #ogv - if (os.path.exists(oggFilepath)): - os.remove(oggFilepath) - muxFilepath = os.path.join(Instance.instancePath, "mux.ogg") #ogv - if (os.path.exists(muxFilepath)): - os.remove(muxFilepath) + def stopRecordingAudio( self ): + self.audiobin.set_state(gst.STATE_NULL) + self.pipeline.remove(self.audiobin) + gobject.idle_add( self.stoppedRecordingAudio ) + + + def stoppedRecordingVideo(self): + if ( len(self.thumbPipes) > 0 ): + thumbline = self.thumbPipes[len(self.thumbPipes)-1] + thumbline.get_by_name('thumbFakesink').disconnect(self.THUMB_HANDOFF_ID) + + oggFilepath = os.path.join(Instance.instancePath, "output.ogg") #ogv + if (not os.path.exists(oggFilepath)): + self.record = False + self.ca.m.cannotSaveVideo() + self.ca.m.stoppedRecordingVideo() + return + oggSize = os.path.getsize(oggFilepath) + if (oggSize <= 0): + self.record = False + self.ca.m.cannotSaveVideo() + self.ca.m.stoppedRecordingVideo() + return + + line = 'filesrc location=' + str(oggFilepath) + ' name=thumbFilesrc ! oggdemux name=thumbOggdemux ! theoradec name=thumbTheoradec ! tee name=thumbTee ! queue name=thumbQueue ! ffmpegcolorspace name=thumbFfmpegcolorspace ! jpegenc name=thumbJPegenc ! fakesink name=thumbFakesink' + thumbline = gst.parse_launch(line) + thumbQueue = thumbline.get_by_name('thumbQueue') + thumbQueue.set_property("leaky", True) + thumbQueue.set_property("max-size-buffers", 1) + thumbTee = thumbline.get_by_name('thumbTee') + thumbFakesink = thumbline.get_by_name('thumbFakesink') + self.THUMB_HANDOFF_ID = thumbFakesink.connect("handoff", self.copyThumbPic) + thumbFakesink.set_property("signal-handoffs", True) + self.thumbPipes.append(thumbline) + self.thumbExposureOpen = True + gobject.idle_add( self.idlePlayElement, thumbline ) + + + def stoppedRecordingAudio( self ): + record.Record.log.debug("stoppedRecordingAudio") + if (self.audioPixbuf != None): + audioFilepath = os.path.join(Instance.instancePath, "output.wav")#self.el("audioFilesink").get_property("location") + if (not os.path.exists(audioFilepath)): + self.record = False + self.audio = False + self.ca.m.cannotSaveVideo() + return + wavSize = os.path.getsize(audioFilepath) + if (wavSize <= 0): + self.record = False + self.ca.m.cannotSaveVideo() + return + + self.ca.ui.setPostProcessPixBuf(self.audioPixbuf) + + line = 'filesrc location=' + str(audioFilepath) + ' name=audioFilesrc ! wavparse name=audioWavparse ! audioconvert name=audioAudioconvert ! vorbisenc name=audioVorbisenc ! oggmux name=audioOggmux ! filesink name=audioFilesink' + audioline = gst.parse_launch(line) + + taglist = self.getTags(Constants.TYPE_AUDIO) + base64AudioSnapshot = utils.getStringFromPixbuf(self.audioPixbuf) + taglist[gst.TAG_EXTENDED_COMMENT] = "coverart="+str(base64AudioSnapshot) + vorbisEnc = audioline.get_by_name('audioVorbisenc') + vorbisEnc.merge_tags(taglist, gst.TAG_MERGE_REPLACE_ALL) + + audioFilesink = audioline.get_by_name('audioFilesink') + audioOggFilepath = os.path.join(Instance.instancePath, "output.ogg") + audioFilesink.set_property("location", audioOggFilepath ) + + audioBus = audioline.get_bus() + audioBus.add_signal_watch() + self.AUDIO_TRANSCODE_ID = audioBus.connect('message', self._onMuxedAudioMessageCb, audioline) + self.TRANSCODE_ID = gobject.timeout_add(self.TRANSCODE_UPDATE_INTERVAL, self._transcodeUpdateCb, audioline) + gobject.idle_add( self.idlePlayElement, audioline ) + else: + self.record = False + self.audio = False + self.ca.m.cannotSaveVideo() + + + def getTags( self, type ): + tl = gst.TagList() + tl[gst.TAG_ARTIST] = str(Instance.nickName) + tl[gst.TAG_COMMENT] = "olpc" + #this is unfortunately, unreliable + #record.Record.log.debug("self.ca.metadata['title']->" + str(self.ca.metadata['title']) ) + tl[gst.TAG_ALBUM] = "olpc" #self.ca.metadata['title'] + tl[gst.TAG_DATE] = utils.getDateString(int(time.time())) + stringType = Constants.mediaTypes[type][Constants.keyIstr] + tl[gst.TAG_TITLE] = Constants.istrBy % {"1":stringType, "2":str(Instance.nickName)} + return tl + + def blockedCb(self, x, y, z): + pass + + def _takePhoto(self): + if self.picExposureOpen: + return + + self.picExposureOpen = True + pad = self.photobin.get_static_pad("sink") + pad.set_blocked_async(True, self.blockedCb, None) + self.pipeline.add(self.photobin) + self.photobin.set_state(gst.STATE_PLAYING) + self.pipeline.get_by_name("tee").link(self.photobin) + pad.set_blocked_async(False, self.blockedCb, None) + + def takePhoto(self): + self.photoMode = self.PHOTO_MODE_PHOTO + self._takePhoto() + + def copyPic(self, fsink, buffer, pad, user_data=None): + if not self.picExposureOpen: + return + + pad = self.photobin.get_static_pad("sink") + pad.set_blocked_async(True, self.blockedCb, None) + self.pipeline.get_by_name("tee").unlink(self.photobin) + self.pipeline.remove(self.photobin) + pad.set_blocked_async(False, self.blockedCb, None) + + self.picExposureOpen = False + pic = gtk.gdk.pixbuf_loader_new_with_mime_type("image/jpeg") + pic.write( buffer ) + pic.close() + pixBuf = pic.get_pixbuf() + del pic + + self.savePhoto( pixBuf ) + + + def savePhoto(self, pixbuf): + if self.photoMode == self.PHOTO_MODE_AUDIO: + self.audioPixbuf = pixbuf + else: + self.ca.m.savePhoto(pixbuf) + + + def startRecordingVideo(self): + self.record = True + self.audio = True + + # It would be nicer to connect the video/audio-recording elements + # without stopping the pipeline. However, that seems to cause a + # very long delay at the start of the video recording where the first + # frame is 'frozen' for several seconds. MikeS from #gstreamer + # suggested that the videorate element might not be receiving a + # "new segment" signal soon enough. + # + # Stopping the pipeline while we reshuffle neatly works around this + # with minimal user experience impact. + self.pipeline.set_state(gst.STATE_NULL) + self.pipeline.add(self.videobin) + self.pipeline.get_by_name("tee").link(self.videobin) + self.pipeline.add(self.audiobin) + self.pipeline.set_state(gst.STATE_PLAYING) + + def startRecordingAudio(self): + self.audioPixbuf = None + + self.photoMode = self.PHOTO_MODE_AUDIO + self._takePhoto() + + self.record = True + self.pipeline.add(self.audiobin) + self.audiobin.set_state(gst.STATE_PLAYING) + + def stopRecordingVideo(self): + # Similarly to as when we start recording, we also stop the pipeline + # while we are adjusting the pipeline to stop recording. If we do + # it on-the-fly, the following video live feed to the screen becomes + # several seconds delayed. Weird! + self._eos_cb = self.stopRecordingVideoEOS + self.pipeline.get_by_name('camsrc').send_event(gst.event_new_eos()) + self.audiobin.get_by_name('absrc').send_event(gst.event_new_eos()) + + def stopRecordingVideoEOS(self): + self.pipeline.set_state(gst.STATE_NULL) + self.pipeline.get_by_name("tee").unlink(self.videobin) + self.pipeline.remove(self.videobin) + self.pipeline.remove(self.audiobin) + self.pipeline.set_state(gst.STATE_PLAYING) + gobject.idle_add( self.stoppedRecordingVideo ) + + + def copyThumbPic(self, fsink, buffer, pad, user_data=None): + if (self.thumbExposureOpen): + self.thumbExposureOpen = False + pic = gtk.gdk.pixbuf_loader_new_with_mime_type("image/jpeg") + pic.write(buffer) + pic.close() + self.thumbBuf = pic.get_pixbuf() + del pic + self.thumbEl('thumbTee').unlink(self.thumbEl('thumbQueue')) + + oggFilepath = os.path.join(Instance.instancePath, "output.ogg") #ogv + if (self.audio): + self.ca.ui.setPostProcessPixBuf(self.thumbBuf) + + wavFilepath = os.path.join(Instance.instancePath, "output.wav") + muxFilepath = os.path.join(Instance.instancePath, "mux.ogg") #ogv + + muxline = gst.parse_launch('filesrc location=' + str(oggFilepath) + ' name=muxVideoFilesrc ! oggdemux name=muxOggdemux ! theoradec name=muxTheoradec ! theoraenc name=muxTheoraenc ! oggmux name=muxOggmux ! filesink location=' + str(muxFilepath) + ' name=muxFilesink filesrc location=' + str(wavFilepath) + ' name=muxAudioFilesrc ! wavparse name=muxWavparse ! audioconvert name=muxAudioconvert ! vorbisenc name=muxVorbisenc ! muxOggmux.') + taglist = self.getTags(Constants.TYPE_VIDEO) + vorbisEnc = muxline.get_by_name('muxVorbisenc') + vorbisEnc.merge_tags(taglist, gst.TAG_MERGE_REPLACE_ALL) + + muxBus = muxline.get_bus() + muxBus.add_signal_watch() + self.VIDEO_TRANSCODE_ID = muxBus.connect('message', self._onMuxedVideoMessageCb, muxline) + self.muxPipes.append(muxline) + #add a listener here to monitor % of transcoding... + self.TRANSCODE_ID = gobject.timeout_add(self.TRANSCODE_UPDATE_INTERVAL, self._transcodeUpdateCb, muxline) + muxline.set_state(gst.STATE_PLAYING) + else: + self.record = False + self.audio = False + self.ca.m.saveVideo(self.thumbBuf, str(oggFilepath), self.VIDEO_WIDTH_SMALL, self.VIDEO_HEIGHT_SMALL) + self.ca.m.stoppedRecordingVideo() + + + def _transcodeUpdateCb( self, pipe ): + position, duration = self.queryPosition( pipe ) + if position != gst.CLOCK_TIME_NONE: + value = position * 100.0 / duration + value = value/100.0 + self.ca.ui.progressWindow.updateProgress(value, Constants.istrSaving) + return True + + + def queryPosition( self, pipe ): + try: + position, format = pipe.query_position(gst.FORMAT_TIME) + except: + position = gst.CLOCK_TIME_NONE + + try: + duration, format = pipe.query_duration(gst.FORMAT_TIME) + except: + duration = gst.CLOCK_TIME_NONE + + return (position, duration) + + + def _onMuxedVideoMessageCb(self, bus, message, pipe): + t = message.type + if (t == gst.MESSAGE_EOS): + self.record = False + self.audio = False + gobject.source_remove(self.VIDEO_TRANSCODE_ID) + self.VIDEO_TRANSCODE_ID = 0 + gobject.source_remove(self.TRANSCODE_ID) + self.TRANSCODE_ID = 0 + pipe.set_state(gst.STATE_NULL) + pipe.get_bus().remove_signal_watch() + pipe.get_bus().disable_sync_message_emission() + + wavFilepath = os.path.join(Instance.instancePath, "output.wav") + oggFilepath = os.path.join(Instance.instancePath, "output.ogg") #ogv + muxFilepath = os.path.join(Instance.instancePath, "mux.ogg") #ogv + os.remove( wavFilepath ) + os.remove( oggFilepath ) + self.ca.m.saveVideo(self.thumbBuf, str(muxFilepath), self.VIDEO_WIDTH_SMALL, self.VIDEO_HEIGHT_SMALL) + self.ca.m.stoppedRecordingVideo() + return False + else: + return True + + + def _onMuxedAudioMessageCb(self, bus, message, pipe): + t = message.type + if (t == gst.MESSAGE_EOS): + record.Record.log.debug("audio gst.MESSAGE_EOS") + self.record = False + self.audio = False + gobject.source_remove(self.AUDIO_TRANSCODE_ID) + self.AUDIO_TRANSCODE_ID = 0 + gobject.source_remove(self.TRANSCODE_ID) + self.TRANSCODE_ID = 0 + pipe.set_state(gst.STATE_NULL) + pipe.get_bus().remove_signal_watch() + pipe.get_bus().disable_sync_message_emission() + + wavFilepath = os.path.join(Instance.instancePath, "output.wav") + oggFilepath = os.path.join(Instance.instancePath, "output.ogg") + os.remove( wavFilepath ) + self.ca.m.saveAudio(oggFilepath, self.audioPixbuf) + return False + else: + return True + + + def _onSyncMessageCb(self, bus, message): + if message.structure is None: + return + if message.structure.get_name() == 'prepare-xwindow-id': + self.window.set_sink(message.src) + message.src.set_property('force-aspect-ratio', True) + + + def _onMessageCb(self, bus, message): + t = message.type + if t == gst.MESSAGE_EOS: + if self._eos_cb: + cb = self._eos_cb + self._eos_cb = None + cb() + elif t == gst.MESSAGE_ERROR: + #todo: if we come out of suspend/resume with errors, then get us back up and running... + #todo: handle "No space left on the resource.gstfilesink.c" + #err, debug = message.parse_error() + pass + + def abandonMedia(self): + self.stop() + + if (self.AUDIO_TRANSCODE_ID != 0): + gobject.source_remove(self.AUDIO_TRANSCODE_ID) + self.AUDIO_TRANSCODE_ID = 0 + if (self.TRANSCODE_ID != 0): + gobject.source_remove(self.TRANSCODE_ID) + self.TRANSCODE_ID = 0 + if (self.VIDEO_TRANSCODE_ID != 0): + gobject.source_remove(self.VIDEO_TRANSCODE_ID) + self.VIDEO_TRANSCODE_ID = 0 + + wavFilepath = os.path.join(Instance.instancePath, "output.wav") + if (os.path.exists(wavFilepath)): + os.remove(wavFilepath) + oggFilepath = os.path.join(Instance.instancePath, "output.ogg") #ogv + if (os.path.exists(oggFilepath)): + os.remove(oggFilepath) + muxFilepath = os.path.join(Instance.instancePath, "mux.ogg") #ogv + if (os.path.exists(muxFilepath)): + os.remove(muxFilepath) class LiveVideoWindow(gtk.Window): - def __init__(self, bgd ): - gtk.Window.__init__(self) + def __init__(self, bgd ): + gtk.Window.__init__(self) - self.imagesink = None - self.glive = None + self.imagesink = None + self.glive = None - self.modify_bg( gtk.STATE_NORMAL, bgd ) - self.modify_bg( gtk.STATE_INSENSITIVE, bgd ) - self.unset_flags(gtk.DOUBLE_BUFFERED) - self.set_flags(gtk.APP_PAINTABLE) + self.modify_bg( gtk.STATE_NORMAL, bgd ) + self.modify_bg( gtk.STATE_INSENSITIVE, bgd ) + self.unset_flags(gtk.DOUBLE_BUFFERED) + self.set_flags(gtk.APP_PAINTABLE) - def set_glive(self, pglive): - self.glive = pglive - self.glive.window = self + def set_glive(self, pglive): + self.glive = pglive + self.glive.window = self - def set_sink(self, sink): - if (self.imagesink != None): - assert self.window.xid - self.imagesink = None - del self.imagesink + def set_sink(self, sink): + if (self.imagesink != None): + assert self.window.xid + self.imagesink = None + del self.imagesink - self.imagesink = sink - self.imagesink.set_xwindow_id(self.window.xid) + self.imagesink = sink + self.imagesink.set_xwindow_id(self.window.xid) diff --git a/glivex.py b/glivex.py index 5b8267f..7c2955d 100644 --- a/glivex.py +++ b/glivex.py @@ -48,100 +48,100 @@ import utils import ui class GliveX: - def __init__(self, pca): - self.window = None - self.ca = pca - - self.playing = False - - self.pipeline = gst.Pipeline("slow-pipeline") - self.createPipeline() - - bus = self.pipeline.get_bus() - bus.enable_sync_message_emission() - bus.add_signal_watch() - self.SYNC_ID = bus.connect('sync-message::element', self._onSyncMessageCb) - self.MESSAGE_ID = bus.connect('message', self._onMessageCb) - - def createPipeline ( self ): - src = gst.element_factory_make("v4l2src", "camsrc") - try: - # old gst-plugins-good does not have this property - src.set_property("queue-size", 2) - except: - pass - - queue = gst.element_factory_make("queue", "dispqueue") - queue.set_property("leaky", True) - queue.set_property('max-size-buffers', 1) - - scale = gst.element_factory_make("videoscale", "scale") - scalecaps = gst.Caps('video/x-raw-yuv,width='+str(ui.UI.dim_PIPW)+',height='+str(ui.UI.dim_PIPH)) - colorspace = gst.element_factory_make("ffmpegcolorspace", "colorspace") - xsink = gst.element_factory_make("ximagesink", "xsink") - self.pipeline.add(src, queue, scale, colorspace, xsink) - gst.element_link_many(src, queue, scale) - scale.link(colorspace, scalecaps) - colorspace.link(xsink) - - def play(self): - self.pipeline.set_state(gst.STATE_PLAYING) - self.playing = True - - def pause(self): - self.pipeline.set_state(gst.STATE_PAUSED) - self.playing = False - - def stop(self): - self.pipeline.set_state(gst.STATE_NULL) - self.playing = False - - def is_playing(self): - return self.playing - - def idlePlayElement(self, element): - element.set_state(gst.STATE_PLAYING) - return False - - def _onSyncMessageCb(self, bus, message): - if message.structure is None: - return - if message.structure.get_name() == 'prepare-xwindow-id': - self.window.set_sink(message.src) - message.src.set_property('force-aspect-ratio', True) - - def _onMessageCb(self, bus, message): - t = message.type - if t == gst.MESSAGE_EOS: - #print("MESSAGE_EOS") - pass - elif t == gst.MESSAGE_ERROR: - #todo: if we come out of suspend/resume with errors, then get us back up and running... - #todo: handle "No space left on the resource.gstfilesink.c" - #err, debug = message.parse_error() - pass + def __init__(self, pca): + self.window = None + self.ca = pca + + self.playing = False + + self.pipeline = gst.Pipeline("slow-pipeline") + self.createPipeline() + + bus = self.pipeline.get_bus() + bus.enable_sync_message_emission() + bus.add_signal_watch() + self.SYNC_ID = bus.connect('sync-message::element', self._onSyncMessageCb) + self.MESSAGE_ID = bus.connect('message', self._onMessageCb) + + def createPipeline ( self ): + src = gst.element_factory_make("v4l2src", "camsrc") + try: + # old gst-plugins-good does not have this property + src.set_property("queue-size", 2) + except: + pass + + queue = gst.element_factory_make("queue", "dispqueue") + queue.set_property("leaky", True) + queue.set_property('max-size-buffers', 1) + + scale = gst.element_factory_make("videoscale", "scale") + scalecaps = gst.Caps('video/x-raw-yuv,width='+str(ui.UI.dim_PIPW)+',height='+str(ui.UI.dim_PIPH)) + colorspace = gst.element_factory_make("ffmpegcolorspace", "colorspace") + xsink = gst.element_factory_make("ximagesink", "xsink") + self.pipeline.add(src, queue, scale, colorspace, xsink) + gst.element_link_many(src, queue, scale) + scale.link(colorspace, scalecaps) + colorspace.link(xsink) + + def play(self): + self.pipeline.set_state(gst.STATE_PLAYING) + self.playing = True + + def pause(self): + self.pipeline.set_state(gst.STATE_PAUSED) + self.playing = False + + def stop(self): + self.pipeline.set_state(gst.STATE_NULL) + self.playing = False + + def is_playing(self): + return self.playing + + def idlePlayElement(self, element): + element.set_state(gst.STATE_PLAYING) + return False + + def _onSyncMessageCb(self, bus, message): + if message.structure is None: + return + if message.structure.get_name() == 'prepare-xwindow-id': + self.window.set_sink(message.src) + message.src.set_property('force-aspect-ratio', True) + + def _onMessageCb(self, bus, message): + t = message.type + if t == gst.MESSAGE_EOS: + #print("MESSAGE_EOS") + pass + elif t == gst.MESSAGE_ERROR: + #todo: if we come out of suspend/resume with errors, then get us back up and running... + #todo: handle "No space left on the resource.gstfilesink.c" + #err, debug = message.parse_error() + pass class SlowLiveVideoWindow(gtk.Window): - def __init__(self, bgd ): - gtk.Window.__init__(self) + def __init__(self, bgd ): + gtk.Window.__init__(self) - self.imagesink = None - self.glivex = None + self.imagesink = None + self.glivex = None - self.modify_bg( gtk.STATE_NORMAL, bgd ) - self.modify_bg( gtk.STATE_INSENSITIVE, bgd ) - self.unset_flags(gtk.DOUBLE_BUFFERED) - self.set_flags(gtk.APP_PAINTABLE) + self.modify_bg( gtk.STATE_NORMAL, bgd ) + self.modify_bg( gtk.STATE_INSENSITIVE, bgd ) + self.unset_flags(gtk.DOUBLE_BUFFERED) + self.set_flags(gtk.APP_PAINTABLE) - def set_glivex(self, pglivex): - self.glivex = pglivex - self.glivex.window = self + def set_glivex(self, pglivex): + self.glivex = pglivex + self.glivex.window = self - def set_sink(self, sink): - if (self.imagesink != None): - assert self.window.xid - self.imagesink = None - del self.imagesink + def set_sink(self, sink): + if (self.imagesink != None): + assert self.window.xid + self.imagesink = None + del self.imagesink - self.imagesink = sink - self.imagesink.set_xwindow_id(self.window.xid) + self.imagesink = sink + self.imagesink.set_xwindow_id(self.window.xid) diff --git a/gplay.py b/gplay.py index e8572e0..b6cc7dd 100644 --- a/gplay.py +++ b/gplay.py @@ -36,119 +36,119 @@ import record class Gplay: - def __init__(self): - self.window = None - self.players = [] - self.playing = False - self.nextMovie() + def __init__(self): + self.window = None + self.players = [] + self.playing = False + self.nextMovie() - def nextMovie(self): - if ( len(self.players) > 0 ): - self.playing = False - self.getPlayer().set_property("video-sink", None) - self.getPlayer().get_bus().disconnect(self.SYNC_ID) - self.getPlayer().get_bus().remove_signal_watch() - self.getPlayer().get_bus().disable_sync_message_emission() + def nextMovie(self): + if ( len(self.players) > 0 ): + self.playing = False + self.getPlayer().set_property("video-sink", None) + self.getPlayer().get_bus().disconnect(self.SYNC_ID) + self.getPlayer().get_bus().remove_signal_watch() + self.getPlayer().get_bus().disable_sync_message_emission() - player = gst.element_factory_make("playbin", "playbin") - xis = gst.element_factory_make("xvimagesink", "xvimagesink") - player.set_property("video-sink", xis) - bus = player.get_bus() - bus.enable_sync_message_emission() - bus.add_signal_watch() - self.SYNC_ID = bus.connect('sync-message::element', self.onSyncMessage) - self.players.append(player) + player = gst.element_factory_make("playbin", "playbin") + xis = gst.element_factory_make("xvimagesink", "xvimagesink") + player.set_property("video-sink", xis) + bus = player.get_bus() + bus.enable_sync_message_emission() + bus.add_signal_watch() + self.SYNC_ID = bus.connect('sync-message::element', self.onSyncMessage) + self.players.append(player) - def getPlayer(self): - return self.players[len(self.players)-1] + def getPlayer(self): + return self.players[len(self.players)-1] - def onSyncMessage(self, bus, message): - if message.structure is None: - return True - if message.structure.get_name() == 'prepare-xwindow-id': - self.window.set_sink(message.src) - message.src.set_property('force-aspect-ratio', True) - return True + def onSyncMessage(self, bus, message): + if message.structure is None: + return True + if message.structure.get_name() == 'prepare-xwindow-id': + self.window.set_sink(message.src) + message.src.set_property('force-aspect-ratio', True) + return True - def setLocation(self, location): - if (self.getPlayer().get_property('uri') == location): - self.seek(gst.SECOND*0) - return + def setLocation(self, location): + if (self.getPlayer().get_property('uri') == location): + self.seek(gst.SECOND*0) + return - self.getPlayer().set_state(gst.STATE_READY) - self.getPlayer().set_property('uri', location) - ext = location[len(location)-3:] - record.Record.log.debug("setLocation: ext->"+str(ext)) - if (ext == "jpg"): - self.pause() + self.getPlayer().set_state(gst.STATE_READY) + self.getPlayer().set_property('uri', location) + ext = location[len(location)-3:] + record.Record.log.debug("setLocation: ext->"+str(ext)) + if (ext == "jpg"): + self.pause() - def queryPosition(self): - "Returns a (position, duration) tuple" - try: - position, format = self.getPlayer().query_position(gst.FORMAT_TIME) - except: - position = gst.CLOCK_TIME_NONE + def queryPosition(self): + "Returns a (position, duration) tuple" + try: + position, format = self.getPlayer().query_position(gst.FORMAT_TIME) + except: + position = gst.CLOCK_TIME_NONE - try: - duration, format = self.getPlayer().query_duration(gst.FORMAT_TIME) - except: - duration = gst.CLOCK_TIME_NONE + try: + duration, format = self.getPlayer().query_duration(gst.FORMAT_TIME) + except: + duration = gst.CLOCK_TIME_NONE - return (position, duration) + return (position, duration) - def seek(self, location): - event = gst.event_new_seek(1.0, gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE, gst.SEEK_TYPE_SET, location, gst.SEEK_TYPE_NONE, 0) - res = self.getPlayer().send_event(event) - if res: - self.getPlayer().set_new_stream_time(0L) + def seek(self, location): + event = gst.event_new_seek(1.0, gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE, gst.SEEK_TYPE_SET, location, gst.SEEK_TYPE_NONE, 0) + res = self.getPlayer().send_event(event) + if res: + self.getPlayer().set_new_stream_time(0L) - def pause(self): - self.playing = False - self.getPlayer().set_state(gst.STATE_PAUSED) + def pause(self): + self.playing = False + self.getPlayer().set_state(gst.STATE_PAUSED) - def play(self): - self.playing = True - self.getPlayer().set_state(gst.STATE_PLAYING) + def play(self): + self.playing = True + self.getPlayer().set_state(gst.STATE_PLAYING) - def stop(self): - self.playing = False - self.getPlayer().set_state(gst.STATE_NULL) - self.nextMovie() + def stop(self): + self.playing = False + self.getPlayer().set_state(gst.STATE_NULL) + self.nextMovie() - def get_state(self, timeout=1): - return self.getPlayer().get_state(timeout=timeout) + def get_state(self, timeout=1): + return self.getPlayer().get_state(timeout=timeout) - def is_playing(self): - return self.playing + def is_playing(self): + return self.playing class PlayVideoWindow(gtk.Window): - def __init__(self, bgd): - gtk.Window.__init__(self) + def __init__(self, bgd): + gtk.Window.__init__(self) - self.imagesink = None + self.imagesink = None - self.modify_bg( gtk.STATE_NORMAL, bgd ) - self.modify_bg( gtk.STATE_INSENSITIVE, bgd ) - self.unset_flags(gtk.DOUBLE_BUFFERED) - self.set_flags(gtk.APP_PAINTABLE) + self.modify_bg( gtk.STATE_NORMAL, bgd ) + self.modify_bg( gtk.STATE_INSENSITIVE, bgd ) + self.unset_flags(gtk.DOUBLE_BUFFERED) + self.set_flags(gtk.APP_PAINTABLE) - def set_sink(self, sink): - if (self.imagesink != None): - assert self.window.xid - self.imagesink = None - del self.imagesink + def set_sink(self, sink): + if (self.imagesink != None): + assert self.window.xid + self.imagesink = None + del self.imagesink - self.imagesink = sink - self.imagesink.set_xwindow_id(self.window.xid) \ No newline at end of file + self.imagesink = sink + self.imagesink.set_xwindow_id(self.window.xid) \ No newline at end of file diff --git a/greplay.py b/greplay.py index a2b763b..67758a1 100644 --- a/greplay.py +++ b/greplay.py @@ -30,51 +30,51 @@ import utils class Greplay(gobject.GObject): - __gsignals__ = { - 'coverart-found': - (gobject.SIGNAL_RUN_FIRST, None, [object]) - } + __gsignals__ = { + 'coverart-found': + (gobject.SIGNAL_RUN_FIRST, None, [object]) + } - def findAlbumArt( self, path ): - record.Record.log.debug("getAlbumArt") - if (path == None): - record.Record.log.debug("getAlbumArt: path==None") - self.emit('coverart-found', None) - return - if (not os.path.exists(path)): - record.Record.log.debug("getAlbumArt: path doesn't exist") - self.emit('coverart-found', None) - return + def findAlbumArt( self, path ): + record.Record.log.debug("getAlbumArt") + if (path == None): + record.Record.log.debug("getAlbumArt: path==None") + self.emit('coverart-found', None) + return + if (not os.path.exists(path)): + record.Record.log.debug("getAlbumArt: path doesn't exist") + self.emit('coverart-found', None) + return - self.pp = gst.parse_launch("filesrc location="+str(path)+" ! oggdemux ! vorbisdec ! fakesink") - self.pp.get_bus().add_signal_watch() - self.pp.get_bus().connect("message", self._onMessageCb) - self.pp.set_state(gst.STATE_PLAYING) + self.pp = gst.parse_launch("filesrc location="+str(path)+" ! oggdemux ! vorbisdec ! fakesink") + self.pp.get_bus().add_signal_watch() + self.pp.get_bus().connect("message", self._onMessageCb) + self.pp.set_state(gst.STATE_PLAYING) - def _onMessageCb(self, bus, message): - t = message.type - if t == gst.MESSAGE_EOS: - record.Record.log.debug("Greplay:MESSAGE_EOS") - self.emit('coverart-found', None) - self.pp.set_state(gst.STATE_NULL) - return False - elif t == gst.MESSAGE_ERROR: - record.Record.log.debug("Greplay:MESSAGE_ERROR") - self.emit('coverart-found', None) - self.pp.set_state(gst.STATE_NULL) - return False - elif t == gst.MESSAGE_TAG: - tags = message.parse_tag() - for tag in tags.keys(): - if (str(tag) == "extended-comment"): - record.Record.log.debug("Found the tag!") - #todo, check for tagname - base64imgString = str(tags[tag])[len("coverart="):] + def _onMessageCb(self, bus, message): + t = message.type + if t == gst.MESSAGE_EOS: + record.Record.log.debug("Greplay:MESSAGE_EOS") + self.emit('coverart-found', None) + self.pp.set_state(gst.STATE_NULL) + return False + elif t == gst.MESSAGE_ERROR: + record.Record.log.debug("Greplay:MESSAGE_ERROR") + self.emit('coverart-found', None) + self.pp.set_state(gst.STATE_NULL) + return False + elif t == gst.MESSAGE_TAG: + tags = message.parse_tag() + for tag in tags.keys(): + if (str(tag) == "extended-comment"): + record.Record.log.debug("Found the tag!") + #todo, check for tagname + base64imgString = str(tags[tag])[len("coverart="):] - pixbuf = utils.getPixbufFromString(base64imgString) - self.pp.set_state(gst.STATE_NULL) - self.emit('coverart-found', pixbuf) - return False - return True + pixbuf = utils.getPixbufFromString(base64imgString) + self.pp.set_state(gst.STATE_NULL) + self.emit('coverart-found', pixbuf) + return False + return True diff --git a/instance.py b/instance.py index 1ab5407..d0178df 100644 --- a/instance.py +++ b/instance.py @@ -9,41 +9,41 @@ from color import Color import record class Instance: - key = profile.get_pubkey() - if hasattr(util, '_sha_data'): - # sugar-0.82 and previous - keyHash = util._sha_data(key) - else: - keyHash = util.sha_data(key) + key = profile.get_pubkey() + if hasattr(util, '_sha_data'): + # sugar-0.82 and previous + keyHash = util._sha_data(key) + else: + keyHash = util.sha_data(key) - keyHashPrintable = util.printable_hash(keyHash) - nickName = profile.get_nick_name() + keyHashPrintable = util.printable_hash(keyHash) + nickName = profile.get_nick_name() - colorFill = Color() - colorFill.init_hex( profile.get_color().get_fill_color() ) - colorStroke = Color() - colorStroke.init_hex( profile.get_color().get_stroke_color() ) + colorFill = Color() + colorFill.init_hex( profile.get_color().get_fill_color() ) + colorStroke = Color() + colorStroke.init_hex( profile.get_color().get_stroke_color() ) - instanceId = None - instancePath = None - dataPath = None + instanceId = None + instancePath = None + dataPath = None - def __init__(self, ca): - self.__class__.instanceId = ca._activity_id + def __init__(self, ca): + self.__class__.instanceId = ca._activity_id - self.__class__.instancePath = os.path.join(ca.get_activity_root(), "instance") - recreateTmp() + self.__class__.instancePath = os.path.join(ca.get_activity_root(), "instance") + recreateTmp() - self.__class__.dataPath = os.path.join(ca.get_activity_root(), "data") - recreateData() + self.__class__.dataPath = os.path.join(ca.get_activity_root(), "data") + recreateData() def recreateTmp(): - if (not os.path.exists(Instance.instancePath)): - os.makedirs(Instance.instancePath) + if (not os.path.exists(Instance.instancePath)): + os.makedirs(Instance.instancePath) def recreateData(): - if (not os.path.exists(Instance.dataPath)): - os.makedirs(Instance.dataPath) + if (not os.path.exists(Instance.dataPath)): + os.makedirs(Instance.dataPath) diff --git a/model.py b/model.py index 15c4553..2eb0b1d 100644 --- a/model.py +++ b/model.py @@ -50,410 +50,410 @@ import serialize class Model: - def __init__( self, pca ): - self.ca = pca - self.MODE = Constants.MODE_PHOTO - self.UPDATING = True - self.RECORDING = False - self.FULL = self._isXoFull() + def __init__( self, pca ): + self.ca = pca + self.MODE = Constants.MODE_PHOTO + self.UPDATING = True + self.RECORDING = False + self.FULL = self._isXoFull() - self.mediaHashs = {} - for key,value in Constants.mediaTypes.items(): - self.mediaHashs[key] = [] + self.mediaHashs = {} + for key,value in Constants.mediaTypes.items(): + self.mediaHashs[key] = [] - def updateXoFullStatus( self ): - self.FULL = self._isXoFull() + def updateXoFullStatus( self ): + self.FULL = self._isXoFull() - - def _isXoFull( self ): - full = False - if (utils.getFreespaceKb() <= Constants.keepFreeKbOnXo): - full = True - - return full - - - def getRecdByMd5( self, md5 ): - for mh in range (0, len(self.mediaHashs)): - for r in range (0, len(self.mediaHashs[mh])): - recd = self.mediaHashs[mh][r] - if (recd.thumbMd5 == md5): - return recd - elif (recd.mediaMd5 == md5): - return recd - - return None - - - def isVideoMode( self ): - return self.MODE == Constants.MODE_VIDEO - - - def isPhotoMode( self ): - return self.MODE == Constants.MODE_PHOTO - - - def displayThumb( self, recd, forceUpdating ): - #to avoid Xlib: unexpected async reply error when taking a picture on a gst callback, always call with idle_add - #this happens b/c this might get called from a gstreamer callback - if (not recd.type == self.MODE): - return - - if (forceUpdating): - self.setUpdating( True ) - hash = self.mediaHashs[recd.type] - if (len(hash) > 0): - self.ca.ui.addThumb(recd, forceUpdating) - if (forceUpdating): - self.setUpdating( False ) - - - def setupMode( self, type, update ): - if (not type == self.MODE): - return - - self.setUpdating( True ) - self.ca.ui.removeThumbs() - hash = self.mediaHashs[type] - for i in range (0, len(hash)): - self.ca.ui.addThumb( hash[i], True ) - if (update): - self.ca.ui.updateModeChange() - self.setUpdating(False) - - - def showNextThumb( self, shownRecd ): - if (shownRecd == None): - self.showLastThumb() - else: - hash = self.mediaHashs[self.MODE] - if (len(hash) > 0): - hash = self.mediaHashs[self.MODE] - i = operator.indexOf( hash, shownRecd ) - i = i+1 - if (i>=len(hash)): - i = 0 - self.ca.ui.showThumbSelection( hash[i] ) + + def _isXoFull( self ): + full = False + if (utils.getFreespaceKb() <= Constants.keepFreeKbOnXo): + full = True + + return full + + + def getRecdByMd5( self, md5 ): + for mh in range (0, len(self.mediaHashs)): + for r in range (0, len(self.mediaHashs[mh])): + recd = self.mediaHashs[mh][r] + if (recd.thumbMd5 == md5): + return recd + elif (recd.mediaMd5 == md5): + return recd + + return None + + + def isVideoMode( self ): + return self.MODE == Constants.MODE_VIDEO + + + def isPhotoMode( self ): + return self.MODE == Constants.MODE_PHOTO + + + def displayThumb( self, recd, forceUpdating ): + #to avoid Xlib: unexpected async reply error when taking a picture on a gst callback, always call with idle_add + #this happens b/c this might get called from a gstreamer callback + if (not recd.type == self.MODE): + return + + if (forceUpdating): + self.setUpdating( True ) + hash = self.mediaHashs[recd.type] + if (len(hash) > 0): + self.ca.ui.addThumb(recd, forceUpdating) + if (forceUpdating): + self.setUpdating( False ) + + + def setupMode( self, type, update ): + if (not type == self.MODE): + return + + self.setUpdating( True ) + self.ca.ui.removeThumbs() + hash = self.mediaHashs[type] + for i in range (0, len(hash)): + self.ca.ui.addThumb( hash[i], True ) + if (update): + self.ca.ui.updateModeChange() + self.setUpdating(False) + + + def showNextThumb( self, shownRecd ): + if (shownRecd == None): + self.showLastThumb() + else: + hash = self.mediaHashs[self.MODE] + if (len(hash) > 0): + hash = self.mediaHashs[self.MODE] + i = operator.indexOf( hash, shownRecd ) + i = i+1 + if (i>=len(hash)): + i = 0 + self.ca.ui.showThumbSelection( hash[i] ) - def showPrevThumb( self, shownRecd ): - if (shownRecd == None): - self.showLastThumb() - else: - hash = self.mediaHashs[self.MODE] - if (len(hash) > 0): - hash = self.mediaHashs[self.MODE] - i = operator.indexOf( hash, shownRecd ) - i = i-1 - if (i<0): - i = len(hash)-1 - self.ca.ui.showThumbSelection( hash[i] ) + def showPrevThumb( self, shownRecd ): + if (shownRecd == None): + self.showLastThumb() + else: + hash = self.mediaHashs[self.MODE] + if (len(hash) > 0): + hash = self.mediaHashs[self.MODE] + i = operator.indexOf( hash, shownRecd ) + i = i-1 + if (i<0): + i = len(hash)-1 + self.ca.ui.showThumbSelection( hash[i] ) - def showLastThumb( self ): - hash = self.mediaHashs[self.MODE] - if (len(hash) > 0): - self.ca.ui.showThumbSelection( hash[len(hash)-1] ) + def showLastThumb( self ): + hash = self.mediaHashs[self.MODE] + if (len(hash) > 0): + self.ca.ui.showThumbSelection( hash[len(hash)-1] ) - def doShutter( self ): - if (self.UPDATING): - return + def doShutter( self ): + if (self.UPDATING): + return - if (self.MODE == Constants.MODE_PHOTO): - self.startTakingPhoto() - elif (self.MODE == Constants.MODE_VIDEO): - if (not self.RECORDING): - self.startRecordingVideo() - else: - #post-processing begins now, so queue up this gfx - self.ca.ui.showPostProcessGfx(True) - self.stopRecordingVideo() - elif (self.MODE == Constants.MODE_AUDIO): - if (not self.RECORDING): - self.startRecordingAudio() - else: - #post-processing begins now, so queue up this gfx - self.ca.ui.showPostProcessGfx(True) - self.stopRecordingAudio() - - - def stopRecordingAudio( self ): - gobject.source_remove( self.ca.ui.UPDATE_DURATION_ID ) - self.ca.ui.progressWindow.updateProgress( 0, "" ) - self.setUpdating( True ) - self.setRecording( False ) - self.ca.ui.TRANSCODING = True - self.ca.ui.FULLSCREEN = False - self.ca.ui.updateVideoComponents() + if (self.MODE == Constants.MODE_PHOTO): + self.startTakingPhoto() + elif (self.MODE == Constants.MODE_VIDEO): + if (not self.RECORDING): + self.startRecordingVideo() + else: + #post-processing begins now, so queue up this gfx + self.ca.ui.showPostProcessGfx(True) + self.stopRecordingVideo() + elif (self.MODE == Constants.MODE_AUDIO): + if (not self.RECORDING): + self.startRecordingAudio() + else: + #post-processing begins now, so queue up this gfx + self.ca.ui.showPostProcessGfx(True) + self.stopRecordingAudio() + + + def stopRecordingAudio( self ): + gobject.source_remove( self.ca.ui.UPDATE_DURATION_ID ) + self.ca.ui.progressWindow.updateProgress( 0, "" ) + self.setUpdating( True ) + self.setRecording( False ) + self.ca.ui.TRANSCODING = True + self.ca.ui.FULLSCREEN = False + self.ca.ui.updateVideoComponents() - self.ca.glive.stopRecordingAudio( ) + self.ca.glive.stopRecordingAudio( ) - def saveAudio( self, tmpPath, pixbuf ): - self.setUpdating( True ) - - recd = self.createNewRecorded( Constants.TYPE_AUDIO ) - os.rename( tmpPath, os.path.join(Instance.instancePath,recd.mediaFilename)) - - thumbPath = os.path.join(Instance.instancePath, recd.thumbFilename) - scale = float((UI.dim_THUMB_WIDTH+0.0)/(pixbuf.get_width()+0.0)) - thumbImg = utils.generateThumbnail(pixbuf, scale, UI.dim_THUMB_WIDTH, UI.dim_THUMB_HEIGHT) - thumbImg.write_to_png(thumbPath) - - imagePath = os.path.join(Instance.instancePath, "audioPicture.png") - imagePath = utils.getUniqueFilepath( imagePath, 0 ) - pixbuf.save( imagePath, "png", {} ) - recd.audioImageFilename = os.path.basename(imagePath) - - #at this point, we have both audio and thumb sapath, so we can save the recd - self.createNewRecordedMd5Sums( recd ) - - audioHash = self.mediaHashs[Constants.TYPE_AUDIO] - audioHash.append( recd ) - gobject.idle_add(self.displayThumb, recd, True) - self.doPostSaveVideo() - self.meshShareRecd( recd ) + def saveAudio( self, tmpPath, pixbuf ): + self.setUpdating( True ) + + recd = self.createNewRecorded( Constants.TYPE_AUDIO ) + os.rename( tmpPath, os.path.join(Instance.instancePath,recd.mediaFilename)) + + thumbPath = os.path.join(Instance.instancePath, recd.thumbFilename) + scale = float((UI.dim_THUMB_WIDTH+0.0)/(pixbuf.get_width()+0.0)) + thumbImg = utils.generateThumbnail(pixbuf, scale, UI.dim_THUMB_WIDTH, UI.dim_THUMB_HEIGHT) + thumbImg.write_to_png(thumbPath) + + imagePath = os.path.join(Instance.instancePath, "audioPicture.png") + imagePath = utils.getUniqueFilepath( imagePath, 0 ) + pixbuf.save( imagePath, "png", {} ) + recd.audioImageFilename = os.path.basename(imagePath) + + #at this point, we have both audio and thumb sapath, so we can save the recd + self.createNewRecordedMd5Sums( recd ) + + audioHash = self.mediaHashs[Constants.TYPE_AUDIO] + audioHash.append( recd ) + gobject.idle_add(self.displayThumb, recd, True) + self.doPostSaveVideo() + self.meshShareRecd( recd ) - def startRecordingVideo( self ): - self.setUpdating( True ) - self.setRecording( True ) - #let the red eye kick in before we start the video underway - gobject.idle_add( self.beginRecordingVideo ) + def startRecordingVideo( self ): + self.setUpdating( True ) + self.setRecording( True ) + #let the red eye kick in before we start the video underway + gobject.idle_add( self.beginRecordingVideo ) - def beginRecordingVideo( self ): - self.ca.ui.recordVideo() - self.setUpdating( False ) + def beginRecordingVideo( self ): + self.ca.ui.recordVideo() + self.setUpdating( False ) - def startRecordingAudio( self ): - self.setUpdating( True ) - self.setRecording( True ) - self.ca.ui.recordAudio() - self.setUpdating( False ) + def startRecordingAudio( self ): + self.setUpdating( True ) + self.setRecording( True ) + self.ca.ui.recordAudio() + self.setUpdating( False ) - def setUpdating( self, upd ): - self.UPDATING = upd - self.ca.ui.updateButtonSensitivities() + def setUpdating( self, upd ): + self.UPDATING = upd + self.ca.ui.updateButtonSensitivities() - def setRecording( self, rec ): - self.RECORDING = rec - self.ca.ui.updateButtonSensitivities() + def setRecording( self, rec ): + self.RECORDING = rec + self.ca.ui.updateButtonSensitivities() - def stopRecordingVideo( self ): - self.ca.glive.stopRecordingVideo() - gobject.source_remove( self.ca.ui.UPDATE_DURATION_ID ) - self.ca.ui.progressWindow.updateProgress( 0, "" ) - self.setUpdating( True ) - self.setRecording( False ) - self.ca.ui.TRANSCODING = True - self.ca.ui.FULLSCREEN = False - self.ca.ui.updateVideoComponents() + def stopRecordingVideo( self ): + self.ca.glive.stopRecordingVideo() + gobject.source_remove( self.ca.ui.UPDATE_DURATION_ID ) + self.ca.ui.progressWindow.updateProgress( 0, "" ) + self.setUpdating( True ) + self.setRecording( False ) + self.ca.ui.TRANSCODING = True + self.ca.ui.FULLSCREEN = False + self.ca.ui.updateVideoComponents() - def saveVideo( self, pixbuf, tmpPath, wid, hit ): - recd = self.createNewRecorded( Constants.TYPE_VIDEO ) - os.rename( tmpPath, os.path.join(Instance.instancePath,recd.mediaFilename)) + def saveVideo( self, pixbuf, tmpPath, wid, hit ): + recd = self.createNewRecorded( Constants.TYPE_VIDEO ) + os.rename( tmpPath, os.path.join(Instance.instancePath,recd.mediaFilename)) - thumbPath = os.path.join(Instance.instancePath, recd.thumbFilename) - scale = float((UI.dim_THUMB_WIDTH+0.0)/(wid+0.0)) - thumbImg = utils.generateThumbnail(pixbuf, scale, UI.dim_THUMB_WIDTH, UI.dim_THUMB_HEIGHT) - thumbImg.write_to_png(thumbPath) + thumbPath = os.path.join(Instance.instancePath, recd.thumbFilename) + scale = float((UI.dim_THUMB_WIDTH+0.0)/(wid+0.0)) + thumbImg = utils.generateThumbnail(pixbuf, scale, UI.dim_THUMB_WIDTH, UI.dim_THUMB_HEIGHT) + thumbImg.write_to_png(thumbPath) - self.createNewRecordedMd5Sums( recd ) + self.createNewRecordedMd5Sums( recd ) - videoHash = self.mediaHashs[Constants.TYPE_VIDEO] - videoHash.append( recd ) - self.doPostSaveVideo() - gobject.idle_add(self.displayThumb, recd, True) - self.meshShareRecd( recd ) + videoHash = self.mediaHashs[Constants.TYPE_VIDEO] + videoHash.append( recd ) + self.doPostSaveVideo() + gobject.idle_add(self.displayThumb, recd, True) + self.meshShareRecd( recd ) - def meshShareRecd( self, recd ): - record.Record.log.debug('meshShareRecd') - #hey, i just took a cool video.audio.photo! let me show you! - if (self.ca.recTube != None): - recdXml = serialize.getRecdXmlMeshString(recd) - self.ca.recTube.notifyBudsOfNewRecd( Instance.keyHashPrintable, recdXml ) + def meshShareRecd( self, recd ): + record.Record.log.debug('meshShareRecd') + #hey, i just took a cool video.audio.photo! let me show you! + if (self.ca.recTube != None): + recdXml = serialize.getRecdXmlMeshString(recd) + self.ca.recTube.notifyBudsOfNewRecd( Instance.keyHashPrintable, recdXml ) - def cannotSaveVideo( self ): - self.doPostSaveVideo() + def cannotSaveVideo( self ): + self.doPostSaveVideo() - def doPostSaveVideo( self ): - self.ca.ui.showPostProcessGfx(False) + def doPostSaveVideo( self ): + self.ca.ui.showPostProcessGfx(False) - #prep the ui for your return - self.ca.ui.LAST_MODE = -1 - self.ca.ui.TRANSCODING = False + #prep the ui for your return + self.ca.ui.LAST_MODE = -1 + self.ca.ui.TRANSCODING = False - #resume live video from the camera (if the activity is active) - if (self.ca.ui.ACTIVE): - self.ca.ui.updateVideoComponents() + #resume live video from the camera (if the activity is active) + if (self.ca.ui.ACTIVE): + self.ca.ui.updateVideoComponents() - self.ca.ui.progressWindow.updateProgress( 0, "" ) - self.setRecording( False ) - self.setUpdating( False ) + self.ca.ui.progressWindow.updateProgress( 0, "" ) + self.setRecording( False ) + self.setUpdating( False ) - def abandonRecording( self ): + def abandonRecording( self ): - self.ca.ui.LAST_MODE = -1 - self.ca.ui.TRANSCODING = False - self.ca.ui.completeTimer() - self.ca.ui.completeCountdown() - self.setRecording(False) + self.ca.ui.LAST_MODE = -1 + self.ca.ui.TRANSCODING = False + self.ca.ui.completeTimer() + self.ca.ui.completeCountdown() + self.setRecording(False) - self.ca.ui.progressWindow.updateProgress( 0, "" ) + self.ca.ui.progressWindow.updateProgress( 0, "" ) - self.ca.glive.abandonMedia() + self.ca.glive.abandonMedia() - def stoppedRecordingVideo( self ): - self.setUpdating( False ) + def stoppedRecordingVideo( self ): + self.setUpdating( False ) - def startTakingPhoto( self ): - self.setUpdating( True ) - self.ca.glive.takePhoto() + def startTakingPhoto( self ): + self.setUpdating( True ) + self.ca.glive.takePhoto() - def savePhoto( self, pixbuf ): - recd = self.createNewRecorded( Constants.TYPE_PHOTO ) + def savePhoto( self, pixbuf ): + recd = self.createNewRecorded( Constants.TYPE_PHOTO ) - imgpath = os.path.join(Instance.instancePath, recd.mediaFilename) - pixbuf.save( imgpath, "jpeg" ) + imgpath = os.path.join(Instance.instancePath, recd.mediaFilename) + pixbuf.save( imgpath, "jpeg" ) - thumbpath = os.path.join(Instance.instancePath, recd.thumbFilename) - scale = float((UI.dim_THUMB_WIDTH+0.0)/(pixbuf.get_width()+0.0)) - thumbImg = utils.generateThumbnail(pixbuf, scale, UI.dim_THUMB_WIDTH, UI.dim_THUMB_HEIGHT) - thumbImg.write_to_png(thumbpath) - gc.collect() - #now that we've saved both the image and its pixbuf, we get their md5s - self.createNewRecordedMd5Sums( recd ) + thumbpath = os.path.join(Instance.instancePath, recd.thumbFilename) + scale = float((UI.dim_THUMB_WIDTH+0.0)/(pixbuf.get_width()+0.0)) + thumbImg = utils.generateThumbnail(pixbuf, scale, UI.dim_THUMB_WIDTH, UI.dim_THUMB_HEIGHT) + thumbImg.write_to_png(thumbpath) + gc.collect() + #now that we've saved both the image and its pixbuf, we get their md5s + self.createNewRecordedMd5Sums( recd ) - photoHash = self.mediaHashs[Constants.TYPE_PHOTO] - photoHash.append( recd ) - gobject.idle_add(self.displayThumb, recd, True) + photoHash = self.mediaHashs[Constants.TYPE_PHOTO] + photoHash.append( recd ) + gobject.idle_add(self.displayThumb, recd, True) - self.meshShareRecd( recd ) + self.meshShareRecd( recd ) - def addMeshRecd( self, recd ): - #todo: sort on time-taken, not on their arrival time over the mesh (?) - self.mediaHashs[recd.type].append( recd ) + def addMeshRecd( self, recd ): + #todo: sort on time-taken, not on their arrival time over the mesh (?) + self.mediaHashs[recd.type].append( recd ) - #updateUi, but don't lock up the buttons if they're recording or whatever - gobject.idle_add(self.displayThumb, recd, False) + #updateUi, but don't lock up the buttons if they're recording or whatever + gobject.idle_add(self.displayThumb, recd, False) - def createNewRecorded( self, type ): - recd = Recorded( ) + def createNewRecorded( self, type ): + recd = Recorded( ) - recd.recorderName = Instance.nickName - recd.recorderHash = Instance.keyHashPrintable + recd.recorderName = Instance.nickName + recd.recorderHash = Instance.keyHashPrintable - #to create a file, use the hardware_id+time *and* check if available or not - nowtime = int(time.time()) - recd.time = nowtime - recd.type = type + #to create a file, use the hardware_id+time *and* check if available or not + nowtime = int(time.time()) + recd.time = nowtime + recd.type = type - mediaThumbFilename = str(recd.recorderHash) + "_" + str(recd.time) - mediaFilename = mediaThumbFilename - mediaFilename = mediaFilename + "." + Constants.mediaTypes[type][Constants.keyExt] - mediaFilepath = os.path.join( Instance.instancePath, mediaFilename ) - mediaFilepath = utils.getUniqueFilepath( mediaFilepath, 0 ) - recd.mediaFilename = os.path.basename( mediaFilepath ) + mediaThumbFilename = str(recd.recorderHash) + "_" + str(recd.time) + mediaFilename = mediaThumbFilename + mediaFilename = mediaFilename + "." + Constants.mediaTypes[type][Constants.keyExt] + mediaFilepath = os.path.join( Instance.instancePath, mediaFilename ) + mediaFilepath = utils.getUniqueFilepath( mediaFilepath, 0 ) + recd.mediaFilename = os.path.basename( mediaFilepath ) - thumbFilename = mediaThumbFilename + "_thumb.jpg" - thumbFilepath = os.path.join( Instance.instancePath, thumbFilename ) - thumbFilepath = utils.getUniqueFilepath( thumbFilepath, 0 ) - recd.thumbFilename = os.path.basename( thumbFilepath ) + thumbFilename = mediaThumbFilename + "_thumb.jpg" + thumbFilepath = os.path.join( Instance.instancePath, thumbFilename ) + thumbFilepath = utils.getUniqueFilepath( thumbFilepath, 0 ) + recd.thumbFilename = os.path.basename( thumbFilepath ) - stringType = Constants.mediaTypes[type][Constants.keyIstr] - recd.title = Constants.istrBy % {"1":stringType, "2":str(recd.recorderName)} + stringType = Constants.mediaTypes[type][Constants.keyIstr] + recd.title = Constants.istrBy % {"1":stringType, "2":str(recd.recorderName)} - recd.colorStroke = Instance.colorStroke - recd.colorFill = Instance.colorFill + recd.colorStroke = Instance.colorStroke + recd.colorFill = Instance.colorFill - record.Record.log.debug('createNewRecorded: ' + str(recd) + ", thumbFilename:" + str(recd.thumbFilename)) - return recd + record.Record.log.debug('createNewRecorded: ' + str(recd) + ", thumbFilename:" + str(recd.thumbFilename)) + return recd - def createNewRecordedMd5Sums( self, recd ): - #load the thumbfile - thumbFile = os.path.join(Instance.instancePath, recd.thumbFilename) - thumbMd5 = utils.md5File( thumbFile ) - recd.thumbMd5 = thumbMd5 - tBytes = os.stat(thumbFile)[6] - recd.thumbBytes = tBytes + def createNewRecordedMd5Sums( self, recd ): + #load the thumbfile + thumbFile = os.path.join(Instance.instancePath, recd.thumbFilename) + thumbMd5 = utils.md5File( thumbFile ) + recd.thumbMd5 = thumbMd5 + tBytes = os.stat(thumbFile)[6] + recd.thumbBytes = tBytes - recd.tags = "" + recd.tags = "" - #load the mediafile - mediaFile = os.path.join(Instance.instancePath, recd.mediaFilename) - mediaMd5 = utils.md5File( mediaFile ) - recd.mediaMd5 = mediaMd5 - mBytes = os.stat(mediaFile)[6] - recd.mediaBytes = mBytes + #load the mediafile + mediaFile = os.path.join(Instance.instancePath, recd.mediaFilename) + mediaMd5 = utils.md5File( mediaFile ) + recd.mediaMd5 = mediaMd5 + mBytes = os.stat(mediaFile)[6] + recd.mediaBytes = mBytes - def deleteRecorded( self, recd ): - recd.deleted = True + def deleteRecorded( self, recd ): + recd.deleted = True - #clear the index - hash = self.mediaHashs[recd.type] - index = hash.index(recd) - hash.remove( recd ) + #clear the index + hash = self.mediaHashs[recd.type] + index = hash.index(recd) + hash.remove( recd ) - if (not recd.meshUploading): - self.doDeleteRecorded( recd ) + if (not recd.meshUploading): + self.doDeleteRecorded( recd ) - def doDeleteRecorded( self, recd ): - #remove files from the filesystem if not on the datastore - if (recd.datastoreId == None): - mediaFile = recd.getMediaFilepath() - if (os.path.exists(mediaFile)): - os.remove(mediaFile) + def doDeleteRecorded( self, recd ): + #remove files from the filesystem if not on the datastore + if (recd.datastoreId == None): + mediaFile = recd.getMediaFilepath() + if (os.path.exists(mediaFile)): + os.remove(mediaFile) - thumbFile = recd.getThumbFilepath( ) - if (os.path.exists(thumbFile)): - os.remove(thumbFile) - else: - #remove from the datastore here, since once gone, it is gone... - serialize.removeMediaFromDatastore( recd ) + thumbFile = recd.getThumbFilepath( ) + if (os.path.exists(thumbFile)): + os.remove(thumbFile) + else: + #remove from the datastore here, since once gone, it is gone... + serialize.removeMediaFromDatastore( recd ) - def doVideoMode( self ): - if (self.MODE == Constants.MODE_VIDEO): - return + def doVideoMode( self ): + if (self.MODE == Constants.MODE_VIDEO): + return - self.MODE = Constants.MODE_VIDEO - self.setUpdating(True) - gobject.idle_add( self.setupMode, self.MODE, True ) + self.MODE = Constants.MODE_VIDEO + self.setUpdating(True) + gobject.idle_add( self.setupMode, self.MODE, True ) - def doPhotoMode( self ): - if (self.MODE == Constants.MODE_PHOTO): - return + def doPhotoMode( self ): + if (self.MODE == Constants.MODE_PHOTO): + return - self.MODE = Constants.MODE_PHOTO - self.setUpdating(True) - gobject.idle_add( self.setupMode, self.MODE, True ) + self.MODE = Constants.MODE_PHOTO + self.setUpdating(True) + gobject.idle_add( self.setupMode, self.MODE, True ) - def doAudioMode( self ): - if (self.MODE == Constants.MODE_AUDIO): - return + def doAudioMode( self ): + if (self.MODE == Constants.MODE_AUDIO): + return - self.MODE = Constants.MODE_AUDIO - self.setUpdating(True) - gobject.idle_add( self.setupMode, self.MODE, True ) + self.MODE = Constants.MODE_AUDIO + self.setUpdating(True) + gobject.idle_add( self.setupMode, self.MODE, True ) diff --git a/p5.py b/p5.py index ebcb08e..e785f94 100644 --- a/p5.py +++ b/p5.py @@ -27,164 +27,164 @@ import math #Sometimes a gtk.Image is a useful alternative to a drawing area. You can put a gtk.gdk.Pixmap in the gtk.Image and draw to the gtk.gdk.Pixmap, calling the gtk.Widget.queue_draw() method on the gtk.Image when you want to refresh to the screen. class P5(gtk.DrawingArea): - def __init__(self): - super(P5, self).__init__() + def __init__(self): + super(P5, self).__init__() - # gtk.Widget signals - self.connect("expose_event", self.expose) - self.connect("button_press_event", self.button_press) - self.connect("button_release_event", self.button_release) - self.connect("motion_notify_event", self.motion_notify) + # gtk.Widget signals + self.connect("expose_event", self.expose) + self.connect("button_press_event", self.button_press) + self.connect("button_release_event", self.button_release) + self.connect("motion_notify_event", self.motion_notify) - # ok, we have to listen to mouse events here too - self.add_events(gdk.BUTTON_PRESS_MASK | gdk.BUTTON_RELEASE_MASK | gdk.POINTER_MOTION_MASK) - self._dragging = False - self._mouseX = 0 - self._mouseY = 0 + # ok, we have to listen to mouse events here too + self.add_events(gdk.BUTTON_PRESS_MASK | gdk.BUTTON_RELEASE_MASK | gdk.POINTER_MOTION_MASK) + self._dragging = False + self._mouseX = 0 + self._mouseY = 0 - self._w = -1 - self._h = -1 + self._w = -1 + self._h = -1 - #ok, this calls an initial painting & setting of painterly variables - #e.g. time for the clock widget - #(but not through to redraw_canvas when called here first time) - self._msecUpdate = 100 - self._looping = False - self.noloop() + #ok, this calls an initial painting & setting of painterly variables + #e.g. time for the clock widget + #(but not through to redraw_canvas when called here first time) + self._msecUpdate = 100 + self._looping = False + self.noloop() - def loop(self): - if (self._looping): - return - else: - self._looping = True - # this is our maybe-threaded refresh (in millisecs) - gobject.timeout_add( self._msecUpdate, self.update ) + def loop(self): + if (self._looping): + return + else: + self._looping = True + # this is our maybe-threaded refresh (in millisecs) + gobject.timeout_add( self._msecUpdate, self.update ) - def noloop(self): - self._looping = False - self.redraw() + def noloop(self): + self._looping = False + self.redraw() - def redraw(self): - self.update() + def redraw(self): + self.update() - def expose(self, widget, event): - ctx = widget.window.cairo_create() + def expose(self, widget, event): + ctx = widget.window.cairo_create() - # set a clip region for the expose event - ctx.rectangle(event.area.x, event.area.y, event.area.width, event.area.height) - ctx.clip() + # set a clip region for the expose event + ctx.rectangle(event.area.x, event.area.y, event.area.width, event.area.height) + ctx.clip() - rect = widget.allocation - #self.draw(ctx, event.area.width, event.area.height) - self.draw( ctx, rect.width, rect.height ) + rect = widget.allocation + #self.draw(ctx, event.area.width, event.area.height) + self.draw( ctx, rect.width, rect.height ) - def button_press(self, widget, event): - self._mouseX = event.x - self._mouseY = event.y - self._dragging = True + def button_press(self, widget, event): + self._mouseX = event.x + self._mouseY = event.y + self._dragging = True - def button_release(self, widget, event): - if self._dragging: - self._dragging = False + def button_release(self, widget, event): + if self._dragging: + self._dragging = False - def motion_notify(self, widget, event): - self._mouseX = event.x - self._mouseY = event.y + def motion_notify(self, widget, event): + self._mouseX = event.x + self._mouseY = event.y - def draw(self, ctx, w, h): - ctx.set_antialias( cairo.ANTIALIAS_NONE ) - ctx.set_line_width( 1 ) - ctx.identity_matrix( ) - if ((w != self._w) or (h != self._h)): - self._w = w - self._h = h - self.doResize( ) + def draw(self, ctx, w, h): + ctx.set_antialias( cairo.ANTIALIAS_NONE ) + ctx.set_line_width( 1 ) + ctx.identity_matrix( ) + if ((w != self._w) or (h != self._h)): + self._w = w + self._h = h + self.doResize( ) - def doResize(self): - pass + def doResize(self): + pass - #called from update - def redraw_canvas(self): - if self.window: - alloc = self.get_allocation() - #this is odd behavior, but once we add this widget to a parent (vbox) - #it requires setting the q_d_a x,y to 0, 0 - #self.queue_draw_area(alloc.x, alloc.y, alloc.width, alloc.height) - self.queue_draw_area(0, 0, alloc.width, alloc.height) - self.window.process_updates(True) + #called from update + def redraw_canvas(self): + if self.window: + alloc = self.get_allocation() + #this is odd behavior, but once we add this widget to a parent (vbox) + #it requires setting the q_d_a x,y to 0, 0 + #self.queue_draw_area(alloc.x, alloc.y, alloc.width, alloc.height) + self.queue_draw_area(0, 0, alloc.width, alloc.height) + self.window.process_updates(True) - def update(self): - #paint thread -- call redraw_canvas, which calls expose - self.redraw_canvas() - if (self._looping): - return True # keep running this event - else: - return False + def update(self): + #paint thread -- call redraw_canvas, which calls expose + self.redraw_canvas() + if (self._looping): + return True # keep running this event + else: + return False - def drawShape( self, ctx, poly, col ): - self.setColor( ctx, col ) + def drawShape( self, ctx, poly, col ): + self.setColor( ctx, col ) - for i in range ( 0, len(poly._xs) ): - ctx.line_to ( poly._xs[i], poly._ys[i] ) - ctx.close_path() - ctx.set_line_width(1) - ctx.stroke() + for i in range ( 0, len(poly._xs) ): + ctx.line_to ( poly._xs[i], poly._ys[i] ) + ctx.close_path() + ctx.set_line_width(1) + ctx.stroke() - def fillShape( self, ctx, poly, col ): - self.setColor( ctx, col ) - for i in range ( 0, len(poly._xs) ): - ctx.line_to (poly._xs[i], poly._ys[i]) - ctx.close_path() + def fillShape( self, ctx, poly, col ): + self.setColor( ctx, col ) + for i in range ( 0, len(poly._xs) ): + ctx.line_to (poly._xs[i], poly._ys[i]) + ctx.close_path() - ctx.fill() + ctx.fill() - def background( self, ctx, col, w, h ): - self.setColor( ctx, col ) + def background( self, ctx, col, w, h ): + self.setColor( ctx, col ) - ctx.line_to(0, 0) - ctx.line_to(w, 0) - ctx.line_to(w, h) - ctx.line_to(0, h) - ctx.close_path() + ctx.line_to(0, 0) + ctx.line_to(w, 0) + ctx.line_to(w, h) + ctx.line_to(0, h) + ctx.close_path() - ctx.fill() + ctx.fill() - def rect( self, ctx, x, y, w, h ): - ctx.line_to(x, y) - ctx.line_to(x+w, y) - ctx.line_to(x+w, y+h) - ctx.line_to(x, y+h) - ctx.close_path() + def rect( self, ctx, x, y, w, h ): + ctx.line_to(x, y) + ctx.line_to(x+w, y) + ctx.line_to(x+w, y+h) + ctx.line_to(x, y+h) + ctx.close_path() - def setColor( self, ctx, col ): - if (not col._opaque): - ctx.set_source_rgba( col._r, col._g, col._b, col._a ) - else: - ctx.set_source_rgb( col._r, col._g, col._b ) + def setColor( self, ctx, col ): + if (not col._opaque): + ctx.set_source_rgba( col._r, col._g, col._b, col._a ) + else: + ctx.set_source_rgb( col._r, col._g, col._b ) - def line( self, ctx, x1, y1, x2, y2 ): - ctx.move_to (x1, y1) - ctx.line_to (x2, y2) - ctx.stroke() + def line( self, ctx, x1, y1, x2, y2 ): + ctx.move_to (x1, y1) + ctx.line_to (x2, y2) + ctx.stroke() - def point( self, ctx, x1, y1 ): - self.line( ctx, x1, y1, x1+1, y1 ) \ No newline at end of file + def point( self, ctx, x1, y1 ): + self.line( ctx, x1, y1, x1+1, y1 ) \ No newline at end of file diff --git a/p5_button.py b/p5_button.py index 0461b3c..cf76a34 100644 --- a/p5_button.py +++ b/p5_button.py @@ -22,152 +22,152 @@ from p5 import P5 class P5Button(P5): - def __init__(self): - P5.__init__(self) - self.noloop() - self._butts = [] - self._buttonPressed = False + def __init__(self): + P5.__init__(self) + self.noloop() + self._butts = [] + self._buttonPressed = False - def button_press(self, widget, event): - P5.button_press(self, widget, event) + def button_press(self, widget, event): + P5.button_press(self, widget, event) - #iterate through the buttons to see if you've pressed any down - bp = False - for i in range ( 0, len(self._butts) ): - if (self._butts[i]._enabled): - contains = self._butts[i].contains(event.x, event.y) - self._butts[i]._pressed = contains - if (contains): - bp = True + #iterate through the buttons to see if you've pressed any down + bp = False + for i in range ( 0, len(self._butts) ): + if (self._butts[i]._enabled): + contains = self._butts[i].contains(event.x, event.y) + self._butts[i]._pressed = contains + if (contains): + bp = True - self._buttonPressed = bp - self.redraw() + self._buttonPressed = bp + self.redraw() - def button_release(self, widget, event): - P5.button_release(self, widget, event) - self._buttonPressed = False + def button_release(self, widget, event): + P5.button_release(self, widget, event) + self._buttonPressed = False - pressed = [] - #iterate through the buttons to see if you've released on any - for i in range ( 0, len(self._butts) ): - if (self._butts[i]._enabled): - if (self._butts[i]._pressed): - if (self._butts[i].contains(event.x, event.y)): - pressed.append( self._butts[i] ) + pressed = [] + #iterate through the buttons to see if you've released on any + for i in range ( 0, len(self._butts) ): + if (self._butts[i]._enabled): + if (self._butts[i]._pressed): + if (self._butts[i].contains(event.x, event.y)): + pressed.append( self._butts[i] ) - if (self._butts[i]._toggle): - self._butts[i]._pressed = not self._butts[i]._pressed - else: - self._butts[i]._pressed = False + if (self._butts[i]._toggle): + self._butts[i]._pressed = not self._butts[i]._pressed + else: + self._butts[i]._pressed = False - for i in range( 0, len(pressed) ): - pressed[i].doPressed() + for i in range( 0, len(pressed) ): + pressed[i].doPressed() - self.redraw() + self.redraw() class Polygon: - def __init__( self, xs, ys ): - self.setPoints( xs, ys ) + def __init__( self, xs, ys ): + self.setPoints( xs, ys ) - def setPoints( self, xs, ys ): - self._xs = xs - self._ys = ys + def setPoints( self, xs, ys ): + self._xs = xs + self._ys = ys - self._boundingX = self._xs[0] - self._boundingY = self._ys[0] - self._boundingW = self._xs[0] - self._boundingH = self._ys[0] + self._boundingX = self._xs[0] + self._boundingY = self._ys[0] + self._boundingW = self._xs[0] + self._boundingH = self._ys[0] - for i in range ( 1, len(self._xs) ): - if (self._xs[i] > self._boundingW): - self._boundingW = self._xs[i] - if (self._ys[i] > self._boundingH): - self._boundingH = self._ys[i] - if (self._xs[i] < self._boundingX): - self._boundingX = self._xs[i] - if (self._ys[i] < self._boundingY): - self._boundingY = self._ys[i] + for i in range ( 1, len(self._xs) ): + if (self._xs[i] > self._boundingW): + self._boundingW = self._xs[i] + if (self._ys[i] > self._boundingH): + self._boundingH = self._ys[i] + if (self._xs[i] < self._boundingX): + self._boundingX = self._xs[i] + if (self._ys[i] < self._boundingY): + self._boundingY = self._ys[i] - def contains( self, mx, my ): - if (not self.bbox_contains(mx, my)): - return False + def contains( self, mx, my ): + if (not self.bbox_contains(mx, my)): + return False - #insert simple path tracing check on the polygon here + #insert simple path tracing check on the polygon here - return True + return True - def bbox_contains( self, mx, my ): - if ( not((mx>=self._boundingX) and (my>=self._boundingY) and (mx=self._boundingX) and (my>=self._boundingY) and (mx 0): - self.__class__.log.debug('mnrrb: weve already tried bud ' + str(nextBudObj.props.nick)) - else: - self.__class__.log.debug('mnrrb: ask next buddy: ' + str(nextBudObj.props.nick)) - goodBudObj = nextBudObj - break - - if (goodBudObj != None): - goodNick = goodBudObj.props.nick - goodBud = util._sha_data(goodBudObj.props.key) - goodBud = util.printable_hash(goodBud) - self.meshReqRecFromBuddy(recd, goodBud, goodNick) - else: - self.__class__.log.debug('weve tried all buddies here, and no one has this recd') - recd.meshDownloading = False - recd.triedMeshBuddies = [] - recd.triedMeshBuddies.append(Instance.keyHashPrintable) - self.ui.updateMeshProgress(False, recd) - - - def meshReqRecFromBuddy( self, recd, fromWho, fromWhosNick ): - recd.triedMeshBuddies.append( fromWho ) - recd.meshDownloadingFrom = fromWho - recd.meshDownloadingFromNick = fromWhosNick - recd.meshDownloadingProgress = False - recd.meshDownloading = True - recd.meshDownlodingPercent = 0.0 - self.ui.updateMeshProgress(True, recd) - recd.meshReqCallbackId = gobject.timeout_add(self.meshTimeoutTime, self._meshCheckOnRecdRequest, recd) - self.recTube.requestRecdBits( Instance.keyHashPrintable, fromWho, recd.mediaMd5 ) - - - def _meshCheckOnRecdRequest( self, recdRequesting ): - #todo: add category for "not active activity, so go ahead and delete" - - if (recdRequesting.downloadedFromBuddy): - self.__class__.log.debug('_meshCheckOnRecdRequest: recdRequesting.downloadedFromBuddy') - if (recdRequesting.meshReqCallbackId != 0): - gobject.source_remove(recdRequesting.meshReqCallbackId) - recdRequesting.meshReqCallbackId = 0 - return False - if (recdRequesting.deleted): - self.__class__.log.debug('_meshCheckOnRecdRequest: recdRequesting.deleted') - if (recdRequesting.meshReqCallbackId != 0): - gobject.source_remove(recdRequesting.meshReqCallbackId) - recdRequesting.meshReqCallbackId = 0 - return False - if (recdRequesting.meshDownloadingProgress): - self.__class__.log.debug('_meshCheckOnRecdRequest: recdRequesting.meshDownloadingProgress') - #we've received some bits since last we checked, so keep waiting... they'll all get here eventually! - recdRequesting.meshDownloadingProgress = False - return True - else: - self.__class__.log.debug('_meshCheckOnRecdRequest: ! recdRequesting.meshDownloadingProgress') - #that buddy we asked info from isn't responding; next buddy! - #self.meshNextRoundRobinBuddy( recdRequesting ) - gobject.idle_add(self.meshNextRoundRobinBuddy, recdRequesting) - return False - - - def _recdRequestCb( self, objectThatSentTheSignal, whoWantsIt, md5sumOfIt ): - #if we are here, it is because someone has been told we have what they want. - #we need to send them that thing, whatever that thing is - recd = self.m.getRecdByMd5( md5sumOfIt ) - if (recd == None): - self.__class__.log.debug('_recdRequestCb: we dont have the recd they asked for') - self.recTube.unavailableRecd(md5sumOfIt, Instance.keyHashPrintable, whoWantsIt) - return - if (recd.deleted): - self.__class__.log.debug('_recdRequestCb: we have the recd, but it has been deleted, so we wont share') - self.recTube.unavailableRecd(md5sumOfIt, Instance.keyHashPrintable, whoWantsIt) - return - if (recd.buddy and not recd.downloadedFromBuddy): - self.__class__.log.debug('_recdRequestCb: we have an incomplete recd, so we wont share') - self.recTube.unavailableRecd(md5sumOfIt, Instance.keyHashPrintable, whoWantsIt) - return - - recd.meshUploading = True - filepath = recd.getMediaFilepath() - - if (recd.type == Constants.TYPE_AUDIO): - audioImgFilepath = recd.getAudioImageFilepath() - - destPath = os.path.join(Instance.instancePath, "audioBundle") - destPath = utils.getUniqueFilepath(destPath, 0) - cmd = "cat " + str(filepath) + " " + str(audioImgFilepath) + " > " + str(destPath) - self.__class__.log.debug(cmd) - os.system(cmd) - filepath = destPath - - sent = self.recTube.broadcastRecd(recd.mediaMd5, filepath, whoWantsIt) - recd.meshUploading = False - #if you were deleted while uploading, now throw away those bits now - if (recd.deleted): - recd.doDeleteRecorded(recd) - - - def _recdBitsArrivedCb( self, objectThatSentTheSignal, md5sumOfIt, part, numparts, bytes, fromWho ): - #self.__class__.log.debug('_recdBitsArrivedCb: ' + str(part) + "/" + str(numparts)) - recd = self.m.getRecdByMd5( md5sumOfIt ) - if (recd == None): - self.__class__.log.debug('_recdBitsArrivedCb: thx 4 yr bits, but we dont even have that photo') - return - if (recd.deleted): - self.__class__.log.debug('_recdBitsArrivedCb: thx 4 yr bits, but we deleted that photo') - return - if (recd.downloadedFromBuddy): - self.__class__.log.debug('_recdBitsArrivedCb: weve already downloadedFromBuddy') - return - if (not recd.buddy): - self.__class__.log.debug('_recdBitsArrivedCb: uh, we took this photo, so dont need your bits') - return - if (recd.meshDownloadingFrom != fromWho): - self.__class__.log.debug('_recdBitsArrivedCb: wrong bits ' + str(fromWho) + ", exp:" + str(recd.meshDownloadingFrom)) - return - - #update that we've heard back about this, reset the timeout - gobject.source_remove(recd.meshReqCallbackId) - recd.meshReqCallbackId = gobject.timeout_add(self.meshTimeoutTime, self._meshCheckOnRecdRequest, recd) - - #update the progress bar - recd.meshDownlodingPercent = (part+0.0)/(numparts+0.0) - recd.meshDownloadingProgress = True - self.ui.updateMeshProgress(True, recd) - f = open(recd.getMediaFilepath(), 'a+') - f.write(bytes) - f.close() - - if part == numparts: - self.__class__.log.debug('Finished receiving %s' % recd.title) - gobject.source_remove( recd.meshReqCallbackId ) - recd.meshReqCallbackId = 0 - recd.meshDownloading = False - recd.meshDownlodingPercent = 1.0 - recd.downloadedFromBuddy = True - if (recd.type == Constants.TYPE_AUDIO): - filepath = recd.getMediaFilepath() - bundlePath = os.path.join(Instance.instancePath, "audioBundle") - bundlePath = utils.getUniqueFilepath(bundlePath, 0) - - cmd = "split -a 1 -b " + str(recd.mediaBytes) + " " + str(filepath) + " " + str(bundlePath) - self.__class__.log.debug( cmd ) - os.system( cmd ) - - bundleName = os.path.basename(bundlePath) - mediaFilename = str(bundleName) + "a" - mediaFilepath = os.path.join(Instance.instancePath, mediaFilename) - mediaFilepathExt = os.path.join(Instance.instancePath, mediaFilename+".ogg") - os.rename(mediaFilepath, mediaFilepathExt) - audioImageFilename = str(bundleName) + "b" - audioImageFilepath = os.path.join(Instance.instancePath, audioImageFilename) - audioImageFilepathExt = os.path.join(Instance.instancePath, audioImageFilename+".png") - os.rename(audioImageFilepath, audioImageFilepathExt) - - recd.mediaFilename = os.path.basename(mediaFilepathExt) - recd.audioImageFilename = os.path.basename(audioImageFilepathExt) - - self.ui.showMeshRecd( recd ) - elif part > numparts: - self.__class__.log.error('More parts than required have arrived') - - - def _getAlbumArtCb( self, objectThatSentTheSignal, pixbuf, recd ): - - if (pixbuf != None): - imagePath = os.path.join(Instance.instancePath, "audioPicture.png") - imagePath = utils.getUniqueFilepath( imagePath, 0 ) - pixbuf.save( imagePath, "png", {} ) - recd.audioImageFilename = os.path.basename(imagePath) - - self.ui.showMeshRecd( recd ) - return False - - - def _recdUnavailableCb( self, objectThatSentTheSignal, md5sumOfIt, whoDoesntHaveIt ): - self.__class__.log.debug('_recdUnavailableCb: sux, we want to see that photo') - recd = self.m.getRecdByMd5( md5sumOfIt ) - if (recd == None): - self.__class__.log.debug('_recdUnavailableCb: actually, we dont even know about that one..') - return - if (recd.deleted): - self.__class__.log.debug('_recdUnavailableCb: actually, since we asked, we deleted.') - return - if (not recd.buddy): - self.__class__.log.debug('_recdUnavailableCb: uh, odd, we took that photo and have it already.') - return - if (recd.downloadedFromBuddy): - self.__class__.log.debug('_recdUnavailableCb: we already downloaded it... you might have been slow responding.') - return - if (recd.meshDownloadingFrom != whoDoesntHaveIt): - self.__class__.log.debug('_recdUnavailableCb: we arent asking you for a copy now. slow response, pbly.') - return - - #self.meshNextRoundRobinBuddy( recd ) + #this calls write_file + activity.Activity.close( self ) + + + def destroy( self ): + if self.I_AM_SAVED: + activity.Activity.destroy( self ) + + + def _sharedCb( self, activity ): + self._setup() + + id = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferDBusTube( Constants.SERVICE, {}) + + + def _meshJoinedCb( self, activity ): + if not self._shared_activity: + return + + self._setup() + + self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].ListTubes( reply_handler=self._list_tubes_reply_cb, error_handler=self._list_tubes_error_cb) + + + def _list_tubes_reply_cb(self, tubes): + for tube_info in tubes: + self._newTubeCb(*tube_info) + + + def _list_tubes_error_cb(self, e): + self.__class__.log.error('ListTubes() failed: %s', e) + + + def _setup(self): + #sets up the tubes... + if self._shared_activity is None: + self.__class__.log.error('_setup: Failed to share or join activity') + return + + pservice = presenceservice.get_instance() + try: + name, path = pservice.get_preferred_connection() + self.conn = telepathy.client.Connection(name, path) + except: + self.__class__.log.error('_setup: Failed to get_preferred_connection') + + # Work out what our room is called and whether we have Tubes already + bus_name, conn_path, channel_paths = self._shared_activity.get_channels() + room = None + tubes_chan = None + text_chan = None + for channel_path in channel_paths: + channel = telepathy.client.Channel(bus_name, channel_path) + htype, handle = channel.GetHandle() + if htype == telepathy.HANDLE_TYPE_ROOM: + self.__class__.log.debug('Found our room: it has handle#%d "%s"', handle, self.conn.InspectHandles(htype, [handle])[0]) + room = handle + ctype = channel.GetChannelType() + if ctype == telepathy.CHANNEL_TYPE_TUBES: + self.__class__.log.debug('Found our Tubes channel at %s', channel_path) + tubes_chan = channel + elif ctype == telepathy.CHANNEL_TYPE_TEXT: + self.__class__.log.debug('Found our Text channel at %s', channel_path) + text_chan = channel + + if room is None: + self.__class__.log.error("Presence service didn't create a room") + return + if text_chan is None: + self.__class__.log.error("Presence service didn't create a text channel") + return + + # Make sure we have a Tubes channel - PS doesn't yet provide one + if tubes_chan is None: + self.__class__.log.debug("Didn't find our Tubes channel, requesting one...") + tubes_chan = self.conn.request_channel(telepathy.CHANNEL_TYPE_TUBES, telepathy.HANDLE_TYPE_ROOM, room, True) + + self.tubes_chan = tubes_chan + self.text_chan = text_chan + + tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal('NewTube', self._newTubeCb) + + + def _newTubeCb(self, id, initiator, type, service, params, state): + self.__class__.log.debug('New tube: ID=%d initator=%d type=%d service=%s params=%r state=%d', id, initiator, type, service, params, state) + if (type == telepathy.TUBE_TYPE_DBUS and service == Constants.SERVICE): + if state == telepathy.TUBE_STATE_LOCAL_PENDING: + self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].AcceptDBusTube(id) + tube_conn = TubeConnection(self.conn, self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES], id, group_iface=self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP]) + self.recTube = RecordTube(tube_conn) + self.recTube.connect("new-recd", self._newRecdCb) + self.recTube.connect("recd-request", self._recdRequestCb) + self.recTube.connect("recd-bits-arrived", self._recdBitsArrivedCb) + self.recTube.connect("recd-unavailable", self._recdUnavailableCb) + + + def _newRecdCb( self, objectThatSentTheSignal, recorder, xmlString ): + self.__class__.log.debug('_newRecdCb') + dom = None + try: + dom = xml.dom.minidom.parseString(xmlString) + except: + self.__class__.log.error('Unable to parse mesh xml') + if (dom == None): + return + + recd = Recorded() + recd = serialize.fillRecdFromNode(recd, dom.documentElement) + if (recd != None): + self.__class__.log.debug('_newRecdCb: adding new recd thumb') + recd.buddy = True + recd.downloadedFromBuddy = False + self.m.addMeshRecd( recd ) + else: + self.__class__.log.debug('_newRecdCb: recd is None. Unable to parse XML') + + + def requestMeshDownload( self, recd ): + if (recd.meshDownloading): + return True + + self.m.updateXoFullStatus() + if (self.m.FULL): + return True + + #this call will get the bits or request the bits if they're not available + if (recd.buddy and (not recd.downloadedFromBuddy)): + self.meshInitRoundRobin(recd) + return True + + else: + return False + + + def meshInitRoundRobin( self, recd ): + if (recd.meshDownloading): + self.__class__.log.debug("meshInitRoundRobin: we are in midst of downloading this file...") + return + + if (self.recTube == None): + gobject.idle_add(self.ui.updateMeshProgress, False, recd) + return + + #start with who took the photo + recd.triedMeshBuddies = [] + recd.triedMeshBuddies.append(Instance.keyHashPrintable) + self.meshReqRecFromBuddy( recd, recd.recorderHash, recd.recorderName ) + + + def meshNextRoundRobinBuddy( self, recd ): + self.__class__.log.debug('meshNextRoundRobinBuddy') + if (recd.meshReqCallbackId != 0): + gobject.source_remove(recd.meshReqCallbackId) + recd.meshReqCallbackId = 0 + + #delete any stub of a partially downloaded file + filepath = recd.getMediaFilepath() + if (filepath != None): + if (os.path.exists(filepath)): + os.remove( filepath ) + + goodBudObj = None + buds = self._shared_activity.get_joined_buddies() + for i in range (0, len(buds)): + nextBudObj = buds[i] + nextBud = util._sha_data(nextBudObj.props.key) + nextBud = util.printable_hash(nextBud) + if (recd.triedMeshBuddies.count(nextBud) > 0): + self.__class__.log.debug('mnrrb: weve already tried bud ' + str(nextBudObj.props.nick)) + else: + self.__class__.log.debug('mnrrb: ask next buddy: ' + str(nextBudObj.props.nick)) + goodBudObj = nextBudObj + break + + if (goodBudObj != None): + goodNick = goodBudObj.props.nick + goodBud = util._sha_data(goodBudObj.props.key) + goodBud = util.printable_hash(goodBud) + self.meshReqRecFromBuddy(recd, goodBud, goodNick) + else: + self.__class__.log.debug('weve tried all buddies here, and no one has this recd') + recd.meshDownloading = False + recd.triedMeshBuddies = [] + recd.triedMeshBuddies.append(Instance.keyHashPrintable) + self.ui.updateMeshProgress(False, recd) + + + def meshReqRecFromBuddy( self, recd, fromWho, fromWhosNick ): + recd.triedMeshBuddies.append( fromWho ) + recd.meshDownloadingFrom = fromWho + recd.meshDownloadingFromNick = fromWhosNick + recd.meshDownloadingProgress = False + recd.meshDownloading = True + recd.meshDownlodingPercent = 0.0 + self.ui.updateMeshProgress(True, recd) + recd.meshReqCallbackId = gobject.timeout_add(self.meshTimeoutTime, self._meshCheckOnRecdRequest, recd) + self.recTube.requestRecdBits( Instance.keyHashPrintable, fromWho, recd.mediaMd5 ) + + + def _meshCheckOnRecdRequest( self, recdRequesting ): + #todo: add category for "not active activity, so go ahead and delete" + + if (recdRequesting.downloadedFromBuddy): + self.__class__.log.debug('_meshCheckOnRecdRequest: recdRequesting.downloadedFromBuddy') + if (recdRequesting.meshReqCallbackId != 0): + gobject.source_remove(recdRequesting.meshReqCallbackId) + recdRequesting.meshReqCallbackId = 0 + return False + if (recdRequesting.deleted): + self.__class__.log.debug('_meshCheckOnRecdRequest: recdRequesting.deleted') + if (recdRequesting.meshReqCallbackId != 0): + gobject.source_remove(recdRequesting.meshReqCallbackId) + recdRequesting.meshReqCallbackId = 0 + return False + if (recdRequesting.meshDownloadingProgress): + self.__class__.log.debug('_meshCheckOnRecdRequest: recdRequesting.meshDownloadingProgress') + #we've received some bits since last we checked, so keep waiting... they'll all get here eventually! + recdRequesting.meshDownloadingProgress = False + return True + else: + self.__class__.log.debug('_meshCheckOnRecdRequest: ! recdRequesting.meshDownloadingProgress') + #that buddy we asked info from isn't responding; next buddy! + #self.meshNextRoundRobinBuddy( recdRequesting ) + gobject.idle_add(self.meshNextRoundRobinBuddy, recdRequesting) + return False + + + def _recdRequestCb( self, objectThatSentTheSignal, whoWantsIt, md5sumOfIt ): + #if we are here, it is because someone has been told we have what they want. + #we need to send them that thing, whatever that thing is + recd = self.m.getRecdByMd5( md5sumOfIt ) + if (recd == None): + self.__class__.log.debug('_recdRequestCb: we dont have the recd they asked for') + self.recTube.unavailableRecd(md5sumOfIt, Instance.keyHashPrintable, whoWantsIt) + return + if (recd.deleted): + self.__class__.log.debug('_recdRequestCb: we have the recd, but it has been deleted, so we wont share') + self.recTube.unavailableRecd(md5sumOfIt, Instance.keyHashPrintable, whoWantsIt) + return + if (recd.buddy and not recd.downloadedFromBuddy): + self.__class__.log.debug('_recdRequestCb: we have an incomplete recd, so we wont share') + self.recTube.unavailableRecd(md5sumOfIt, Instance.keyHashPrintable, whoWantsIt) + return + + recd.meshUploading = True + filepath = recd.getMediaFilepath() + + if (recd.type == Constants.TYPE_AUDIO): + audioImgFilepath = recd.getAudioImageFilepath() + + destPath = os.path.join(Instance.instancePath, "audioBundle") + destPath = utils.getUniqueFilepath(destPath, 0) + cmd = "cat " + str(filepath) + " " + str(audioImgFilepath) + " > " + str(destPath) + self.__class__.log.debug(cmd) + os.system(cmd) + filepath = destPath + + sent = self.recTube.broadcastRecd(recd.mediaMd5, filepath, whoWantsIt) + recd.meshUploading = False + #if you were deleted while uploading, now throw away those bits now + if (recd.deleted): + recd.doDeleteRecorded(recd) + + + def _recdBitsArrivedCb( self, objectThatSentTheSignal, md5sumOfIt, part, numparts, bytes, fromWho ): + #self.__class__.log.debug('_recdBitsArrivedCb: ' + str(part) + "/" + str(numparts)) + recd = self.m.getRecdByMd5( md5sumOfIt ) + if (recd == None): + self.__class__.log.debug('_recdBitsArrivedCb: thx 4 yr bits, but we dont even have that photo') + return + if (recd.deleted): + self.__class__.log.debug('_recdBitsArrivedCb: thx 4 yr bits, but we deleted that photo') + return + if (recd.downloadedFromBuddy): + self.__class__.log.debug('_recdBitsArrivedCb: weve already downloadedFromBuddy') + return + if (not recd.buddy): + self.__class__.log.debug('_recdBitsArrivedCb: uh, we took this photo, so dont need your bits') + return + if (recd.meshDownloadingFrom != fromWho): + self.__class__.log.debug('_recdBitsArrivedCb: wrong bits ' + str(fromWho) + ", exp:" + str(recd.meshDownloadingFrom)) + return + + #update that we've heard back about this, reset the timeout + gobject.source_remove(recd.meshReqCallbackId) + recd.meshReqCallbackId = gobject.timeout_add(self.meshTimeoutTime, self._meshCheckOnRecdRequest, recd) + + #update the progress bar + recd.meshDownlodingPercent = (part+0.0)/(numparts+0.0) + recd.meshDownloadingProgress = True + self.ui.updateMeshProgress(True, recd) + f = open(recd.getMediaFilepath(), 'a+') + f.write(bytes) + f.close() + + if part == numparts: + self.__class__.log.debug('Finished receiving %s' % recd.title) + gobject.source_remove( recd.meshReqCallbackId ) + recd.meshReqCallbackId = 0 + recd.meshDownloading = False + recd.meshDownlodingPercent = 1.0 + recd.downloadedFromBuddy = True + if (recd.type == Constants.TYPE_AUDIO): + filepath = recd.getMediaFilepath() + bundlePath = os.path.join(Instance.instancePath, "audioBundle") + bundlePath = utils.getUniqueFilepath(bundlePath, 0) + + cmd = "split -a 1 -b " + str(recd.mediaBytes) + " " + str(filepath) + " " + str(bundlePath) + self.__class__.log.debug( cmd ) + os.system( cmd ) + + bundleName = os.path.basename(bundlePath) + mediaFilename = str(bundleName) + "a" + mediaFilepath = os.path.join(Instance.instancePath, mediaFilename) + mediaFilepathExt = os.path.join(Instance.instancePath, mediaFilename+".ogg") + os.rename(mediaFilepath, mediaFilepathExt) + audioImageFilename = str(bundleName) + "b" + audioImageFilepath = os.path.join(Instance.instancePath, audioImageFilename) + audioImageFilepathExt = os.path.join(Instance.instancePath, audioImageFilename+".png") + os.rename(audioImageFilepath, audioImageFilepathExt) + + recd.mediaFilename = os.path.basename(mediaFilepathExt) + recd.audioImageFilename = os.path.basename(audioImageFilepathExt) + + self.ui.showMeshRecd( recd ) + elif part > numparts: + self.__class__.log.error('More parts than required have arrived') + + + def _getAlbumArtCb( self, objectThatSentTheSignal, pixbuf, recd ): + + if (pixbuf != None): + imagePath = os.path.join(Instance.instancePath, "audioPicture.png") + imagePath = utils.getUniqueFilepath( imagePath, 0 ) + pixbuf.save( imagePath, "png", {} ) + recd.audioImageFilename = os.path.basename(imagePath) + + self.ui.showMeshRecd( recd ) + return False + + + def _recdUnavailableCb( self, objectThatSentTheSignal, md5sumOfIt, whoDoesntHaveIt ): + self.__class__.log.debug('_recdUnavailableCb: sux, we want to see that photo') + recd = self.m.getRecdByMd5( md5sumOfIt ) + if (recd == None): + self.__class__.log.debug('_recdUnavailableCb: actually, we dont even know about that one..') + return + if (recd.deleted): + self.__class__.log.debug('_recdUnavailableCb: actually, since we asked, we deleted.') + return + if (not recd.buddy): + self.__class__.log.debug('_recdUnavailableCb: uh, odd, we took that photo and have it already.') + return + if (recd.downloadedFromBuddy): + self.__class__.log.debug('_recdUnavailableCb: we already downloaded it... you might have been slow responding.') + return + if (recd.meshDownloadingFrom != whoDoesntHaveIt): + self.__class__.log.debug('_recdUnavailableCb: we arent asking you for a copy now. slow response, pbly.') + return + + #self.meshNextRoundRobinBuddy( recd ) diff --git a/recorded.py b/recorded.py index 488a01c..8639a70 100644 --- a/recorded.py +++ b/recorded.py @@ -30,144 +30,144 @@ import record class Recorded: - def __init__( self ): - self.type = -1 - self.time = None - self.recorderName = None - self.recorderHash = None - self.title = None - self.colorStroke = None - self.colorFill = None - self.mediaMd5 = None - self.thumbMd5 = None - self.mediaBytes = None - self.thumbBytes = None - self.tags = None - - #flag to alert need to re-datastore the title - self.metaChange = False - - #when you are datastore-serialized, you get one of these ids... - self.datastoreId = None - self.datastoreOb = None - - #if not from the datastore, then your media is here... - self.mediaFilename = None - self.thumbFilename = None - self.audioImageFilename = None - - #for flagging when you are being saved to the datastore for the first time... - #and just because you have a datastore id, doesn't mean you're saved - self.savedMedia = False - self.savedXml = False - - #assume you took the picture - self.buddy = False - self.downloadedFromBuddy = False - self.triedMeshBuddies = [] - self.meshDownloading = False - self.meshDownloadingFrom = "" - self.meshDownloadingFromNick = "" - self.meshDownlodingPercent = 0.0 - self.meshDownloadingProgress = False - #if someone is downloading this, then hold onto it - self.meshUploading = False - self.meshReqCallbackId = 0 - - self.deleted = False - - - def setTitle( self, newTitle ): - self.title = newTitle - self.metaChange = True - - - def setTags( self, newTags ): - self.tags = newTags - self.metaChange = True - - - def isClipboardCopyable( self ): - copyme = True - if (self.buddy): - if (not self.downloadedFromBuddy): - return False - return copyme - - - #scenarios: - #launch, your new thumb -- Journal/session - #launch, your new media -- Journal/session - #launch, their new thumb -- Journal/session/buddy - #launch, their new media -- ([request->]) Journal/session/buddy - #relaunch, your old thumb -- metadataPixbuf on request (or save to Journal/session..?) - #relaunch, your old media -- datastoreObject->file (hold onto the datastore object, delete if deleted) - #relaunch, their old thumb -- metadataPixbuf on request (or save to Journal/session..?) - #relaunch, their old media -- datastoreObject->file (hold onto the datastore object, delete if deleted) | ([request->]) Journal/session/buddy - - def getThumbPixbuf( self ): - thumbPixbuf = None - thumbFilepath = self.getThumbFilepath() - if ( os.path.isfile(thumbFilepath) ): - thumbPixbuf = gtk.gdk.pixbuf_new_from_file(thumbFilepath) - return thumbPixbuf - - - def getThumbFilepath( self ): - return os.path.join(Instance.instancePath, self.thumbFilename) - - - def getAudioImagePixbuf( self ): - audioPixbuf = None - - if (self.audioImageFilename == None): - audioPixbuf = self.getThumbPixbuf() - else: - audioFilepath = self.getAudioImageFilepath() - if (audioFilepath != None): - audioPixbuf = gtk.gdk.pixbuf_new_from_file(audioFilepath) - - return audioPixbuf - - - def getAudioImageFilepath( self ): - if (self.audioImageFilename != None): - audioFilepath = os.path.join(Instance.instancePath, self.audioImageFilename) - return os.path.abspath(audioFilepath) - else: - return self.getThumbFilepath() - - - def getMediaFilepath(self): - if (self.datastoreId == None): - if (not self.buddy): - #just taken by you, so it is in the tempSessionDir - mediaFilepath = os.path.join(Instance.instancePath, self.mediaFilename) - return os.path.abspath(mediaFilepath) - else: - if (self.downloadedFromBuddy): - #the user has requested the high-res version, and it has downloaded - mediaFilepath = os.path.join(Instance.instancePath, self.mediaFilename) - return os.path.abspath(mediaFilepath) - else: - if self.mediaFilename == None: - #creating a new filepath, probably just got here from the mesh - ext = Constants.mediaTypes[self.type][Constants.keyExt] - recdPath = os.path.join(Instance.instancePath, "recdFile_"+self.mediaMd5+"."+ext) - recdPath = utils.getUniqueFilepath(recdPath, 0) - self.mediaFilename = os.path.basename(recdPath) - mediaFilepath = os.path.join(Instance.instancePath, self.mediaFilename) - return os.path.abspath(mediaFilepath) - else: - mediaFilepath = os.path.join(Instance.instancePath, self.mediaFilename) - return os.path.abspath(mediaFilepath) - - else: #pulling from the datastore, regardless of who took it, cause we got it - #first, get the datastoreObject and hold the reference in this Recorded instance - if (self.datastoreOb == None): - self.datastoreOb = serialize.getMediaFromDatastore( self ) - if (self.datastoreOb == None): - print("RecordActivity error -- unable to get datastore object in getMediaFilepath") - return None - - return self.datastoreOb.file_path \ No newline at end of file + def __init__( self ): + self.type = -1 + self.time = None + self.recorderName = None + self.recorderHash = None + self.title = None + self.colorStroke = None + self.colorFill = None + self.mediaMd5 = None + self.thumbMd5 = None + self.mediaBytes = None + self.thumbBytes = None + self.tags = None + + #flag to alert need to re-datastore the title + self.metaChange = False + + #when you are datastore-serialized, you get one of these ids... + self.datastoreId = None + self.datastoreOb = None + + #if not from the datastore, then your media is here... + self.mediaFilename = None + self.thumbFilename = None + self.audioImageFilename = None + + #for flagging when you are being saved to the datastore for the first time... + #and just because you have a datastore id, doesn't mean you're saved + self.savedMedia = False + self.savedXml = False + + #assume you took the picture + self.buddy = False + self.downloadedFromBuddy = False + self.triedMeshBuddies = [] + self.meshDownloading = False + self.meshDownloadingFrom = "" + self.meshDownloadingFromNick = "" + self.meshDownlodingPercent = 0.0 + self.meshDownloadingProgress = False + #if someone is downloading this, then hold onto it + self.meshUploading = False + self.meshReqCallbackId = 0 + + self.deleted = False + + + def setTitle( self, newTitle ): + self.title = newTitle + self.metaChange = True + + + def setTags( self, newTags ): + self.tags = newTags + self.metaChange = True + + + def isClipboardCopyable( self ): + copyme = True + if (self.buddy): + if (not self.downloadedFromBuddy): + return False + return copyme + + + #scenarios: + #launch, your new thumb -- Journal/session + #launch, your new media -- Journal/session + #launch, their new thumb -- Journal/session/buddy + #launch, their new media -- ([request->]) Journal/session/buddy + #relaunch, your old thumb -- metadataPixbuf on request (or save to Journal/session..?) + #relaunch, your old media -- datastoreObject->file (hold onto the datastore object, delete if deleted) + #relaunch, their old thumb -- metadataPixbuf on request (or save to Journal/session..?) + #relaunch, their old media -- datastoreObject->file (hold onto the datastore object, delete if deleted) | ([request->]) Journal/session/buddy + + def getThumbPixbuf( self ): + thumbPixbuf = None + thumbFilepath = self.getThumbFilepath() + if ( os.path.isfile(thumbFilepath) ): + thumbPixbuf = gtk.gdk.pixbuf_new_from_file(thumbFilepath) + return thumbPixbuf + + + def getThumbFilepath( self ): + return os.path.join(Instance.instancePath, self.thumbFilename) + + + def getAudioImagePixbuf( self ): + audioPixbuf = None + + if (self.audioImageFilename == None): + audioPixbuf = self.getThumbPixbuf() + else: + audioFilepath = self.getAudioImageFilepath() + if (audioFilepath != None): + audioPixbuf = gtk.gdk.pixbuf_new_from_file(audioFilepath) + + return audioPixbuf + + + def getAudioImageFilepath( self ): + if (self.audioImageFilename != None): + audioFilepath = os.path.join(Instance.instancePath, self.audioImageFilename) + return os.path.abspath(audioFilepath) + else: + return self.getThumbFilepath() + + + def getMediaFilepath(self): + if (self.datastoreId == None): + if (not self.buddy): + #just taken by you, so it is in the tempSessionDir + mediaFilepath = os.path.join(Instance.instancePath, self.mediaFilename) + return os.path.abspath(mediaFilepath) + else: + if (self.downloadedFromBuddy): + #the user has requested the high-res version, and it has downloaded + mediaFilepath = os.path.join(Instance.instancePath, self.mediaFilename) + return os.path.abspath(mediaFilepath) + else: + if self.mediaFilename == None: + #creating a new filepath, probably just got here from the mesh + ext = Constants.mediaTypes[self.type][Constants.keyExt] + recdPath = os.path.join(Instance.instancePath, "recdFile_"+self.mediaMd5+"."+ext) + recdPath = utils.getUniqueFilepath(recdPath, 0) + self.mediaFilename = os.path.basename(recdPath) + mediaFilepath = os.path.join(Instance.instancePath, self.mediaFilename) + return os.path.abspath(mediaFilepath) + else: + mediaFilepath = os.path.join(Instance.instancePath, self.mediaFilename) + return os.path.abspath(mediaFilepath) + + else: #pulling from the datastore, regardless of who took it, cause we got it + #first, get the datastoreObject and hold the reference in this Recorded instance + if (self.datastoreOb == None): + self.datastoreOb = serialize.getMediaFromDatastore( self ) + if (self.datastoreOb == None): + print("RecordActivity error -- unable to get datastore object in getMediaFilepath") + return None + + return self.datastoreOb.file_path \ No newline at end of file diff --git a/recordtube.py b/recordtube.py index 5332823..7f63922 100644 --- a/recordtube.py +++ b/recordtube.py @@ -10,117 +10,117 @@ import record class RecordTube(ExportedGObject): - __gsignals__ = { - 'recd-bits-arrived': - (gobject.SIGNAL_RUN_FIRST, None, [object,object,object,object,object]), - 'recd-request': - (gobject.SIGNAL_RUN_FIRST, None, [object,object]), - 'new-recd': - (gobject.SIGNAL_RUN_FIRST, None, [object,object]), - 'recd-unavailable': - (gobject.SIGNAL_RUN_FIRST, None, [object,object]) - } - - - def __init__(self, tube): - super(RecordTube, self).__init__(tube, Constants.PATH) - self.tube = tube - - self.idNotify = self.tube.add_signal_receiver(self._newRecdTubeCb, 'notifyBudsOfNewRecd', Constants.IFACE, path=Constants.PATH, sender_keyword='sender') - self.idRequest = self.tube.add_signal_receiver(self._reqRecdTubeCb, 'requestRecdBits', Constants.IFACE, path=Constants.PATH, sender_keyword='sender') - self.idBroadcast = self.tube.add_signal_receiver(self._getRecdTubeCb, 'broadcastRecdBits', Constants.IFACE, path=Constants.PATH, sender_keyword='sender', byte_arrays=True) - self.idUnavailable = self.tube.add_signal_receiver(self._unavailableRecdTubeCb, 'unavailableRecd', Constants.IFACE, path=Constants.PATH, sender_keyword='sender') - - - @signal(dbus_interface=Constants.IFACE, signature='ss') #dual s for 2x strings - def notifyBudsOfNewRecd(self, recorder, recdXml): - record.Record.log.debug('Ive taken a new pho-ideo-audio! I hereby send you an xml thumb of said media via this interface.') - - - def _newRecdTubeCb(self, recorder, recdXml, sender=None): - record.Record.log.debug("_newRecdTubeCb from " + recorder ) - if sender == self.tube.get_unique_name(): - record.Record.log.debug("_newRecdTubeCb: sender is my bus name, so ignore my own signal") - return - elif (recorder == Instance.keyHashPrintable): - record.Record.log.debug('_newRecdTubeCb: excuse me? you are asking me to share a photo with myself?') - return - - self.emit( "new-recd", str(recorder), str(recdXml) ) - - - @signal(dbus_interface=Constants.IFACE, signature='sss') #triple s for 3x strings - def requestRecdBits(self, whoWantsIt, whoTheyWantItFrom, recdMd5sumOfIt ): - record.Record.log.debug('I am requesting a high-res version of someones media.') - - - def _reqRecdTubeCb(self, whoWantsIt, whoTheyWantItFrom, recdMd5sumOfIt, sender=None): - if sender == self.tube.get_unique_name(): - record.Record.log.debug("_reqRecdTubeCb: sender is my bus name, so ignore my own signal") - return - elif (whoWantsIt == Instance.keyHashPrintable): - record.Record.log.debug('_reqRecdTubeCb: excuse me? you are asking me to share a photo with myself?') - return - elif (whoTheyWantItFrom != Instance.keyHashPrintable): - record.Record.log.debug('_reqRecdTubeCb: ive overhead someone wants a photo, but not from me') - return - - self.emit( "recd-request", str(whoWantsIt), str(recdMd5sumOfIt) ) - - - def broadcastRecd(self, md5, filepath, sendThisTo ): - size = os.path.getsize(filepath) - f = open(filepath) - chunk_size = 1000 - chunks = size / chunk_size - if (size%chunk_size != 0): - chunks += 1 - - for chunk in range(chunks): - bytes = f.read(chunk_size) - if (chunk == 0): - record.Record.log.debug("sending " + str(chunk+1) + " of " + str(chunks) + " to " + sendThisTo ) - if (chunk == chunks-1): - record.Record.log.debug("sending " + str(chunk+1) + " of " + str(chunks) + " to " + sendThisTo ) - self.broadcastRecdBits(md5, chunk+1, chunks, bytes, sendThisTo, Instance.keyHashPrintable) - - f.close() - return True - - - @signal(dbus_interface=Constants.IFACE, signature='suuayss') - def broadcastRecdBits(self, md5, part, numparts, bytes, sendTo, fromWho ): - pass - - - def _getRecdTubeCb(self, md5, part, numparts, bytes, sentTo, fromWho, sender=None): - if sender == self.tube.get_unique_name(): - #record.Record.log.debug("_reqRecdTubeCb: sender is my bus name, so ignore my own signal") - return - if (fromWho == Instance.keyHashPrintable): - #record.Record.log.debug('_getRecdTubeCb: i dont want bits from meself, thx anyway. schizophrenic?') - return - if (sentTo != Instance.keyHashPrintable): - #record.Record.log.debug('_getRecdTubeCb: ive overhead someone sending bits, but not to me!') - return - - self.emit( "recd-bits-arrived", md5, part, numparts, bytes, fromWho ) - - - @signal(dbus_interface=Constants.IFACE, signature='sss') #triple s for 3x strings - def unavailableRecd(self, md5sumOfIt, whoDoesntHaveIt, whoAskedForIt): - record.Record.log.debug('unavailableRecd: id love to share this photo, but i am without a copy meself chum') - - - def _unavailableRecdTubeCb( self, md5sumOfIt, whoDoesntHaveIt, whoAskedForIt, sender=None): - if sender == self.tube.get_unique_name(): - record.Record.log.debug("_unavailableRecdTubeCb: sender is my bus name, so ignore my own signal") - return - if (whoDoesntHaveIt == Instance.keyHashPrintable): - record.Record.log.debug('_unavailableRecdTubeCb: yes, i know i dont have it, i just told you/me/us.') - return - if (whoAskedForIt != Instance.keyHashPrintable): - record.Record.log.debug('_unavailableRecdTubeCb: ive overheard someone doesnt have a photo, but i didnt ask for that one anyways') - return + __gsignals__ = { + 'recd-bits-arrived': + (gobject.SIGNAL_RUN_FIRST, None, [object,object,object,object,object]), + 'recd-request': + (gobject.SIGNAL_RUN_FIRST, None, [object,object]), + 'new-recd': + (gobject.SIGNAL_RUN_FIRST, None, [object,object]), + 'recd-unavailable': + (gobject.SIGNAL_RUN_FIRST, None, [object,object]) + } + + + def __init__(self, tube): + super(RecordTube, self).__init__(tube, Constants.PATH) + self.tube = tube + + self.idNotify = self.tube.add_signal_receiver(self._newRecdTubeCb, 'notifyBudsOfNewRecd', Constants.IFACE, path=Constants.PATH, sender_keyword='sender') + self.idRequest = self.tube.add_signal_receiver(self._reqRecdTubeCb, 'requestRecdBits', Constants.IFACE, path=Constants.PATH, sender_keyword='sender') + self.idBroadcast = self.tube.add_signal_receiver(self._getRecdTubeCb, 'broadcastRecdBits', Constants.IFACE, path=Constants.PATH, sender_keyword='sender', byte_arrays=True) + self.idUnavailable = self.tube.add_signal_receiver(self._unavailableRecdTubeCb, 'unavailableRecd', Constants.IFACE, path=Constants.PATH, sender_keyword='sender') + + + @signal(dbus_interface=Constants.IFACE, signature='ss') #dual s for 2x strings + def notifyBudsOfNewRecd(self, recorder, recdXml): + record.Record.log.debug('Ive taken a new pho-ideo-audio! I hereby send you an xml thumb of said media via this interface.') + + + def _newRecdTubeCb(self, recorder, recdXml, sender=None): + record.Record.log.debug("_newRecdTubeCb from " + recorder ) + if sender == self.tube.get_unique_name(): + record.Record.log.debug("_newRecdTubeCb: sender is my bus name, so ignore my own signal") + return + elif (recorder == Instance.keyHashPrintable): + record.Record.log.debug('_newRecdTubeCb: excuse me? you are asking me to share a photo with myself?') + return + + self.emit( "new-recd", str(recorder), str(recdXml) ) + + + @signal(dbus_interface=Constants.IFACE, signature='sss') #triple s for 3x strings + def requestRecdBits(self, whoWantsIt, whoTheyWantItFrom, recdMd5sumOfIt ): + record.Record.log.debug('I am requesting a high-res version of someones media.') + + + def _reqRecdTubeCb(self, whoWantsIt, whoTheyWantItFrom, recdMd5sumOfIt, sender=None): + if sender == self.tube.get_unique_name(): + record.Record.log.debug("_reqRecdTubeCb: sender is my bus name, so ignore my own signal") + return + elif (whoWantsIt == Instance.keyHashPrintable): + record.Record.log.debug('_reqRecdTubeCb: excuse me? you are asking me to share a photo with myself?') + return + elif (whoTheyWantItFrom != Instance.keyHashPrintable): + record.Record.log.debug('_reqRecdTubeCb: ive overhead someone wants a photo, but not from me') + return + + self.emit( "recd-request", str(whoWantsIt), str(recdMd5sumOfIt) ) + + + def broadcastRecd(self, md5, filepath, sendThisTo ): + size = os.path.getsize(filepath) + f = open(filepath) + chunk_size = 1000 + chunks = size / chunk_size + if (size%chunk_size != 0): + chunks += 1 + + for chunk in range(chunks): + bytes = f.read(chunk_size) + if (chunk == 0): + record.Record.log.debug("sending " + str(chunk+1) + " of " + str(chunks) + " to " + sendThisTo ) + if (chunk == chunks-1): + record.Record.log.debug("sending " + str(chunk+1) + " of " + str(chunks) + " to " + sendThisTo ) + self.broadcastRecdBits(md5, chunk+1, chunks, bytes, sendThisTo, Instance.keyHashPrintable) + + f.close() + return True + + + @signal(dbus_interface=Constants.IFACE, signature='suuayss') + def broadcastRecdBits(self, md5, part, numparts, bytes, sendTo, fromWho ): + pass + + + def _getRecdTubeCb(self, md5, part, numparts, bytes, sentTo, fromWho, sender=None): + if sender == self.tube.get_unique_name(): + #record.Record.log.debug("_reqRecdTubeCb: sender is my bus name, so ignore my own signal") + return + if (fromWho == Instance.keyHashPrintable): + #record.Record.log.debug('_getRecdTubeCb: i dont want bits from meself, thx anyway. schizophrenic?') + return + if (sentTo != Instance.keyHashPrintable): + #record.Record.log.debug('_getRecdTubeCb: ive overhead someone sending bits, but not to me!') + return + + self.emit( "recd-bits-arrived", md5, part, numparts, bytes, fromWho ) + + + @signal(dbus_interface=Constants.IFACE, signature='sss') #triple s for 3x strings + def unavailableRecd(self, md5sumOfIt, whoDoesntHaveIt, whoAskedForIt): + record.Record.log.debug('unavailableRecd: id love to share this photo, but i am without a copy meself chum') + + + def _unavailableRecdTubeCb( self, md5sumOfIt, whoDoesntHaveIt, whoAskedForIt, sender=None): + if sender == self.tube.get_unique_name(): + record.Record.log.debug("_unavailableRecdTubeCb: sender is my bus name, so ignore my own signal") + return + if (whoDoesntHaveIt == Instance.keyHashPrintable): + record.Record.log.debug('_unavailableRecdTubeCb: yes, i know i dont have it, i just told you/me/us.') + return + if (whoAskedForIt != Instance.keyHashPrintable): + record.Record.log.debug('_unavailableRecdTubeCb: ive overheard someone doesnt have a photo, but i didnt ask for that one anyways') + return - self.emit("recd-unavailable", md5sumOfIt, whoDoesntHaveIt) \ No newline at end of file + self.emit("recd-unavailable", md5sumOfIt, whoDoesntHaveIt) \ No newline at end of file diff --git a/serialize.py b/serialize.py index f86c373..7a1db27 100644 --- a/serialize.py +++ b/serialize.py @@ -15,328 +15,328 @@ import utils import recorded def fillMediaHash( index, mediaHashs ): - doc = None - if (os.path.exists(index)): - try: - doc = parse( os.path.abspath(index) ) - except: - doc = None - if (doc == None): - return + doc = None + if (os.path.exists(index)): + try: + doc = parse( os.path.abspath(index) ) + except: + doc = None + if (doc == None): + return - for key,value in Constants.mediaTypes.items(): - recdElements = doc.documentElement.getElementsByTagName(value[Constants.keyName]) - for el in recdElements: - _loadMediaIntoHash( el, mediaHashs[key] ) + for key,value in Constants.mediaTypes.items(): + recdElements = doc.documentElement.getElementsByTagName(value[Constants.keyName]) + for el in recdElements: + _loadMediaIntoHash( el, mediaHashs[key] ) def _loadMediaIntoHash( el, hash ): - addToHash = True - recd = record.Recorded() - recd = fillRecdFromNode(recd, el) - if (recd != None): - if (recd.datastoreId != None): - #quickly check: if you have a datastoreId that the file hasn't been deleted, - #cause if you do, we need to flag your removal - #2904 trac - recd.datastoreOb = getMediaFromDatastore( recd ) - if (recd.datastoreOb == None): - addToHash = False - else: - #name might have been changed in the journal, so reflect that here - if (recd.title != recd.datastoreOb.metadata['title']): - recd.setTitle(recd.datastoreOb.metadata['title']) - if (recd.tags != recd.datastoreOb.metadata['tags']): - recd.setTags(recd.datastoreOb.metadata['tags']) - if (recd.buddy): - recd.downloadedFromBuddy = True - - recd.datastoreOb == None - - if (addToHash): - hash.append( recd ) + addToHash = True + recd = record.Recorded() + recd = fillRecdFromNode(recd, el) + if (recd != None): + if (recd.datastoreId != None): + #quickly check: if you have a datastoreId that the file hasn't been deleted, + #cause if you do, we need to flag your removal + #2904 trac + recd.datastoreOb = getMediaFromDatastore( recd ) + if (recd.datastoreOb == None): + addToHash = False + else: + #name might have been changed in the journal, so reflect that here + if (recd.title != recd.datastoreOb.metadata['title']): + recd.setTitle(recd.datastoreOb.metadata['title']) + if (recd.tags != recd.datastoreOb.metadata['tags']): + recd.setTags(recd.datastoreOb.metadata['tags']) + if (recd.buddy): + recd.downloadedFromBuddy = True + + recd.datastoreOb == None + + if (addToHash): + hash.append( recd ) def getMediaFromDatastore( recd ): - if (recd.datastoreId == None): - return None + if (recd.datastoreId == None): + return None - if (recd.datastoreOb != None): - #already have the object - return recd.datastoreOb + if (recd.datastoreOb != None): + #already have the object + return recd.datastoreOb - mediaObject = None - try: - mediaObject = datastore.get( recd.datastoreId ) - finally: - if (mediaObject == None): - return None + mediaObject = None + try: + mediaObject = datastore.get( recd.datastoreId ) + finally: + if (mediaObject == None): + return None - return mediaObject + return mediaObject def removeMediaFromDatastore( recd ): - #before this method is called, the media are removed from the file - if (recd.datastoreId == None): - return - if (recd.datastoreOb == None): - return + #before this method is called, the media are removed from the file + if (recd.datastoreId == None): + return + if (recd.datastoreOb == None): + return - try: - recd.datastoreOb.destroy() - datastore.delete( recd.datastoreId ) + try: + recd.datastoreOb.destroy() + datastore.delete( recd.datastoreId ) - del recd.datastoreId - recd.datastoreId = None + del recd.datastoreId + recd.datastoreId = None - del recd.datastoreOb - recd.datastoreOb = None + del recd.datastoreOb + recd.datastoreOb = None - finally: - #todo: add error message here - pass + finally: + #todo: add error message here + pass def fillRecdFromNode( recd, el ): - if (el.getAttributeNode(Constants.recdType) != None): - typeInt = int(el.getAttribute(Constants.recdType)) - recd.type = typeInt - - if (el.getAttributeNode(Constants.recdTitle) != None): - recd.title = el.getAttribute(Constants.recdTitle) - - if (el.getAttributeNode(Constants.recdTime) != None): - timeInt = int(el.getAttribute(Constants.recdTime)) - recd.time = timeInt - - if (el.getAttributeNode(Constants.recdRecorderName) != None): - recd.recorderName = el.getAttribute(Constants.recdRecorderName) - - if (el.getAttributeNode(Constants.recdTags) != None): - recd.tags = el.getAttribute(Constants.recdTags) - else: - recd.tags = "" - - if (el.getAttributeNode(Constants.recdRecorderHash) != None): - recd.recorderHash = el.getAttribute(Constants.recdRecorderHash) - - if (el.getAttributeNode(Constants.recdColorStroke) != None): - try: - colorStrokeHex = el.getAttribute(Constants.recdColorStroke) - colorStroke = Color() - colorStroke.init_hex(colorStrokeHex) - recd.colorStroke = colorStroke - except: - record.Record.log.error("unable to load recd colorStroke") - - if (el.getAttributeNode(Constants.recdColorFill) != None): - try: - colorFillHex = el.getAttribute(Constants.recdColorFill) - colorFill = Color() - colorFill.init_hex( colorFillHex ) - recd.colorFill = colorFill - except: - record.Record.log.error("unable to load recd colorFill") - - if (el.getAttributeNode(Constants.recdBuddy) != None): - recd.buddy = (el.getAttribute(Constants.recdBuddy) == "True") - - if (el.getAttributeNode(Constants.recdMediaMd5) != None): - recd.mediaMd5 = el.getAttribute(Constants.recdMediaMd5) - - if (el.getAttributeNode(Constants.recdThumbMd5) != None): - recd.thumbMd5 = el.getAttribute(Constants.recdThumbMd5) - - if (el.getAttributeNode(Constants.recdMediaBytes) != None): - recd.mediaBytes = el.getAttribute(Constants.recdMediaBytes) - - if (el.getAttributeNode(Constants.recdThumbBytes) != None): - recd.thumbBytes = el.getAttribute(Constants.recdThumbBytes) - - bt = el.getAttributeNode(Constants.recdBase64Thumb) - if (bt != None): - try: - thumbPath = os.path.join(Instance.instancePath, "datastoreThumb.jpg") - thumbPath = utils.getUniqueFilepath( thumbPath, 0 ) - thumbImg = utils.getPixbufFromString( bt.nodeValue ) - thumbImg.save(thumbPath, "jpeg", {"quality":"85"} ) - recd.thumbFilename = os.path.basename(thumbPath) - record.Record.log.debug("saved thumbFilename") - except: - record.Record.log.error("unable to getRecdBase64Thumb") - - ai = el.getAttributeNode(Constants.recdAudioImage) - if (not ai == None): - try: - audioImagePath = os.path.join(Instance.instancePath, "audioImage.png") - audioImagePath = utils.getUniqueFilepath( audioImagePath, 0 ) - audioImage = utils.getPixbufFromString( ai.nodeValue ) - audioImage.save(audioImagePath, "png", {} ) - recd.audioImageFilename = os.path.basename(audioImagePath) - record.Record.log.debug("loaded audio image and set audioImageFilename") - except: - record.Record.log.error("unable to load audio image") - - datastoreNode = el.getAttributeNode(Constants.recdDatastoreId) - if (datastoreNode != None): - recd.datastoreId = datastoreNode.nodeValue - - return recd + if (el.getAttributeNode(Constants.recdType) != None): + typeInt = int(el.getAttribute(Constants.recdType)) + recd.type = typeInt + + if (el.getAttributeNode(Constants.recdTitle) != None): + recd.title = el.getAttribute(Constants.recdTitle) + + if (el.getAttributeNode(Constants.recdTime) != None): + timeInt = int(el.getAttribute(Constants.recdTime)) + recd.time = timeInt + + if (el.getAttributeNode(Constants.recdRecorderName) != None): + recd.recorderName = el.getAttribute(Constants.recdRecorderName) + + if (el.getAttributeNode(Constants.recdTags) != None): + recd.tags = el.getAttribute(Constants.recdTags) + else: + recd.tags = "" + + if (el.getAttributeNode(Constants.recdRecorderHash) != None): + recd.recorderHash = el.getAttribute(Constants.recdRecorderHash) + + if (el.getAttributeNode(Constants.recdColorStroke) != None): + try: + colorStrokeHex = el.getAttribute(Constants.recdColorStroke) + colorStroke = Color() + colorStroke.init_hex(colorStrokeHex) + recd.colorStroke = colorStroke + except: + record.Record.log.error("unable to load recd colorStroke") + + if (el.getAttributeNode(Constants.recdColorFill) != None): + try: + colorFillHex = el.getAttribute(Constants.recdColorFill) + colorFill = Color() + colorFill.init_hex( colorFillHex ) + recd.colorFill = colorFill + except: + record.Record.log.error("unable to load recd colorFill") + + if (el.getAttributeNode(Constants.recdBuddy) != None): + recd.buddy = (el.getAttribute(Constants.recdBuddy) == "True") + + if (el.getAttributeNode(Constants.recdMediaMd5) != None): + recd.mediaMd5 = el.getAttribute(Constants.recdMediaMd5) + + if (el.getAttributeNode(Constants.recdThumbMd5) != None): + recd.thumbMd5 = el.getAttribute(Constants.recdThumbMd5) + + if (el.getAttributeNode(Constants.recdMediaBytes) != None): + recd.mediaBytes = el.getAttribute(Constants.recdMediaBytes) + + if (el.getAttributeNode(Constants.recdThumbBytes) != None): + recd.thumbBytes = el.getAttribute(Constants.recdThumbBytes) + + bt = el.getAttributeNode(Constants.recdBase64Thumb) + if (bt != None): + try: + thumbPath = os.path.join(Instance.instancePath, "datastoreThumb.jpg") + thumbPath = utils.getUniqueFilepath( thumbPath, 0 ) + thumbImg = utils.getPixbufFromString( bt.nodeValue ) + thumbImg.save(thumbPath, "jpeg", {"quality":"85"} ) + recd.thumbFilename = os.path.basename(thumbPath) + record.Record.log.debug("saved thumbFilename") + except: + record.Record.log.error("unable to getRecdBase64Thumb") + + ai = el.getAttributeNode(Constants.recdAudioImage) + if (not ai == None): + try: + audioImagePath = os.path.join(Instance.instancePath, "audioImage.png") + audioImagePath = utils.getUniqueFilepath( audioImagePath, 0 ) + audioImage = utils.getPixbufFromString( ai.nodeValue ) + audioImage.save(audioImagePath, "png", {} ) + recd.audioImageFilename = os.path.basename(audioImagePath) + record.Record.log.debug("loaded audio image and set audioImageFilename") + except: + record.Record.log.error("unable to load audio image") + + datastoreNode = el.getAttributeNode(Constants.recdDatastoreId) + if (datastoreNode != None): + recd.datastoreId = datastoreNode.nodeValue + + return recd def getRecdXmlMeshString( recd ): - impl = getDOMImplementation() - recdXml = impl.createDocument(None, Constants.recdRecd, None) - root = recdXml.documentElement - _addRecdXmlAttrs( root, recd, True ) + impl = getDOMImplementation() + recdXml = impl.createDocument(None, Constants.recdRecd, None) + root = recdXml.documentElement + _addRecdXmlAttrs( root, recd, True ) - writer = cStringIO.StringIO() - recdXml.writexml(writer) - return writer.getvalue() + writer = cStringIO.StringIO() + recdXml.writexml(writer) + return writer.getvalue() def _addRecdXmlAttrs( el, recd, forMeshTransmit ): - el.setAttribute(Constants.recdType, str(recd.type)) - - if ((recd.type == Constants.TYPE_AUDIO) and (not forMeshTransmit)): - aiPixbuf = recd.getAudioImagePixbuf( ) - aiPixbufString = str( utils.getStringFromPixbuf(aiPixbuf) ) - el.setAttribute(Constants.recdAudioImage, aiPixbufString) - - if ((recd.datastoreId != None) and (not forMeshTransmit)): - el.setAttribute(Constants.recdDatastoreId, str(recd.datastoreId)) - - el.setAttribute(Constants.recdTitle, recd.title) - el.setAttribute(Constants.recdTime, str(recd.time)) - el.setAttribute(Constants.recdRecorderName, recd.recorderName) - el.setAttribute(Constants.recdRecorderHash, str(recd.recorderHash) ) - el.setAttribute(Constants.recdColorStroke, str(recd.colorStroke.hex) ) - el.setAttribute(Constants.recdColorFill, str(recd.colorFill.hex) ) - el.setAttribute(Constants.recdBuddy, str(recd.buddy)) - el.setAttribute(Constants.recdMediaMd5, str(recd.mediaMd5)) - el.setAttribute(Constants.recdThumbMd5, str(recd.thumbMd5)) - el.setAttribute(Constants.recdMediaBytes, str(recd.mediaBytes)) - el.setAttribute(Constants.recdThumbBytes, str(recd.thumbBytes)) - el.setAttribute(Constants.recdRecordVersion, str(Constants.VERSION)) - - pixbuf = recd.getThumbPixbuf( ) - thumb64 = str( utils.getStringFromPixbuf(pixbuf) ) - el.setAttribute(Constants.recdBase64Thumb, thumb64) + el.setAttribute(Constants.recdType, str(recd.type)) + + if ((recd.type == Constants.TYPE_AUDIO) and (not forMeshTransmit)): + aiPixbuf = recd.getAudioImagePixbuf( ) + aiPixbufString = str( utils.getStringFromPixbuf(aiPixbuf) ) + el.setAttribute(Constants.recdAudioImage, aiPixbufString) + + if ((recd.datastoreId != None) and (not forMeshTransmit)): + el.setAttribute(Constants.recdDatastoreId, str(recd.datastoreId)) + + el.setAttribute(Constants.recdTitle, recd.title) + el.setAttribute(Constants.recdTime, str(recd.time)) + el.setAttribute(Constants.recdRecorderName, recd.recorderName) + el.setAttribute(Constants.recdRecorderHash, str(recd.recorderHash) ) + el.setAttribute(Constants.recdColorStroke, str(recd.colorStroke.hex) ) + el.setAttribute(Constants.recdColorFill, str(recd.colorFill.hex) ) + el.setAttribute(Constants.recdBuddy, str(recd.buddy)) + el.setAttribute(Constants.recdMediaMd5, str(recd.mediaMd5)) + el.setAttribute(Constants.recdThumbMd5, str(recd.thumbMd5)) + el.setAttribute(Constants.recdMediaBytes, str(recd.mediaBytes)) + el.setAttribute(Constants.recdThumbBytes, str(recd.thumbBytes)) + el.setAttribute(Constants.recdRecordVersion, str(Constants.VERSION)) + + pixbuf = recd.getThumbPixbuf( ) + thumb64 = str( utils.getStringFromPixbuf(pixbuf) ) + el.setAttribute(Constants.recdBase64Thumb, thumb64) def saveMediaHash( mediaHashs ): - impl = getDOMImplementation() - album = impl.createDocument(None, Constants.recdAlbum, None) - root = album.documentElement - - #flag everything for saving... - atLeastOne = False - for type,value in Constants.mediaTypes.items(): - typeName = value[Constants.keyName] - hash = mediaHashs[type] - for i in range (0, len(hash)): - recd = hash[i] - recd.savedXml = False - recd.savedMedia = False - atLeastOne = True - - #and if there is anything to save, save it - if (atLeastOne): - for type,value in Constants.mediaTypes.items(): - typeName = value[Constants.keyName] - hash = mediaHashs[type] - - for i in range (0, len(hash)): - recd = hash[i] - mediaEl = album.createElement( typeName ) - root.appendChild( mediaEl ) - _saveMedia( mediaEl, recd ) - - return album + impl = getDOMImplementation() + album = impl.createDocument(None, Constants.recdAlbum, None) + root = album.documentElement + + #flag everything for saving... + atLeastOne = False + for type,value in Constants.mediaTypes.items(): + typeName = value[Constants.keyName] + hash = mediaHashs[type] + for i in range (0, len(hash)): + recd = hash[i] + recd.savedXml = False + recd.savedMedia = False + atLeastOne = True + + #and if there is anything to save, save it + if (atLeastOne): + for type,value in Constants.mediaTypes.items(): + typeName = value[Constants.keyName] + hash = mediaHashs[type] + + for i in range (0, len(hash)): + recd = hash[i] + mediaEl = album.createElement( typeName ) + root.appendChild( mediaEl ) + _saveMedia( mediaEl, recd ) + + return album def _saveMedia( el, recd ): - if ( (recd.buddy == True) and (recd.datastoreId == None) and (not recd.downloadedFromBuddy) ): - recd.savedMedia = True - _saveXml( el, recd ) - else: - recd.savedMedia = False - _saveMediaToDatastore( el, recd ) + if ( (recd.buddy == True) and (recd.datastoreId == None) and (not recd.downloadedFromBuddy) ): + recd.savedMedia = True + _saveXml( el, recd ) + else: + recd.savedMedia = False + _saveMediaToDatastore( el, recd ) def _saveXml( el, recd ): - if (recd.thumbFilename != None): - _addRecdXmlAttrs( el, recd, False ) - else: - record.Record.log.debug("WOAH, ERROR: recd has no thumbFilename?! " + str(recd) ) - recd.savedXml = True + if (recd.thumbFilename != None): + _addRecdXmlAttrs( el, recd, False ) + else: + record.Record.log.debug("WOAH, ERROR: recd has no thumbFilename?! " + str(recd) ) + recd.savedXml = True def _saveMediaToDatastore( el, recd ): - #note that we update the recds that go through here to how they would - #look on a fresh load from file since this won't just happen on close() - - if (recd.datastoreId != None): - #already saved to the datastore, don't need to re-rewrite the file since the mediums are immutable - #However, they might have changed the name of the file - if (recd.metaChange): - recd.datastoreOb = getMediaFromDatastore( recd ) - if (recd.datastoreOb.metadata['title'] != recd.title): - recd.datastoreOb.metadata['title'] = recd.title - datastore.write(recd.datastoreOb) - if (recd.datastoreOb.metadata['tags'] != recd.tags): - recd.datastoreOb.metadata['tags'] = recd.tags - datastore.write(recd.datastoreOb) - - #reset for the next title change if not closing... - recd.metaChange = False - #save the title to the xml - recd.savedMedia = True - _saveXml( el, recd ) - else: - recd.savedMedia = True - _saveXml( el, recd ) - - else: - #this will remove the media from being accessed on the local disk since it puts it away into cold storage - #therefore this is only called when write_file is called by the activity superclass - mediaObject = datastore.create() - mediaObject.metadata['title'] = recd.title - mediaObject.metadata['tags'] = recd.tags - - datastorePreviewPixbuf = recd.getThumbPixbuf() - if (recd.type == Constants.TYPE_AUDIO): - datastorePreviewPixbuf = recd.getAudioImagePixbuf() - elif (recd.type == Constants.TYPE_PHOTO): - datastorePreviewFilepath = recd.getMediaFilepath() - datastorePreviewPixbuf = gtk.gdk.pixbuf_new_from_file(datastorePreviewFilepath) - - datastorePreviewWidth = 300 - datastorePreviewHeight = 225 - if (datastorePreviewPixbuf.get_width() != datastorePreviewWidth): - datastorePreviewPixbuf = datastorePreviewPixbuf.scale_simple(datastorePreviewWidth, datastorePreviewHeight, gtk.gdk.INTERP_NEAREST) - - datastorePreviewBase64 = utils.getStringFromPixbuf(datastorePreviewPixbuf) - mediaObject.metadata['preview'] = datastorePreviewBase64 - - colors = str(recd.colorStroke.hex) + "," + str(recd.colorFill.hex) - mediaObject.metadata['icon-color'] = colors - - mtype = Constants.mediaTypes[recd.type] - mime = mtype[Constants.keyMime] - mediaObject.metadata['mime_type'] = mime - - mediaObject.metadata['activity_id'] = Constants.activityId - - mediaFile = recd.getMediaFilepath() - mediaObject.file_path = mediaFile - mediaObject.transfer_ownership = True - - datastore.write( mediaObject ) - - recd.datastoreId = mediaObject.object_id - recd.savedMedia = True - - _saveXml( el, recd ) - - recd.mediaFilename = None \ No newline at end of file + #note that we update the recds that go through here to how they would + #look on a fresh load from file since this won't just happen on close() + + if (recd.datastoreId != None): + #already saved to the datastore, don't need to re-rewrite the file since the mediums are immutable + #However, they might have changed the name of the file + if (recd.metaChange): + recd.datastoreOb = getMediaFromDatastore( recd ) + if (recd.datastoreOb.metadata['title'] != recd.title): + recd.datastoreOb.metadata['title'] = recd.title + datastore.write(recd.datastoreOb) + if (recd.datastoreOb.metadata['tags'] != recd.tags): + recd.datastoreOb.metadata['tags'] = recd.tags + datastore.write(recd.datastoreOb) + + #reset for the next title change if not closing... + recd.metaChange = False + #save the title to the xml + recd.savedMedia = True + _saveXml( el, recd ) + else: + recd.savedMedia = True + _saveXml( el, recd ) + + else: + #this will remove the media from being accessed on the local disk since it puts it away into cold storage + #therefore this is only called when write_file is called by the activity superclass + mediaObject = datastore.create() + mediaObject.metadata['title'] = recd.title + mediaObject.metadata['tags'] = recd.tags + + datastorePreviewPixbuf = recd.getThumbPixbuf() + if (recd.type == Constants.TYPE_AUDIO): + datastorePreviewPixbuf = recd.getAudioImagePixbuf() + elif (recd.type == Constants.TYPE_PHOTO): + datastorePreviewFilepath = recd.getMediaFilepath() + datastorePreviewPixbuf = gtk.gdk.pixbuf_new_from_file(datastorePreviewFilepath) + + datastorePreviewWidth = 300 + datastorePreviewHeight = 225 + if (datastorePreviewPixbuf.get_width() != datastorePreviewWidth): + datastorePreviewPixbuf = datastorePreviewPixbuf.scale_simple(datastorePreviewWidth, datastorePreviewHeight, gtk.gdk.INTERP_NEAREST) + + datastorePreviewBase64 = utils.getStringFromPixbuf(datastorePreviewPixbuf) + mediaObject.metadata['preview'] = datastorePreviewBase64 + + colors = str(recd.colorStroke.hex) + "," + str(recd.colorFill.hex) + mediaObject.metadata['icon-color'] = colors + + mtype = Constants.mediaTypes[recd.type] + mime = mtype[Constants.keyMime] + mediaObject.metadata['mime_type'] = mime + + mediaObject.metadata['activity_id'] = Constants.activityId + + mediaFile = recd.getMediaFilepath() + mediaObject.file_path = mediaFile + mediaObject.transfer_ownership = True + + datastore.write( mediaObject ) + + recd.datastoreId = mediaObject.object_id + recd.savedMedia = True + + _saveXml( el, recd ) + + recd.mediaFilename = None \ No newline at end of file diff --git a/ui.py b/ui.py index 6f715f4..eca4fb1 100644 --- a/ui.py +++ b/ui.py @@ -62,2302 +62,2302 @@ from toolbarcombobox import ToolComboBox class UI: - dim_THUMB_WIDTH = 108 - dim_THUMB_HEIGHT = 81 - dim_INSET = 10 - dim_PIPW = 160 - dim_PIPH = 120 #pipBorder - dim_PIP_BORDER = 4 - dim_PGDW = dim_PIPW + (dim_PIP_BORDER*2) - dim_PGDH = dim_PIPH + (dim_PIP_BORDER*2) - dim_CONTROLBAR_HT = 55 - - def __init__( self, pca ): - self.ca = pca - self.ACTIVE = False - self.LAUNCHING = True - self.ca.add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) - self.ca.connect("visibility-notify-event", self._visibleNotifyCb) - - self.inset = self.__class__.dim_INSET - self.pgdh = self.__class__.dim_PGDH - self.pgdw = self.__class__.dim_PGDW - self.thumbTrayHt = 150 #todo: get sugar constant here - self.thumbSvgW = 124 - self.thumbSvgH = 124 - self.maxw = 49 - self.maxh = 49 - self.controlBarHt = 60 - self.recordButtWd = 55 - self.pipw = self.__class__.dim_PIPW - self.piph = self.__class__.dim_PIPH - - #ui modes - - # True when we're in full-screen mode, False otherwise - self.FULLSCREEN = False - - # True when we're showing live video feed in the primary screen - # area, False otherwise (even when we are still showing live video - # in a p-i-p) - self.LIVEMODE = True - - self.LAST_MODE = -1 - self.LAST_FULLSCREEN = False - self.LAST_LIVE = True - self.LAST_MESHING = False - self.LAST_RECD_INFO = False - self.LAST_TRANSCODING = False - self.TRANSCODING = False - self.MESHING = False - - # RECD_INFO_ON is True when the 'info' for a recording is being - # display on-screen (who recorded it, tags, etc), and False otherwise. - self.RECD_INFO_ON = False - - self.UPDATE_DURATION_ID = 0 - self.UPDATE_TIMER_ID = 0 - self.COUNTINGDOWN = False - - #init - self.mapped = False - self.centered = False - self.setup = False - - #prep for when to show - self.shownRecd = None - - #this includes the default sharing tab - self.toolbox = activity.ActivityToolbox(self.ca) - self.ca.set_toolbox(self.toolbox) - self.photoToolbar = PhotoToolbar() - self.photoToolbar.set_sensitive( False ) - self.toolbox.add_toolbar( Constants.istrPhoto, self.photoToolbar ) - self.videoToolbar = VideoToolbar() - self.videoToolbar.set_sensitive( False ) - self.toolbox.add_toolbar( Constants.istrVideo, self.videoToolbar ) - self.audioToolbar = AudioToolbar() - self.audioToolbar.set_sensitive( False ) - self.toolbox.add_toolbar( Constants.istrAudio, self.audioToolbar ) - self.tbars = {Constants.MODE_PHOTO:self.photoToolbar,Constants.MODE_VIDEO:self.videoToolbar,Constants.MODE_AUDIO:self.audioToolbar} - self.toolbox.set_current_toolbar(self.ca.m.MODE+1) - - self.toolbox.remove(self.toolbox._separator) - #taken directly from toolbox.py b/c I don't know how to mod the hongry hippo - separator = hippo.Canvas() - box = hippo.CanvasBox( - border_color=Constants.colorBlack.get_int(), - background_color=Constants.colorBlack.get_int(), - box_height=style.TOOLBOX_SEPARATOR_HEIGHT, - border_bottom=style.LINE_WIDTH) - separator.set_root(box) - self.toolbox.pack_start(separator, False) - self.toolbox.separator = separator - - self.TOOLBOX_SIZE_ALLOCATE_ID = self.toolbox.connect_after("size-allocate", self._toolboxSizeAllocateCb) - self.toolbox._notebook.set_property("can-focus", False) - self.toolbox.connect("current-toolbar-changed", self._toolbarChangeCb) - self.toolbox.show_all() - - - def _toolboxSizeAllocateCb( self, widget, event ): - self.toolbox.disconnect( self.TOOLBOX_SIZE_ALLOCATE_ID) - - toolboxHt = self.toolbox.size_request()[1] - self.vh = gtk.gdk.screen_height()-(self.thumbTrayHt+toolboxHt+self.controlBarHt) - self.vw = int(self.vh/.75) - self.letterBoxW = (gtk.gdk.screen_width() - self.vw)/2 - self.letterBoxVW = (self.vw/2)-(self.inset*2) - self.letterBoxVH = int(self.letterBoxVW*.75) - - self.setUpWindows() - - #now that we know how big the toolbox is, we can layout more - gobject.idle_add( self.layout ) - - - def layout( self ): - self.mainBox = gtk.VBox() - self.ca.set_canvas(self.mainBox) - - topBox = gtk.HBox() - self.mainBox.pack_start(topBox, expand=True) - - leftFill = gtk.VBox() - leftFill.set_size_request( self.letterBoxW, -1 ) - self.leftFillBox = gtk.EventBox( ) - self.leftFillBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - leftFill.add( self.leftFillBox ) - - topBox.pack_start( leftFill, expand=True ) - - centerVBox = gtk.VBox() - centerVBox.modify_bg(gtk.STATE_NORMAL, Constants.colorBlack.gColor) - topBox.pack_start( centerVBox, expand=True ) - self.centerBox = gtk.EventBox() - self.centerBox.set_size_request(self.vw, -1) - self.centerBox.modify_bg(gtk.STATE_NORMAL, Constants.colorBlack.gColor) - centerVBox.pack_start( self.centerBox, expand=True ) - centerSizer = gtk.VBox() - centerSizer.set_size_request(self.vw, -1) - centerSizer.modify_bg(gtk.STATE_NORMAL, Constants.colorBlack.gColor) - self.centerBox.add(centerSizer) - - self.bottomCenter = gtk.EventBox() - self.bottomCenter.modify_bg(gtk.STATE_NORMAL, Constants.colorBlack.gColor) - self.bottomCenter.set_size_request(self.vw, self.controlBarHt) - centerVBox.pack_start( self.bottomCenter, expand=False ) - - #into the center box we can put this guy... - self.backgdCanvasBox = gtk.VBox() - self.backgdCanvasBox.modify_bg(gtk.STATE_NORMAL, Constants.colorBlack.gColor) - self.backgdCanvasBox.set_size_request(self.vw, -1) - self.backgdCanvas = PhotoCanvas() - self.backgdCanvas.set_size_request(self.vw, self.vh) - self.backgdCanvasBox.pack_start( self.backgdCanvas, expand=False ) - - #or this guy... - self.infoBox = gtk.EventBox() - self.infoBox.modify_bg( gtk.STATE_NORMAL, Constants.colorButton.gColor ) - iinfoBox = gtk.VBox(spacing=self.inset) - self.infoBox.add( iinfoBox ) - iinfoBox.set_size_request(self.vw, -1) - iinfoBox.set_border_width(self.inset) - - rightFill = gtk.VBox() - rightFill.set_size_request( self.letterBoxW, -1 ) - rightFillBox = gtk.EventBox() - rightFillBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - rightFill.add( rightFillBox ) - topBox.pack_start( rightFill, expand=True ) - - #info box innards: - self.infoBoxTop = gtk.HBox() - iinfoBox.pack_start( self.infoBoxTop, expand=True ) - self.infoBoxTopLeft = gtk.VBox(spacing=self.inset) - self.infoBoxTop.pack_start( self.infoBoxTopLeft ) - self.infoBoxTopRight = gtk.VBox() - self.infoBoxTopRight.set_size_request(self.letterBoxVW, -1) - self.infoBoxTop.pack_start( self.infoBoxTopRight ) - - self.namePanel = gtk.HBox() - leftInfBalance = gtk.VBox() - self.nameLabel = gtk.Label(""+Constants.istrTitle+"") - self.nameLabel.set_use_markup( True ) - self.namePanel.pack_start( self.nameLabel, expand=False, padding=self.inset ) - self.nameLabel.set_alignment(0, .5) - self.nameTextfield = gtk.Entry(140) - self.nameTextfield.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) - self.nameTextfield.connect('changed', self._nameTextfieldEditedCb ) - self.nameTextfield.set_alignment(0) - self.nameTextfield.set_size_request( -1, self.controlBarHt-(self.inset*2) ) - self.namePanel.pack_start(self.nameTextfield) - - self.photographerPanel = gtk.VBox(spacing=self.inset) - self.infoBoxTopLeft.pack_start(self.photographerPanel, expand=False) - photographerLabel = gtk.Label("" + Constants.istrRecorder + "") - photographerLabel.set_use_markup( True ) - self.photographerPanel.pack_start(photographerLabel, expand=False) - photographerLabel.set_alignment(0, .5) - photoNamePanel = gtk.HBox(spacing=self.inset) - self.photographerPanel.pack_start(photoNamePanel) - - self.photoXoPanel = xoPanel() - photoNamePanel.pack_start( self.photoXoPanel, expand=False ) - self.photoXoPanel.set_size_request( 40, 40 ) - - self.photographerNameLabel = gtk.Label("") - self.photographerNameLabel.set_alignment(0, .5) - photoNamePanel.pack_start(self.photographerNameLabel) - - self.datePanel = gtk.HBox(spacing=self.inset) - self.infoBoxTopLeft.pack_start(self.datePanel, expand=False) - dateLabel = gtk.Label(""+Constants.istrDate+"") - dateLabel.set_use_markup(True) - self.datePanel.pack_start(dateLabel, expand=False) - self.dateDateLabel = gtk.Label("") - self.dateDateLabel.set_alignment(0, .5) - self.datePanel.pack_start(self.dateDateLabel) - - self.tagsPanel = gtk.VBox(spacing=self.inset) - tagsLabel = gtk.Label(""+Constants.istrTags+"") - tagsLabel.set_use_markup(True) - tagsLabel.set_alignment(0, .5) - self.tagsPanel.pack_start(tagsLabel, expand=False) - self.tagsBuffer = gtk.TextBuffer() - self.tagsBuffer.connect('changed', self._tagsBufferEditedCb) - self.tagsField = gtk.TextView(self.tagsBuffer) - self.tagsField.set_size_request( 100, 100 ) - self.tagsPanel.pack_start(self.tagsField, expand=True) - self.infoBoxTopLeft.pack_start(self.tagsPanel, expand=True) - - infoBotBox = gtk.HBox() - infoBotBox.set_size_request( -1, self.pgdh+self.inset ) - iinfoBox.pack_start(infoBotBox, expand=False) - - thumbnailsEventBox = gtk.EventBox() - thumbnailsEventBox.set_size_request( -1, self.thumbTrayHt ) - thumbnailsBox = gtk.HBox( ) - thumbnailsEventBox.add( thumbnailsBox ) - - self.thumbTray = HTray() - self.thumbTray.set_size_request( -1, self.thumbTrayHt ) - self.mainBox.pack_end( self.thumbTray, expand=False ) - self.thumbTray.show() - - self.CENTER_SIZE_ALLOCATE_ID = self.centerBox.connect_after("size-allocate", self._centerSizeAllocateCb) - self.ca.show_all() - - - def _centerSizeAllocateCb( self, widget, event ): - #initial setup of the panels - self.centerBox.disconnect(self.CENTER_SIZE_ALLOCATE_ID) - self.centerBoxPos = self.centerBox.translate_coordinates( self.ca, 0, 0 ) - - centerKid = self.centerBox.get_child() - if (centerKid != None): - self.centerBox.remove( centerKid ) - - self.centered = True - self.setUp() - - - def _mapEventCb( self, widget, event ): - #when your parent window is ready, turn on the feed of live video - self.liveVideoWindow.disconnect(self.MAP_EVENT_ID) - self.mapped = True - self.setUp() - - - def setUp( self ): - if (self.mapped and self.centered and not self.setup): - self.setup = True - - #set correct window sizes - self.setUpWindowsSizes() - - #listen for ctrl+c & game key buttons - self.ca.connect('key-press-event', self._keyPressEventCb) - #overlay widgets can go away after they've been on screen for a while - self.HIDE_WIDGET_TIMEOUT_ID = 0 - self.hiddenWidgets = False - self.resetWidgetFadeTimer() - self.showLiveVideoTags() - - self.photoToolbar.set_sensitive( True ) - self.videoToolbar.set_sensitive( True ) - self.audioToolbar.set_sensitive( True ) - - #initialize the app with the default thumbs - self.ca.m.setupMode( self.ca.m.MODE, False ) - - gobject.idle_add( self.finalSetUp ) - - - def finalSetUp( self ): - self.LAUNCHING = False - self.ACTIVE = self.ca.get_property( "visible" ) - self.updateVideoComponents() - - if (self.ACTIVE): - self.ca.glive.play() - - - def setUpWindows( self ): - #image windows - self.windowStack = [] - - #live video windows - self.livePhotoWindow = gtk.Window() - self.livePhotoWindow.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - self.livePhotoWindow.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) - self.addToWindowStack( self.livePhotoWindow, self.ca ) - self.livePhotoCanvas = PhotoCanvas() - self.livePhotoWindow.add(self.livePhotoCanvas) - self.livePhotoWindow.connect("button_release_event", self._mediaClickedForPlayback) - self.livePhotoWindow.add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) - self.livePhotoWindow.connect("visibility-notify-event", self._visibleNotifyCb) - - #video playback windows - self.playOggWindow = PlayVideoWindow(Constants.colorBlack.gColor) - self.addToWindowStack( self.playOggWindow, self.windowStack[len(self.windowStack)-1] ) - #self.playOggWindow.set_gplay(self.ca.gplay) - self.ca.gplay.window = self.playOggWindow - self.playOggWindow.set_events(gtk.gdk.BUTTON_RELEASE_MASK) - self.playOggWindow.connect("button_release_event", self._mediaClickedForPlayback) - self.playOggWindow.add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) - self.playOggWindow.connect("visibility-notify-event", self._visibleNotifyCb) - - #border behind - self.pipBgdWindow = gtk.Window() - self.pipBgdWindow.modify_bg( gtk.STATE_NORMAL, Constants.colorWhite.gColor ) - self.pipBgdWindow.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorWhite.gColor ) - self.addToWindowStack( self.pipBgdWindow, self.windowStack[len(self.windowStack)-1] ) - - self.liveVideoWindow = LiveVideoWindow(Constants.colorBlack.gColor) - self.addToWindowStack( self.liveVideoWindow, self.windowStack[len(self.windowStack)-1] ) - self.liveVideoWindow.set_glive(self.ca.glive) - self.liveVideoWindow.set_events(gtk.gdk.BUTTON_RELEASE_MASK) - self.liveVideoWindow.connect("button_release_event", self._liveButtonReleaseCb) - self.liveVideoWindow.add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) - self.liveVideoWindow.connect("visibility-notify-event", self._visibleNotifyCb) - - self.slowLiveVideoWindow = SlowLiveVideoWindow(Constants.colorBlack.gColor) - self.addToWindowStack( self.slowLiveVideoWindow, self.windowStack[len(self.windowStack)-1] ) - self.slowLiveVideoWindow.set_glivex(self.ca.glivex) - self.slowLiveVideoWindow.set_events(gtk.gdk.BUTTON_RELEASE_MASK) - self.slowLiveVideoWindow.connect("button_release_event", self._returnButtonReleaseCb) - self.slowLiveVideoWindow.add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) - self.slowLiveVideoWindow.connect("visibility-notify-event", self._visibleNotifyCb) - - self.recordWindow = RecordWindow(self) - self.addToWindowStack( self.recordWindow, self.windowStack[len(self.windowStack)-1] ) - - self.progressWindow = ProgressWindow(self) - self.addToWindowStack( self.progressWindow, self.windowStack[len(self.windowStack)-1] ) - - self.maxWindow = gtk.Window() - self.maxWindow.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - self.maxWindow.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) - maxButton = MaxButton(self) - self.maxWindow.add( maxButton ) - self.addToWindowStack( self.maxWindow, self.windowStack[len(self.windowStack)-1] ) - - self.scrubWindow = ScrubberWindow(self) - self.addToWindowStack( self.scrubWindow, self.windowStack[len(self.windowStack)-1] ) - - self.infWindow = gtk.Window() - self.infWindow.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - self.infWindow.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) - infButton= InfButton(self) - self.infWindow.add(infButton) - self.addToWindowStack( self.infWindow, self.windowStack[len(self.windowStack)-1] ) - - self.hideAllWindows() - self.MAP_EVENT_ID = self.liveVideoWindow.connect_after("map-event", self._mapEventCb) - for i in range (0, len(self.windowStack)): -# self.windowStack[i].add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) -# self.windowStack[i].connect("visibility-notify-event", self._visibleNotifyCb) - self.windowStack[i].show_all() - - - def _visibleNotifyCb( self, widget, event ): - - if (self.LAUNCHING): - return - - temp_ACTIVE = True - - if (event.state == gtk.gdk.VISIBILITY_FULLY_OBSCURED): - - if (not self.FULLSCREEN): - if (widget == self.ca): - temp_ACTIVE = False - - else: - if (self.ca.m.MODE == Constants.MODE_PHOTO): - if (not self.LIVEMODE and widget == self.livePhotoWindow): - temp_ACTIVE = False - if ( self.LIVEMODE and widget == self.liveVideoWindow): - temp_ACTIVE = False - - if (self.ca.m.MODE == Constants.MODE_VIDEO): - if (not self.LIVEMODE and widget == self.playOggWindow): - temp_ACTIVE = False - if ( self.LIVEMODE and widget == self.liveVideoWindow): - temp_ACTIVE = False - - - if (temp_ACTIVE != self.ACTIVE): - self.ACTIVE = temp_ACTIVE - if (self.ACTIVE): - self.ca.restartPipes() - else: - self.ca.stopPipes() - - - def setUpWindowsSizes( self ): - pipDim = self.getPipDim(False) - eyeDim = self.getEyeDim(False) - imgDim = self.getImgDim( False ) - pgdDim = self.getPgdDim( False ) - maxDim = self.getMaxDim( False ) - prgDim = self.getPrgDim( False ) - infDim = self.getInfDim( False ) - self.livePhotoWindow.resize( imgDim[0], imgDim[1] ) - self.pipBgdWindow.resize( pgdDim[0], pgdDim[1] ) - self.liveVideoWindow.resize( imgDim[0], imgDim[1] ) - self.playOggWindow.resize( imgDim[0], imgDim[1] ) - self.recordWindow.resize( eyeDim[0], eyeDim[1] ) - self.maxWindow.resize( maxDim[0], maxDim[1] ) - self.progressWindow.resize( prgDim[0], prgDim[1] ) - self.infWindow.resize( infDim[0], infDim[1] ) - - - def _toolbarChangeCb( self, tbox, num ): - if (num != 0) and (self.ca.m.RECORDING or self.ca.m.UPDATING): - self.toolbox.set_current_toolbar( self.ca.m.MODE+1 ) - else: - num = num - 1 #offset the default activity tab - if (num == Constants.MODE_PHOTO) and (self.ca.m.MODE != Constants.MODE_PHOTO): - self.ca.m.doPhotoMode() - elif(num == Constants.MODE_VIDEO) and (self.ca.m.MODE != Constants.MODE_VIDEO): - self.ca.m.doVideoMode() - elif(num == Constants.MODE_AUDIO) and (self.ca.m.MODE != Constants.MODE_AUDIO): - self.ca.m.doAudioMode() - - - def addToWindowStack( self, win, parent ): - self.windowStack.append( win ) - win.set_transient_for( parent ) - win.set_type_hint( gtk.gdk.WINDOW_TYPE_HINT_DIALOG ) - win.set_decorated( False ) - win.set_focus_on_map( False ) - win.set_property("accept-focus", False) - - - def resetWidgetFadeTimer( self ): - #only show the clutter when the mouse moves - self.mx = -1 - self.my = -1 - self.hideWidgetsTimer = time.time() - if (self.hiddenWidgets): - self.showWidgets() - self.hiddenWidgets = False - - #remove, then add - self.doMouseListener( False ) - if (self.HIDE_WIDGET_TIMEOUT_ID != 0): - gobject.source_remove( self.HIDE_WIDGET_TIMEOUT_ID) - - self.HIDE_WIDGET_TIMEOUT_ID = gobject.timeout_add( 500, self._mouseMightaMovedCb ) - - - def doMouseListener( self, listen ): - if (listen): - self.resetWidgetFadeTimer() - else: - if (self.HIDE_WIDGET_TIMEOUT_ID != None): - if (self.HIDE_WIDGET_TIMEOUT_ID != 0): - gobject.source_remove( self.HIDE_WIDGET_TIMEOUT_ID ) - - - def hideWidgets( self ): - self.moveWinOffscreen( self.maxWindow ) - self.moveWinOffscreen( self.pipBgdWindow ) - self.moveWinOffscreen( self.infWindow ) - self.moveWinOffscreen( self.slowLiveVideoWindow ) - - if (self.FULLSCREEN): - self.moveWinOffscreen( self.recordWindow ) - self.moveWinOffscreen( self.progressWindow ) - self.moveWinOffscreen( self.scrubWindow ) - - if (self.ca.m.MODE == Constants.MODE_PHOTO): - if (not self.LIVEMODE): - self.moveWinOffscreen( self.liveVideoWindow ) - elif (self.ca.m.MODE == Constants.MODE_VIDEO): - if (not self.LIVEMODE): - self.moveWinOffscreen( self.liveVideoWindow ) - elif (self.ca.m.MODE == Constants.MODE_AUDIO): - if (not self.LIVEMODE): - self.moveWinOffscreen( self.liveVideoWindow ) - self.LAST_MODE = -1 - - - def _mouseMightaMovedCb( self ): - x, y = self.ca.get_pointer() - passedTime = 0 - - if (x != self.mx or y != self.my): - self.hideWidgetsTimer = time.time() - if (self.hiddenWidgets): - self.showWidgets() - self.hiddenWidgets = False - else: - passedTime = time.time() - self.hideWidgetsTimer - - if (self.ca.m.RECORDING): - self.hideWidgetsTimer = time.time() - passedTime = 0 - - if (passedTime >= 3): - if (not self.hiddenWidgets): - if (self.mouseInWidget(x,y)): - self.hideWidgetsTimer = time.time() - elif (self.RECD_INFO_ON): - self.hideWidgetsTimer = time.time() - elif (self.UPDATE_TIMER_ID != 0): - self.hideWidgetsTimer = time.time() - else: - self.hideWidgets() - self.hiddenWidgets = True - - self.mx = x - self.my = y - return True - - - def mouseInWidget( self, mx, my ): - if (self.ca.m.MODE != Constants.MODE_AUDIO): - if (self.inWidget( mx, my, self.getLoc("max", self.FULLSCREEN), self.getDim("max", self.FULLSCREEN))): - return True - - if (not self.LIVEMODE): - if (self.inWidget( mx, my, self.getLoc("pgd", self.FULLSCREEN), self.getDim("pgd", self.FULLSCREEN))): - return True - - if (self.inWidget( mx, my, self.getLoc("inb", self.FULLSCREEN), self.getDim("inb", self.FULLSCREEN))): - return True - - if (self.inWidget( mx, my, self.getLoc("prg", self.FULLSCREEN), self.getDim("prg", self.FULLSCREEN))): - return True - - if (self.inWidget( mx, my, self.getLoc("inf", self.FULLSCREEN), self.getDim("inf", self.FULLSCREEN))): - return True - - if (self.LIVEMODE): - if (self.inWidget( mx, my, self.getLoc("eye", self.FULLSCREEN), self.getDim("eye", self.FULLSCREEN))): - return True - - return False - - - def _mediaClickedForPlayback(self, widget, event): - if (not self.LIVEMODE): - if (self.shownRecd != None): - if (self.ca.m.MODE != Constants.MODE_PHOTO): - self.showThumbSelection( self.shownRecd ) - - - def inWidget( self, mx, my, loc, dim ): - if ( (mx > loc[0]) and (my > loc[1]) ): - if ( (mx < loc[0]+dim[0]) and (my < loc[1]+dim[1]) ): - return True - - - def _nameTextfieldEditedCb(self, widget): - if (self.shownRecd != None): - if (self.nameTextfield.get_text() != self.shownRecd.title): - self.shownRecd.setTitle( self.nameTextfield.get_text() ) - - - def _tagsBufferEditedCb(self, widget): - if (self.shownRecd != None): - txt = self.tagsBuffer.get_text( self.tagsBuffer.get_start_iter(), self.tagsBuffer.get_end_iter() ) - if (txt != self.shownRecd.tags): - self.shownRecd.setTags( txt ) + dim_THUMB_WIDTH = 108 + dim_THUMB_HEIGHT = 81 + dim_INSET = 10 + dim_PIPW = 160 + dim_PIPH = 120 #pipBorder + dim_PIP_BORDER = 4 + dim_PGDW = dim_PIPW + (dim_PIP_BORDER*2) + dim_PGDH = dim_PIPH + (dim_PIP_BORDER*2) + dim_CONTROLBAR_HT = 55 + + def __init__( self, pca ): + self.ca = pca + self.ACTIVE = False + self.LAUNCHING = True + self.ca.add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) + self.ca.connect("visibility-notify-event", self._visibleNotifyCb) + + self.inset = self.__class__.dim_INSET + self.pgdh = self.__class__.dim_PGDH + self.pgdw = self.__class__.dim_PGDW + self.thumbTrayHt = 150 #todo: get sugar constant here + self.thumbSvgW = 124 + self.thumbSvgH = 124 + self.maxw = 49 + self.maxh = 49 + self.controlBarHt = 60 + self.recordButtWd = 55 + self.pipw = self.__class__.dim_PIPW + self.piph = self.__class__.dim_PIPH + + #ui modes + + # True when we're in full-screen mode, False otherwise + self.FULLSCREEN = False + + # True when we're showing live video feed in the primary screen + # area, False otherwise (even when we are still showing live video + # in a p-i-p) + self.LIVEMODE = True + + self.LAST_MODE = -1 + self.LAST_FULLSCREEN = False + self.LAST_LIVE = True + self.LAST_MESHING = False + self.LAST_RECD_INFO = False + self.LAST_TRANSCODING = False + self.TRANSCODING = False + self.MESHING = False + + # RECD_INFO_ON is True when the 'info' for a recording is being + # display on-screen (who recorded it, tags, etc), and False otherwise. + self.RECD_INFO_ON = False + + self.UPDATE_DURATION_ID = 0 + self.UPDATE_TIMER_ID = 0 + self.COUNTINGDOWN = False + + #init + self.mapped = False + self.centered = False + self.setup = False + + #prep for when to show + self.shownRecd = None + + #this includes the default sharing tab + self.toolbox = activity.ActivityToolbox(self.ca) + self.ca.set_toolbox(self.toolbox) + self.photoToolbar = PhotoToolbar() + self.photoToolbar.set_sensitive( False ) + self.toolbox.add_toolbar( Constants.istrPhoto, self.photoToolbar ) + self.videoToolbar = VideoToolbar() + self.videoToolbar.set_sensitive( False ) + self.toolbox.add_toolbar( Constants.istrVideo, self.videoToolbar ) + self.audioToolbar = AudioToolbar() + self.audioToolbar.set_sensitive( False ) + self.toolbox.add_toolbar( Constants.istrAudio, self.audioToolbar ) + self.tbars = {Constants.MODE_PHOTO:self.photoToolbar,Constants.MODE_VIDEO:self.videoToolbar,Constants.MODE_AUDIO:self.audioToolbar} + self.toolbox.set_current_toolbar(self.ca.m.MODE+1) + + self.toolbox.remove(self.toolbox._separator) + #taken directly from toolbox.py b/c I don't know how to mod the hongry hippo + separator = hippo.Canvas() + box = hippo.CanvasBox( + border_color=Constants.colorBlack.get_int(), + background_color=Constants.colorBlack.get_int(), + box_height=style.TOOLBOX_SEPARATOR_HEIGHT, + border_bottom=style.LINE_WIDTH) + separator.set_root(box) + self.toolbox.pack_start(separator, False) + self.toolbox.separator = separator + + self.TOOLBOX_SIZE_ALLOCATE_ID = self.toolbox.connect_after("size-allocate", self._toolboxSizeAllocateCb) + self.toolbox._notebook.set_property("can-focus", False) + self.toolbox.connect("current-toolbar-changed", self._toolbarChangeCb) + self.toolbox.show_all() + + + def _toolboxSizeAllocateCb( self, widget, event ): + self.toolbox.disconnect( self.TOOLBOX_SIZE_ALLOCATE_ID) + + toolboxHt = self.toolbox.size_request()[1] + self.vh = gtk.gdk.screen_height()-(self.thumbTrayHt+toolboxHt+self.controlBarHt) + self.vw = int(self.vh/.75) + self.letterBoxW = (gtk.gdk.screen_width() - self.vw)/2 + self.letterBoxVW = (self.vw/2)-(self.inset*2) + self.letterBoxVH = int(self.letterBoxVW*.75) + + self.setUpWindows() + + #now that we know how big the toolbox is, we can layout more + gobject.idle_add( self.layout ) + + + def layout( self ): + self.mainBox = gtk.VBox() + self.ca.set_canvas(self.mainBox) + + topBox = gtk.HBox() + self.mainBox.pack_start(topBox, expand=True) + + leftFill = gtk.VBox() + leftFill.set_size_request( self.letterBoxW, -1 ) + self.leftFillBox = gtk.EventBox( ) + self.leftFillBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + leftFill.add( self.leftFillBox ) + + topBox.pack_start( leftFill, expand=True ) + + centerVBox = gtk.VBox() + centerVBox.modify_bg(gtk.STATE_NORMAL, Constants.colorBlack.gColor) + topBox.pack_start( centerVBox, expand=True ) + self.centerBox = gtk.EventBox() + self.centerBox.set_size_request(self.vw, -1) + self.centerBox.modify_bg(gtk.STATE_NORMAL, Constants.colorBlack.gColor) + centerVBox.pack_start( self.centerBox, expand=True ) + centerSizer = gtk.VBox() + centerSizer.set_size_request(self.vw, -1) + centerSizer.modify_bg(gtk.STATE_NORMAL, Constants.colorBlack.gColor) + self.centerBox.add(centerSizer) + + self.bottomCenter = gtk.EventBox() + self.bottomCenter.modify_bg(gtk.STATE_NORMAL, Constants.colorBlack.gColor) + self.bottomCenter.set_size_request(self.vw, self.controlBarHt) + centerVBox.pack_start( self.bottomCenter, expand=False ) + + #into the center box we can put this guy... + self.backgdCanvasBox = gtk.VBox() + self.backgdCanvasBox.modify_bg(gtk.STATE_NORMAL, Constants.colorBlack.gColor) + self.backgdCanvasBox.set_size_request(self.vw, -1) + self.backgdCanvas = PhotoCanvas() + self.backgdCanvas.set_size_request(self.vw, self.vh) + self.backgdCanvasBox.pack_start( self.backgdCanvas, expand=False ) + + #or this guy... + self.infoBox = gtk.EventBox() + self.infoBox.modify_bg( gtk.STATE_NORMAL, Constants.colorButton.gColor ) + iinfoBox = gtk.VBox(spacing=self.inset) + self.infoBox.add( iinfoBox ) + iinfoBox.set_size_request(self.vw, -1) + iinfoBox.set_border_width(self.inset) + + rightFill = gtk.VBox() + rightFill.set_size_request( self.letterBoxW, -1 ) + rightFillBox = gtk.EventBox() + rightFillBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + rightFill.add( rightFillBox ) + topBox.pack_start( rightFill, expand=True ) + + #info box innards: + self.infoBoxTop = gtk.HBox() + iinfoBox.pack_start( self.infoBoxTop, expand=True ) + self.infoBoxTopLeft = gtk.VBox(spacing=self.inset) + self.infoBoxTop.pack_start( self.infoBoxTopLeft ) + self.infoBoxTopRight = gtk.VBox() + self.infoBoxTopRight.set_size_request(self.letterBoxVW, -1) + self.infoBoxTop.pack_start( self.infoBoxTopRight ) + + self.namePanel = gtk.HBox() + leftInfBalance = gtk.VBox() + self.nameLabel = gtk.Label(""+Constants.istrTitle+"") + self.nameLabel.set_use_markup( True ) + self.namePanel.pack_start( self.nameLabel, expand=False, padding=self.inset ) + self.nameLabel.set_alignment(0, .5) + self.nameTextfield = gtk.Entry(140) + self.nameTextfield.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) + self.nameTextfield.connect('changed', self._nameTextfieldEditedCb ) + self.nameTextfield.set_alignment(0) + self.nameTextfield.set_size_request( -1, self.controlBarHt-(self.inset*2) ) + self.namePanel.pack_start(self.nameTextfield) + + self.photographerPanel = gtk.VBox(spacing=self.inset) + self.infoBoxTopLeft.pack_start(self.photographerPanel, expand=False) + photographerLabel = gtk.Label("" + Constants.istrRecorder + "") + photographerLabel.set_use_markup( True ) + self.photographerPanel.pack_start(photographerLabel, expand=False) + photographerLabel.set_alignment(0, .5) + photoNamePanel = gtk.HBox(spacing=self.inset) + self.photographerPanel.pack_start(photoNamePanel) + + self.photoXoPanel = xoPanel() + photoNamePanel.pack_start( self.photoXoPanel, expand=False ) + self.photoXoPanel.set_size_request( 40, 40 ) + + self.photographerNameLabel = gtk.Label("") + self.photographerNameLabel.set_alignment(0, .5) + photoNamePanel.pack_start(self.photographerNameLabel) + + self.datePanel = gtk.HBox(spacing=self.inset) + self.infoBoxTopLeft.pack_start(self.datePanel, expand=False) + dateLabel = gtk.Label(""+Constants.istrDate+"") + dateLabel.set_use_markup(True) + self.datePanel.pack_start(dateLabel, expand=False) + self.dateDateLabel = gtk.Label("") + self.dateDateLabel.set_alignment(0, .5) + self.datePanel.pack_start(self.dateDateLabel) + + self.tagsPanel = gtk.VBox(spacing=self.inset) + tagsLabel = gtk.Label(""+Constants.istrTags+"") + tagsLabel.set_use_markup(True) + tagsLabel.set_alignment(0, .5) + self.tagsPanel.pack_start(tagsLabel, expand=False) + self.tagsBuffer = gtk.TextBuffer() + self.tagsBuffer.connect('changed', self._tagsBufferEditedCb) + self.tagsField = gtk.TextView(self.tagsBuffer) + self.tagsField.set_size_request( 100, 100 ) + self.tagsPanel.pack_start(self.tagsField, expand=True) + self.infoBoxTopLeft.pack_start(self.tagsPanel, expand=True) + + infoBotBox = gtk.HBox() + infoBotBox.set_size_request( -1, self.pgdh+self.inset ) + iinfoBox.pack_start(infoBotBox, expand=False) + + thumbnailsEventBox = gtk.EventBox() + thumbnailsEventBox.set_size_request( -1, self.thumbTrayHt ) + thumbnailsBox = gtk.HBox( ) + thumbnailsEventBox.add( thumbnailsBox ) + + self.thumbTray = HTray() + self.thumbTray.set_size_request( -1, self.thumbTrayHt ) + self.mainBox.pack_end( self.thumbTray, expand=False ) + self.thumbTray.show() + + self.CENTER_SIZE_ALLOCATE_ID = self.centerBox.connect_after("size-allocate", self._centerSizeAllocateCb) + self.ca.show_all() + + + def _centerSizeAllocateCb( self, widget, event ): + #initial setup of the panels + self.centerBox.disconnect(self.CENTER_SIZE_ALLOCATE_ID) + self.centerBoxPos = self.centerBox.translate_coordinates( self.ca, 0, 0 ) + + centerKid = self.centerBox.get_child() + if (centerKid != None): + self.centerBox.remove( centerKid ) + + self.centered = True + self.setUp() + + + def _mapEventCb( self, widget, event ): + #when your parent window is ready, turn on the feed of live video + self.liveVideoWindow.disconnect(self.MAP_EVENT_ID) + self.mapped = True + self.setUp() + + + def setUp( self ): + if (self.mapped and self.centered and not self.setup): + self.setup = True + + #set correct window sizes + self.setUpWindowsSizes() + + #listen for ctrl+c & game key buttons + self.ca.connect('key-press-event', self._keyPressEventCb) + #overlay widgets can go away after they've been on screen for a while + self.HIDE_WIDGET_TIMEOUT_ID = 0 + self.hiddenWidgets = False + self.resetWidgetFadeTimer() + self.showLiveVideoTags() + + self.photoToolbar.set_sensitive( True ) + self.videoToolbar.set_sensitive( True ) + self.audioToolbar.set_sensitive( True ) + + #initialize the app with the default thumbs + self.ca.m.setupMode( self.ca.m.MODE, False ) + + gobject.idle_add( self.finalSetUp ) + + + def finalSetUp( self ): + self.LAUNCHING = False + self.ACTIVE = self.ca.get_property( "visible" ) + self.updateVideoComponents() + + if (self.ACTIVE): + self.ca.glive.play() + + + def setUpWindows( self ): + #image windows + self.windowStack = [] + + #live video windows + self.livePhotoWindow = gtk.Window() + self.livePhotoWindow.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + self.livePhotoWindow.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) + self.addToWindowStack( self.livePhotoWindow, self.ca ) + self.livePhotoCanvas = PhotoCanvas() + self.livePhotoWindow.add(self.livePhotoCanvas) + self.livePhotoWindow.connect("button_release_event", self._mediaClickedForPlayback) + self.livePhotoWindow.add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) + self.livePhotoWindow.connect("visibility-notify-event", self._visibleNotifyCb) + + #video playback windows + self.playOggWindow = PlayVideoWindow(Constants.colorBlack.gColor) + self.addToWindowStack( self.playOggWindow, self.windowStack[len(self.windowStack)-1] ) + #self.playOggWindow.set_gplay(self.ca.gplay) + self.ca.gplay.window = self.playOggWindow + self.playOggWindow.set_events(gtk.gdk.BUTTON_RELEASE_MASK) + self.playOggWindow.connect("button_release_event", self._mediaClickedForPlayback) + self.playOggWindow.add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) + self.playOggWindow.connect("visibility-notify-event", self._visibleNotifyCb) + + #border behind + self.pipBgdWindow = gtk.Window() + self.pipBgdWindow.modify_bg( gtk.STATE_NORMAL, Constants.colorWhite.gColor ) + self.pipBgdWindow.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorWhite.gColor ) + self.addToWindowStack( self.pipBgdWindow, self.windowStack[len(self.windowStack)-1] ) + + self.liveVideoWindow = LiveVideoWindow(Constants.colorBlack.gColor) + self.addToWindowStack( self.liveVideoWindow, self.windowStack[len(self.windowStack)-1] ) + self.liveVideoWindow.set_glive(self.ca.glive) + self.liveVideoWindow.set_events(gtk.gdk.BUTTON_RELEASE_MASK) + self.liveVideoWindow.connect("button_release_event", self._liveButtonReleaseCb) + self.liveVideoWindow.add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) + self.liveVideoWindow.connect("visibility-notify-event", self._visibleNotifyCb) + + self.slowLiveVideoWindow = SlowLiveVideoWindow(Constants.colorBlack.gColor) + self.addToWindowStack( self.slowLiveVideoWindow, self.windowStack[len(self.windowStack)-1] ) + self.slowLiveVideoWindow.set_glivex(self.ca.glivex) + self.slowLiveVideoWindow.set_events(gtk.gdk.BUTTON_RELEASE_MASK) + self.slowLiveVideoWindow.connect("button_release_event", self._returnButtonReleaseCb) + self.slowLiveVideoWindow.add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) + self.slowLiveVideoWindow.connect("visibility-notify-event", self._visibleNotifyCb) + + self.recordWindow = RecordWindow(self) + self.addToWindowStack( self.recordWindow, self.windowStack[len(self.windowStack)-1] ) + + self.progressWindow = ProgressWindow(self) + self.addToWindowStack( self.progressWindow, self.windowStack[len(self.windowStack)-1] ) + + self.maxWindow = gtk.Window() + self.maxWindow.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + self.maxWindow.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) + maxButton = MaxButton(self) + self.maxWindow.add( maxButton ) + self.addToWindowStack( self.maxWindow, self.windowStack[len(self.windowStack)-1] ) + + self.scrubWindow = ScrubberWindow(self) + self.addToWindowStack( self.scrubWindow, self.windowStack[len(self.windowStack)-1] ) + + self.infWindow = gtk.Window() + self.infWindow.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + self.infWindow.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) + infButton= InfButton(self) + self.infWindow.add(infButton) + self.addToWindowStack( self.infWindow, self.windowStack[len(self.windowStack)-1] ) + + self.hideAllWindows() + self.MAP_EVENT_ID = self.liveVideoWindow.connect_after("map-event", self._mapEventCb) + for i in range (0, len(self.windowStack)): +# self.windowStack[i].add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) +# self.windowStack[i].connect("visibility-notify-event", self._visibleNotifyCb) + self.windowStack[i].show_all() + + + def _visibleNotifyCb( self, widget, event ): + + if (self.LAUNCHING): + return + + temp_ACTIVE = True + + if (event.state == gtk.gdk.VISIBILITY_FULLY_OBSCURED): + + if (not self.FULLSCREEN): + if (widget == self.ca): + temp_ACTIVE = False + + else: + if (self.ca.m.MODE == Constants.MODE_PHOTO): + if (not self.LIVEMODE and widget == self.livePhotoWindow): + temp_ACTIVE = False + if ( self.LIVEMODE and widget == self.liveVideoWindow): + temp_ACTIVE = False + + if (self.ca.m.MODE == Constants.MODE_VIDEO): + if (not self.LIVEMODE and widget == self.playOggWindow): + temp_ACTIVE = False + if ( self.LIVEMODE and widget == self.liveVideoWindow): + temp_ACTIVE = False + + + if (temp_ACTIVE != self.ACTIVE): + self.ACTIVE = temp_ACTIVE + if (self.ACTIVE): + self.ca.restartPipes() + else: + self.ca.stopPipes() + + + def setUpWindowsSizes( self ): + pipDim = self.getPipDim(False) + eyeDim = self.getEyeDim(False) + imgDim = self.getImgDim( False ) + pgdDim = self.getPgdDim( False ) + maxDim = self.getMaxDim( False ) + prgDim = self.getPrgDim( False ) + infDim = self.getInfDim( False ) + self.livePhotoWindow.resize( imgDim[0], imgDim[1] ) + self.pipBgdWindow.resize( pgdDim[0], pgdDim[1] ) + self.liveVideoWindow.resize( imgDim[0], imgDim[1] ) + self.playOggWindow.resize( imgDim[0], imgDim[1] ) + self.recordWindow.resize( eyeDim[0], eyeDim[1] ) + self.maxWindow.resize( maxDim[0], maxDim[1] ) + self.progressWindow.resize( prgDim[0], prgDim[1] ) + self.infWindow.resize( infDim[0], infDim[1] ) + + + def _toolbarChangeCb( self, tbox, num ): + if (num != 0) and (self.ca.m.RECORDING or self.ca.m.UPDATING): + self.toolbox.set_current_toolbar( self.ca.m.MODE+1 ) + else: + num = num - 1 #offset the default activity tab + if (num == Constants.MODE_PHOTO) and (self.ca.m.MODE != Constants.MODE_PHOTO): + self.ca.m.doPhotoMode() + elif(num == Constants.MODE_VIDEO) and (self.ca.m.MODE != Constants.MODE_VIDEO): + self.ca.m.doVideoMode() + elif(num == Constants.MODE_AUDIO) and (self.ca.m.MODE != Constants.MODE_AUDIO): + self.ca.m.doAudioMode() + + + def addToWindowStack( self, win, parent ): + self.windowStack.append( win ) + win.set_transient_for( parent ) + win.set_type_hint( gtk.gdk.WINDOW_TYPE_HINT_DIALOG ) + win.set_decorated( False ) + win.set_focus_on_map( False ) + win.set_property("accept-focus", False) + + + def resetWidgetFadeTimer( self ): + #only show the clutter when the mouse moves + self.mx = -1 + self.my = -1 + self.hideWidgetsTimer = time.time() + if (self.hiddenWidgets): + self.showWidgets() + self.hiddenWidgets = False + + #remove, then add + self.doMouseListener( False ) + if (self.HIDE_WIDGET_TIMEOUT_ID != 0): + gobject.source_remove( self.HIDE_WIDGET_TIMEOUT_ID) + + self.HIDE_WIDGET_TIMEOUT_ID = gobject.timeout_add( 500, self._mouseMightaMovedCb ) + + + def doMouseListener( self, listen ): + if (listen): + self.resetWidgetFadeTimer() + else: + if (self.HIDE_WIDGET_TIMEOUT_ID != None): + if (self.HIDE_WIDGET_TIMEOUT_ID != 0): + gobject.source_remove( self.HIDE_WIDGET_TIMEOUT_ID ) + + + def hideWidgets( self ): + self.moveWinOffscreen( self.maxWindow ) + self.moveWinOffscreen( self.pipBgdWindow ) + self.moveWinOffscreen( self.infWindow ) + self.moveWinOffscreen( self.slowLiveVideoWindow ) + + if (self.FULLSCREEN): + self.moveWinOffscreen( self.recordWindow ) + self.moveWinOffscreen( self.progressWindow ) + self.moveWinOffscreen( self.scrubWindow ) + + if (self.ca.m.MODE == Constants.MODE_PHOTO): + if (not self.LIVEMODE): + self.moveWinOffscreen( self.liveVideoWindow ) + elif (self.ca.m.MODE == Constants.MODE_VIDEO): + if (not self.LIVEMODE): + self.moveWinOffscreen( self.liveVideoWindow ) + elif (self.ca.m.MODE == Constants.MODE_AUDIO): + if (not self.LIVEMODE): + self.moveWinOffscreen( self.liveVideoWindow ) + self.LAST_MODE = -1 + + + def _mouseMightaMovedCb( self ): + x, y = self.ca.get_pointer() + passedTime = 0 + + if (x != self.mx or y != self.my): + self.hideWidgetsTimer = time.time() + if (self.hiddenWidgets): + self.showWidgets() + self.hiddenWidgets = False + else: + passedTime = time.time() - self.hideWidgetsTimer + + if (self.ca.m.RECORDING): + self.hideWidgetsTimer = time.time() + passedTime = 0 + + if (passedTime >= 3): + if (not self.hiddenWidgets): + if (self.mouseInWidget(x,y)): + self.hideWidgetsTimer = time.time() + elif (self.RECD_INFO_ON): + self.hideWidgetsTimer = time.time() + elif (self.UPDATE_TIMER_ID != 0): + self.hideWidgetsTimer = time.time() + else: + self.hideWidgets() + self.hiddenWidgets = True + + self.mx = x + self.my = y + return True + + + def mouseInWidget( self, mx, my ): + if (self.ca.m.MODE != Constants.MODE_AUDIO): + if (self.inWidget( mx, my, self.getLoc("max", self.FULLSCREEN), self.getDim("max", self.FULLSCREEN))): + return True + + if (not self.LIVEMODE): + if (self.inWidget( mx, my, self.getLoc("pgd", self.FULLSCREEN), self.getDim("pgd", self.FULLSCREEN))): + return True + + if (self.inWidget( mx, my, self.getLoc("inb", self.FULLSCREEN), self.getDim("inb", self.FULLSCREEN))): + return True + + if (self.inWidget( mx, my, self.getLoc("prg", self.FULLSCREEN), self.getDim("prg", self.FULLSCREEN))): + return True + + if (self.inWidget( mx, my, self.getLoc("inf", self.FULLSCREEN), self.getDim("inf", self.FULLSCREEN))): + return True + + if (self.LIVEMODE): + if (self.inWidget( mx, my, self.getLoc("eye", self.FULLSCREEN), self.getDim("eye", self.FULLSCREEN))): + return True + + return False + + + def _mediaClickedForPlayback(self, widget, event): + if (not self.LIVEMODE): + if (self.shownRecd != None): + if (self.ca.m.MODE != Constants.MODE_PHOTO): + self.showThumbSelection( self.shownRecd ) + + + def inWidget( self, mx, my, loc, dim ): + if ( (mx > loc[0]) and (my > loc[1]) ): + if ( (mx < loc[0]+dim[0]) and (my < loc[1]+dim[1]) ): + return True + + + def _nameTextfieldEditedCb(self, widget): + if (self.shownRecd != None): + if (self.nameTextfield.get_text() != self.shownRecd.title): + self.shownRecd.setTitle( self.nameTextfield.get_text() ) + + + def _tagsBufferEditedCb(self, widget): + if (self.shownRecd != None): + txt = self.tagsBuffer.get_text( self.tagsBuffer.get_start_iter(), self.tagsBuffer.get_end_iter() ) + if (txt != self.shownRecd.tags): + self.shownRecd.setTags( txt ) - def _keyPressEventCb( self, widget, event): - #todo: trac #4144 - - self.resetWidgetFadeTimer() + def _keyPressEventCb( self, widget, event): + #todo: trac #4144 + + self.resetWidgetFadeTimer() - #we listen here for CTRL+C events and game keys, and pass on events to gtk.Entry fields - keyname = gtk.gdk.keyval_name(event.keyval) + #we listen here for CTRL+C events and game keys, and pass on events to gtk.Entry fields + keyname = gtk.gdk.keyval_name(event.keyval) - if (keyname == 'KP_Page_Up'): #O, up - if (self.LIVEMODE): - if (not self.ca.m.UPDATING): - self.doShutter() - else: - if (self.COUNTINGDOWN): - self.doShutter() - else: - if (self.ca.m.MODE == Constants.MODE_PHOTO): - self.resumeLiveVideo() - else: - self.resumePlayLiveVideo() - elif (keyname == 'KP_Page_Down'): #x, down - if (not self.ca.m.UPDATING and not self.ca.m.RECORDING): - self.ca.m.showLastThumb() - elif (keyname == 'KP_Home'): #square, left - if (not self.ca.m.UPDATING and not self.ca.m.RECORDING and not self.LIVEMODE): - self.ca.m.showPrevThumb( self.shownRecd ) - elif (keyname == 'KP_End'): #check, right - if (not self.ca.m.UPDATING and not self.ca.m.RECORDING and not self.LIVEMODE): - self.ca.m.showNextThumb( self.shownRecd ) - elif (keyname == 'c' and event.state == gtk.gdk.CONTROL_MASK): - if (self.shownRecd != None): - self.copyToClipboard( self.shownRecd ) - elif (keyname == 'Escape'): - if (self.FULLSCREEN): - self.FULLSCREEN = False - if (self.RECD_INFO_ON): - self.infoButtonClicked() - else: - self.updateVideoComponents() - elif (keyname == 'i' and event.state == gtk.gdk.CONTROL_MASK): - if (not self.LIVEMODE): - self.infoButtonClicked() + if (keyname == 'KP_Page_Up'): #O, up + if (self.LIVEMODE): + if (not self.ca.m.UPDATING): + self.doShutter() + else: + if (self.COUNTINGDOWN): + self.doShutter() + else: + if (self.ca.m.MODE == Constants.MODE_PHOTO): + self.resumeLiveVideo() + else: + self.resumePlayLiveVideo() + elif (keyname == 'KP_Page_Down'): #x, down + if (not self.ca.m.UPDATING and not self.ca.m.RECORDING): + self.ca.m.showLastThumb() + elif (keyname == 'KP_Home'): #square, left + if (not self.ca.m.UPDATING and not self.ca.m.RECORDING and not self.LIVEMODE): + self.ca.m.showPrevThumb( self.shownRecd ) + elif (keyname == 'KP_End'): #check, right + if (not self.ca.m.UPDATING and not self.ca.m.RECORDING and not self.LIVEMODE): + self.ca.m.showNextThumb( self.shownRecd ) + elif (keyname == 'c' and event.state == gtk.gdk.CONTROL_MASK): + if (self.shownRecd != None): + self.copyToClipboard( self.shownRecd ) + elif (keyname == 'Escape'): + if (self.FULLSCREEN): + self.FULLSCREEN = False + if (self.RECD_INFO_ON): + self.infoButtonClicked() + else: + self.updateVideoComponents() + elif (keyname == 'i' and event.state == gtk.gdk.CONTROL_MASK): + if (not self.LIVEMODE): + self.infoButtonClicked() - return False + return False - def copyToClipboard( self, recd ): - if (recd.isClipboardCopyable( )): - tmpImgPath = self.doClipboardCopyStart( recd ) - gtk.Clipboard().set_with_data( [('text/uri-list', 0, 0)], self._clipboardGetFuncCb, self._clipboardClearFuncCb, tmpImgPath ) - return True + def copyToClipboard( self, recd ): + if (recd.isClipboardCopyable( )): + tmpImgPath = self.doClipboardCopyStart( recd ) + gtk.Clipboard().set_with_data( [('text/uri-list', 0, 0)], self._clipboardGetFuncCb, self._clipboardClearFuncCb, tmpImgPath ) + return True - def doClipboardCopyStart( self, recd ): - imgPath_s = recd.getMediaFilepath() - if (imgPath_s == None): - record.Record.log.error("doClipboardCopyStart: imgPath_s==None") - return None + def doClipboardCopyStart( self, recd ): + imgPath_s = recd.getMediaFilepath() + if (imgPath_s == None): + record.Record.log.error("doClipboardCopyStart: imgPath_s==None") + return None - tmpImgPath = recd.getMediaFilepath() - tmpImgPath = utils.getUniqueFilepath(tmpImgPath, 0) - shutil.copyfile( imgPath_s, tmpImgPath ) - return tmpImgPath + tmpImgPath = recd.getMediaFilepath() + tmpImgPath = utils.getUniqueFilepath(tmpImgPath, 0) + shutil.copyfile( imgPath_s, tmpImgPath ) + return tmpImgPath - def doClipboardCopyCopy( self, tmpImgPath, selection_data ): - tmpImgUri = "file://" + tmpImgPath - selection_data.set( "text/uri-list", 8, tmpImgUri ) - - - def doClipboardCopyFinish( self, tmpImgPath ): - if (tmpImgPath != None): - if (os.path.exists(tmpImgPath)): - os.remove( tmpImgPath ) - tmpImgPath = None - - - def _clipboardGetFuncCb( self, clipboard, selection_data, info, data): - self.doClipboardCopyCopy( data, selection_data ) - - - def _clipboardClearFuncCb( self, clipboard, data): - self.doClipboardCopyFinish( data ) - - - def showPhoto( self, recd ): - pixbuf = self.getPhotoPixbuf( recd ) - if (pixbuf != None): - #self.shownRecd = recd - - img = camerac.cairo_surface_from_gdk_pixbuf(pixbuf) - self.livePhotoCanvas.setImage( img ) - - self.LIVEMODE = False - self.updateVideoComponents() - - self.showRecdMeta(recd) - - - def getPhotoPixbuf( self, recd ): - pixbuf = None - - downloading = self.ca.requestMeshDownload(recd) - self.MESHING = downloading - - if (not downloading): - self.progressWindow.updateProgress(0, "") - imgPath = recd.getMediaFilepath() - if (not imgPath == None): - if ( os.path.isfile(imgPath) ): - pixbuf = gtk.gdk.pixbuf_new_from_file(imgPath) - - if (pixbuf == None): - #maybe it is not downloaded from the mesh yet... - #but we can show the low res thumb in the interim - pixbuf = recd.getThumbPixbuf() - - return pixbuf + def doClipboardCopyCopy( self, tmpImgPath, selection_data ): + tmpImgUri = "file://" + tmpImgPath + selection_data.set( "text/uri-list", 8, tmpImgUri ) + + + def doClipboardCopyFinish( self, tmpImgPath ): + if (tmpImgPath != None): + if (os.path.exists(tmpImgPath)): + os.remove( tmpImgPath ) + tmpImgPath = None + + + def _clipboardGetFuncCb( self, clipboard, selection_data, info, data): + self.doClipboardCopyCopy( data, selection_data ) + + + def _clipboardClearFuncCb( self, clipboard, data): + self.doClipboardCopyFinish( data ) + + + def showPhoto( self, recd ): + pixbuf = self.getPhotoPixbuf( recd ) + if (pixbuf != None): + #self.shownRecd = recd + + img = camerac.cairo_surface_from_gdk_pixbuf(pixbuf) + self.livePhotoCanvas.setImage( img ) + + self.LIVEMODE = False + self.updateVideoComponents() + + self.showRecdMeta(recd) + + + def getPhotoPixbuf( self, recd ): + pixbuf = None + + downloading = self.ca.requestMeshDownload(recd) + self.MESHING = downloading + + if (not downloading): + self.progressWindow.updateProgress(0, "") + imgPath = recd.getMediaFilepath() + if (not imgPath == None): + if ( os.path.isfile(imgPath) ): + pixbuf = gtk.gdk.pixbuf_new_from_file(imgPath) + + if (pixbuf == None): + #maybe it is not downloaded from the mesh yet... + #but we can show the low res thumb in the interim + pixbuf = recd.getThumbPixbuf() + + return pixbuf - def showLiveVideoTags( self ): - self.shownRecd = None - self.livePhotoCanvas.setImage( None ) - self.nameTextfield.set_text("") - self.tagsBuffer.set_text("") + def showLiveVideoTags( self ): + self.shownRecd = None + self.livePhotoCanvas.setImage( None ) + self.nameTextfield.set_text("") + self.tagsBuffer.set_text("") - self.scrubWindow.removeCallbacks() - self.scrubWindow.reset() - self.MESHING = False - self.progressWindow.updateProgress( 0, "" ) + self.scrubWindow.removeCallbacks() + self.scrubWindow.reset() + self.MESHING = False + self.progressWindow.updateProgress( 0, "" ) - self.resetWidgetFadeTimer( ) + self.resetWidgetFadeTimer( ) - def updateButtonSensitivities( self ): - switchStuff = ((not self.ca.m.UPDATING) and (not self.ca.m.RECORDING)) - self.photoToolbar.set_sensitive( switchStuff ) - self.videoToolbar.set_sensitive( switchStuff ) - self.audioToolbar.set_sensitive( switchStuff ) + def updateButtonSensitivities( self ): + switchStuff = ((not self.ca.m.UPDATING) and (not self.ca.m.RECORDING)) + self.photoToolbar.set_sensitive( switchStuff ) + self.videoToolbar.set_sensitive( switchStuff ) + self.audioToolbar.set_sensitive( switchStuff ) - if (not self.COUNTINGDOWN): - if (self.ca.m.UPDATING): - self.ca.ui.setWaitCursor( self.ca.window ) - for i in range (0, len(self.windowStack)): - self.ca.ui.setWaitCursor( self.windowStack[i].window ) - else: - self.ca.ui.setDefaultCursor( self.ca.window ) - for i in range (0, len(self.windowStack)): - self.ca.ui.setDefaultCursor( self.windowStack[i].window ) + if (not self.COUNTINGDOWN): + if (self.ca.m.UPDATING): + self.ca.ui.setWaitCursor( self.ca.window ) + for i in range (0, len(self.windowStack)): + self.ca.ui.setWaitCursor( self.windowStack[i].window ) + else: + self.ca.ui.setDefaultCursor( self.ca.window ) + for i in range (0, len(self.windowStack)): + self.ca.ui.setDefaultCursor( self.windowStack[i].window ) - #display disc is full messages - self.ca.m.updateXoFullStatus() - self.recordWindow.displayDiscFullText(self.ca.m.FULL) - if (self.ca.m.FULL): - self.recordWindow.shutterButton.set_sensitive( False, True) - fullMessage = Constants.istrYourDiskIsFull % {"1":Constants.istrJournal} - self.progressWindow.updateProgress( 1, fullMessage, "gray" ) - else: - self.recordWindow.shutterButton.set_sensitive( not self.ca.m.UPDATING, False ) - if (self.ca.m.RECORDING): - self.recordWindow.shutterButton.doRecordButton() - else: - self.recordWindow.shutterButton.doNormalButton() + #display disc is full messages + self.ca.m.updateXoFullStatus() + self.recordWindow.displayDiscFullText(self.ca.m.FULL) + if (self.ca.m.FULL): + self.recordWindow.shutterButton.set_sensitive( False, True) + fullMessage = Constants.istrYourDiskIsFull % {"1":Constants.istrJournal} + self.progressWindow.updateProgress( 1, fullMessage, "gray" ) + else: + self.recordWindow.shutterButton.set_sensitive( not self.ca.m.UPDATING, False ) + if (self.ca.m.RECORDING): + self.recordWindow.shutterButton.doRecordButton() + else: + self.recordWindow.shutterButton.doNormalButton() - kids = self.thumbTray.get_children() - for i in range (0, len(kids)): - if (self.ca.m.UPDATING or self.ca.m.RECORDING): - if (kids[i].getButtClickedId() != 0): - kids[i].disconnect( kids[i].getButtClickedId() ) - kids[i].setButtClickedId(0) - else: - if (kids[i].getButtClickedId() == 0): - BUTT_CLICKED_ID = kids[i].connect( "clicked", self._thumbClicked, kids[i].recd ) - kids[i].setButtClickedId(BUTT_CLICKED_ID) + kids = self.thumbTray.get_children() + for i in range (0, len(kids)): + if (self.ca.m.UPDATING or self.ca.m.RECORDING): + if (kids[i].getButtClickedId() != 0): + kids[i].disconnect( kids[i].getButtClickedId() ) + kids[i].setButtClickedId(0) + else: + if (kids[i].getButtClickedId() == 0): + BUTT_CLICKED_ID = kids[i].connect( "clicked", self._thumbClicked, kids[i].recd ) + kids[i].setButtClickedId(BUTT_CLICKED_ID) - def hideAllWindows( self ): - for i in range (0, len(self.windowStack)): - self.moveWinOffscreen( self.windowStack[i] ) + def hideAllWindows( self ): + for i in range (0, len(self.windowStack)): + self.moveWinOffscreen( self.windowStack[i] ) - def _liveButtonReleaseCb(self, widget, event): - self.resumeLiveVideo() + def _liveButtonReleaseCb(self, widget, event): + self.resumeLiveVideo() - def _returnButtonReleaseCb(self, widget, event): - self.ca.gplay.stop() - self.ca.glivex.stop() - self.ca.glive.play() - self.resumeLiveVideo() + def _returnButtonReleaseCb(self, widget, event): + self.ca.gplay.stop() + self.ca.glivex.stop() + self.ca.glive.play() + self.resumeLiveVideo() - def resumeLiveVideo( self ): - self.livePhotoCanvas.setImage( None ) + def resumeLiveVideo( self ): + self.livePhotoCanvas.setImage( None ) - bottomKid = self.bottomCenter.get_child() - if (bottomKid != None): - self.bottomCenter.remove( bottomKid ) + bottomKid = self.bottomCenter.get_child() + if (bottomKid != None): + self.bottomCenter.remove( bottomKid ) - self.RECD_INFO_ON = False + self.RECD_INFO_ON = False - if (not self.LIVEMODE): - self.ca.m.setUpdating(True) - self.ca.gplay.stop() - self.showLiveVideoTags() - self.LIVEMODE = True - self.updateVideoComponents() - self.ca.m.setUpdating(False) + if (not self.LIVEMODE): + self.ca.m.setUpdating(True) + self.ca.gplay.stop() + self.showLiveVideoTags() + self.LIVEMODE = True + self.updateVideoComponents() + self.ca.m.setUpdating(False) - def _playLiveButtonReleaseCb(self, widget, event): - self.resumePlayLiveVideo() + def _playLiveButtonReleaseCb(self, widget, event): + self.resumePlayLiveVideo() - def resumePlayLiveVideo( self ): - self.ca.gplay.stop() + def resumePlayLiveVideo( self ): + self.ca.gplay.stop() - self.RECD_INFO_ON = False - #if you are big on the screen, don't go changing anything, ok? - if (self.LIVEMODE): - return + self.RECD_INFO_ON = False + #if you are big on the screen, don't go changing anything, ok? + if (self.LIVEMODE): + return - self.showLiveVideoTags() - self.LIVEMODE = True - self.startLiveVideo( False ) - self.updateVideoComponents() + self.showLiveVideoTags() + self.LIVEMODE = True + self.startLiveVideo( False ) + self.updateVideoComponents() - def recordVideo( self ): - self.ca.glive.startRecordingVideo( ) - self.beginRecordingTimer( ) + def recordVideo( self ): + self.ca.glive.startRecordingVideo( ) + self.beginRecordingTimer( ) - def recordAudio( self ): - self.ca.glive.startRecordingAudio( ) - self.beginRecordingTimer( ) + def recordAudio( self ): + self.ca.glive.startRecordingAudio( ) + self.beginRecordingTimer( ) - def beginRecordingTimer( self ): - self.recTime = time.time() - self.UPDATE_DURATION_ID = gobject.timeout_add( 500, self._updateDurationCb ) + def beginRecordingTimer( self ): + self.recTime = time.time() + self.UPDATE_DURATION_ID = gobject.timeout_add( 500, self._updateDurationCb ) - def _updateDurationCb( self ): - passedTime = time.time() - self.recTime + def _updateDurationCb( self ): + passedTime = time.time() - self.recTime - duration = 10.0 - if (self.ca.m.MODE == Constants.MODE_VIDEO): - duration = self.videoToolbar.getDuration()+0.0 - elif (self.ca.m.MODE == Constants.MODE_AUDIO): - duration = self.audioToolbar.getDuration()+0.0 + duration = 10.0 + if (self.ca.m.MODE == Constants.MODE_VIDEO): + duration = self.videoToolbar.getDuration()+0.0 + elif (self.ca.m.MODE == Constants.MODE_AUDIO): + duration = self.audioToolbar.getDuration()+0.0 - if (passedTime >= duration ): - self.completeCountdown() - self.progressWindow.updateProgress( 1, Constants.istrFinishedRecording ) - if (self.ca.m.RECORDING): - gobject.idle_add( self.doShutter ) + if (passedTime >= duration ): + self.completeCountdown() + self.progressWindow.updateProgress( 1, Constants.istrFinishedRecording ) + if (self.ca.m.RECORDING): + gobject.idle_add( self.doShutter ) - return False - else: - secsRemaining = duration - passedTime - timeRemainStr = Constants.istrSecondsRemaining % {"1":str(int(secsRemaining))} - if (secsRemaining >= 60): - mins = int( secsRemaining/60 ) - secs = int( secsRemaining%60 ) - timeRemainStr = Constants.istrMinutesSecondsRemaining % {"1":str(int(mins)), "2":str(int(secs))} + return False + else: + secsRemaining = duration - passedTime + timeRemainStr = Constants.istrSecondsRemaining % {"1":str(int(secsRemaining))} + if (secsRemaining >= 60): + mins = int( secsRemaining/60 ) + secs = int( secsRemaining%60 ) + timeRemainStr = Constants.istrMinutesSecondsRemaining % {"1":str(int(mins)), "2":str(int(secs))} - self.progressWindow.updateProgress( passedTime/duration, Constants.istrDuration + " " + timeRemainStr ) - return True + self.progressWindow.updateProgress( passedTime/duration, Constants.istrDuration + " " + timeRemainStr ) + return True - def completeCountdown( self ): - if (self.UPDATE_DURATION_ID != 0): - gobject.source_remove( self.UPDATE_DURATION_ID ) - self.UPDATE_DURATION_ID = 0 + def completeCountdown( self ): + if (self.UPDATE_DURATION_ID != 0): + gobject.source_remove( self.UPDATE_DURATION_ID ) + self.UPDATE_DURATION_ID = 0 - def updateModeChange(self): - #this is called when a menubar button is clicked - self.LIVEMODE = True - self.FULLSCREEN = False - self.RECD_INFO_ON = False - self.MESHING = False + def updateModeChange(self): + #this is called when a menubar button is clicked + self.LIVEMODE = True + self.FULLSCREEN = False + self.RECD_INFO_ON = False + self.MESHING = False - self.progressWindow.updateProgress(0, "") + self.progressWindow.updateProgress(0, "") - #set up the x & xv x-ition (if need be) - self.ca.gplay.stop() - self.startLiveVideo( True ) + #set up the x & xv x-ition (if need be) + self.ca.gplay.stop() + self.startLiveVideo( True ) - bottomKid = self.bottomCenter.get_child() - if (bottomKid != None): - self.bottomCenter.remove( bottomKid ) + bottomKid = self.bottomCenter.get_child() + if (bottomKid != None): + self.bottomCenter.remove( bottomKid ) - self.doMouseListener( True ) - self.showLiveVideoTags() - self.LAST_MODE = -1 #force an update - self.updateVideoComponents() - self.resetWidgetFadeTimer() + self.doMouseListener( True ) + self.showLiveVideoTags() + self.LAST_MODE = -1 #force an update + self.updateVideoComponents() + self.resetWidgetFadeTimer() - def startLiveVideo(self, force): - #We need to know which window and which pipe here + def startLiveVideo(self, force): + #We need to know which window and which pipe here - #if returning from another activity, active won't be false and needs to be to get started - if (self.ca.glive.window == self.liveVideoWindow - and self.ca.props.active - and not force): - return + #if returning from another activity, active won't be false and needs to be to get started + if (self.ca.glive.window == self.liveVideoWindow + and self.ca.props.active + and not force): + return - self.liveVideoWindow.set_glive(self.ca.glive) - self.ca.glive.play() + self.liveVideoWindow.set_glive(self.ca.glive) + self.ca.glive.play() - def doFullscreen( self ): - self.FULLSCREEN = not self.FULLSCREEN - self.updateVideoComponents() + def doFullscreen( self ): + self.FULLSCREEN = not self.FULLSCREEN + self.updateVideoComponents() - def moveWinOffscreen( self, win ): - #we move offscreen to resize or else we get flashes on screen, and setting hide() doesn't allow resize & moves - offW = (gtk.gdk.screen_width() + 100) - offH = (gtk.gdk.screen_height() + 100) - self.smartMove(win, offW, offH) + def moveWinOffscreen( self, win ): + #we move offscreen to resize or else we get flashes on screen, and setting hide() doesn't allow resize & moves + offW = (gtk.gdk.screen_width() + 100) + offH = (gtk.gdk.screen_height() + 100) + self.smartMove(win, offW, offH) - def setImgLocDim( self, win ): - imgDim = self.getImgDim( self.FULLSCREEN ) - self.smartResize( win, imgDim[0], imgDim[1] ) - imgLoc = self.getImgLoc( self.FULLSCREEN ) - self.smartMove( win, imgLoc[0], imgLoc[1] ) + def setImgLocDim( self, win ): + imgDim = self.getImgDim( self.FULLSCREEN ) + self.smartResize( win, imgDim[0], imgDim[1] ) + imgLoc = self.getImgLoc( self.FULLSCREEN ) + self.smartMove( win, imgLoc[0], imgLoc[1] ) - def setPrgLocDim( self, win ): - prgDim = self.getPrgDim( self.FULLSCREEN ) - self.smartResize( win, prgDim[0], prgDim[1] ) - prgLoc = self.getPrgLoc( self.FULLSCREEN ) - self.smartMove( win, prgLoc[0], prgLoc[1] ) + def setPrgLocDim( self, win ): + prgDim = self.getPrgDim( self.FULLSCREEN ) + self.smartResize( win, prgDim[0], prgDim[1] ) + prgLoc = self.getPrgLoc( self.FULLSCREEN ) + self.smartMove( win, prgLoc[0], prgLoc[1] ) - def setTmrLocDim( self, win ): - tmrDim = self.getTmrDim( self.FULLSCREEN ) - self.smartResize( win, tmrDim[0], tmrDim[1] ) - tmrLoc = self.getTmrLoc( self.FULLSCREEN ) - self.smartMove( win, tmrLoc[0], tmrLoc[1] ) + def setTmrLocDim( self, win ): + tmrDim = self.getTmrDim( self.FULLSCREEN ) + self.smartResize( win, tmrDim[0], tmrDim[1] ) + tmrLoc = self.getTmrLoc( self.FULLSCREEN ) + self.smartMove( win, tmrLoc[0], tmrLoc[1] ) - def setScrLocDim( self, win ): - scrDim = self.getScrDim( self.FULLSCREEN ) - self.smartResize( win, scrDim[0], scrDim[1] ) - scrLoc = self.getScrLoc( self.FULLSCREEN ) - self.smartMove( win, scrLoc[0], scrLoc[1] ) + def setScrLocDim( self, win ): + scrDim = self.getScrDim( self.FULLSCREEN ) + self.smartResize( win, scrDim[0], scrDim[1] ) + scrLoc = self.getScrLoc( self.FULLSCREEN ) + self.smartMove( win, scrLoc[0], scrLoc[1] ) - def setInfLocDim( self, win ): - infDim = self.getInfDim( self.FULLSCREEN ) - self.smartResize( win, infDim[0], infDim[1] ) - infLoc = self.getInfLoc( self.FULLSCREEN ) - self.smartMove( win, infLoc[0], infLoc[1] ) + def setInfLocDim( self, win ): + infDim = self.getInfDim( self.FULLSCREEN ) + self.smartResize( win, infDim[0], infDim[1] ) + infLoc = self.getInfLoc( self.FULLSCREEN ) + self.smartMove( win, infLoc[0], infLoc[1] ) - def getScrDim( self, full ): - if (full): - return [gtk.gdk.screen_width()-(self.inset+self.pgdw+self.inset+self.inset), self.controlBarHt] - else: - return [self.vw, self.controlBarHt] + def getScrDim( self, full ): + if (full): + return [gtk.gdk.screen_width()-(self.inset+self.pgdw+self.inset+self.inset), self.controlBarHt] + else: + return [self.vw, self.controlBarHt] - def getScrLoc( self, full ): - if (full): - return [(self.inset+self.pgdw+self.inset), gtk.gdk.screen_height()-(self.inset+self.controlBarHt)] - else: - return [self.centerBoxPos[0], self.centerBoxPos[1]+self.vh] + def getScrLoc( self, full ): + if (full): + return [(self.inset+self.pgdw+self.inset), gtk.gdk.screen_height()-(self.inset+self.controlBarHt)] + else: + return [self.centerBoxPos[0], self.centerBoxPos[1]+self.vh] - def getImgDim( self, full ): - if (full): - return [gtk.gdk.screen_width(), gtk.gdk.screen_height()] - else: - return [self.vw, self.vh] + def getImgDim( self, full ): + if (full): + return [gtk.gdk.screen_width(), gtk.gdk.screen_height()] + else: + return [self.vw, self.vh] - def getImgLoc( self, full ): - if (full): - return[0, 0] - else: - return[self.centerBoxPos[0], self.centerBoxPos[1]] + def getImgLoc( self, full ): + if (full): + return[0, 0] + else: + return[self.centerBoxPos[0], self.centerBoxPos[1]] - def getTmrLoc( self, full ): - if (not full): - return [self.centerBoxPos[0], self.centerBoxPos[1]+self.vh] - else: - return [self.inset, gtk.gdk.screen_height()-(self.inset+self.controlBarHt)] + def getTmrLoc( self, full ): + if (not full): + return [self.centerBoxPos[0], self.centerBoxPos[1]+self.vh] + else: + return [self.inset, gtk.gdk.screen_height()-(self.inset+self.controlBarHt)] - def getTmrDim( self, full ): - if (not full): - return [self.vw, self.controlBarHt] - else: - return [gtk.gdk.screen_width()-(self.inset+self.inset), self.controlBarHt] + def getTmrDim( self, full ): + if (not full): + return [self.vw, self.controlBarHt] + else: + return [gtk.gdk.screen_width()-(self.inset+self.inset), self.controlBarHt] - def setPipLocDim( self, win ): - self.smartResize( win, self.pipw, self.piph ) + def setPipLocDim( self, win ): + self.smartResize( win, self.pipw, self.piph ) - loc = self.getPipLoc( self.FULLSCREEN ) - self.smartMove( win, loc[0], loc[1] ) + loc = self.getPipLoc( self.FULLSCREEN ) + self.smartMove( win, loc[0], loc[1] ) - def getPipLoc( self, full ): - if (full): - return [self.inset+self.__class__.dim_PIP_BORDER, gtk.gdk.screen_height()-(self.inset+self.piph+self.__class__.dim_PIP_BORDER)] - else: - return [self.centerBoxPos[0]+self.inset+self.__class__.dim_PIP_BORDER, (self.centerBoxPos[1]+self.vh)-(self.inset+self.piph+self.__class__.dim_PIP_BORDER)] + def getPipLoc( self, full ): + if (full): + return [self.inset+self.__class__.dim_PIP_BORDER, gtk.gdk.screen_height()-(self.inset+self.piph+self.__class__.dim_PIP_BORDER)] + else: + return [self.centerBoxPos[0]+self.inset+self.__class__.dim_PIP_BORDER, (self.centerBoxPos[1]+self.vh)-(self.inset+self.piph+self.__class__.dim_PIP_BORDER)] - def setPipBgdLocDim( self, win ): - pgdLoc = self.getPgdLoc( self.FULLSCREEN ) - self.smartMove( win, pgdLoc[0], pgdLoc[1] ) + def setPipBgdLocDim( self, win ): + pgdLoc = self.getPgdLoc( self.FULLSCREEN ) + self.smartMove( win, pgdLoc[0], pgdLoc[1] ) - def getPgdLoc( self, full ): - if (full): - return [self.inset, gtk.gdk.screen_height()-(self.inset+self.pgdh)] - else: - return [self.centerBoxPos[0]+self.inset, (self.centerBoxPos[1]+self.vh)-(self.inset+self.pgdh)] + def getPgdLoc( self, full ): + if (full): + return [self.inset, gtk.gdk.screen_height()-(self.inset+self.pgdh)] + else: + return [self.centerBoxPos[0]+self.inset, (self.centerBoxPos[1]+self.vh)-(self.inset+self.pgdh)] - def setMaxLocDim( self, win ): - maxLoc = self.getMaxLoc( self.FULLSCREEN ) - self.smartMove( win, maxLoc[0], maxLoc[1] ) + def setMaxLocDim( self, win ): + maxLoc = self.getMaxLoc( self.FULLSCREEN ) + self.smartMove( win, maxLoc[0], maxLoc[1] ) - def getMaxLoc( self, full ): - if (full): - return [gtk.gdk.screen_width()-(self.maxw+self.inset), self.inset] - else: - return [(self.centerBoxPos[0]+self.vw)-(self.inset+self.maxw), self.centerBoxPos[1]+self.inset] + def getMaxLoc( self, full ): + if (full): + return [gtk.gdk.screen_width()-(self.maxw+self.inset), self.inset] + else: + return [(self.centerBoxPos[0]+self.vw)-(self.inset+self.maxw), self.centerBoxPos[1]+self.inset] - def getInfLoc( self, full ): - if (full): - return [gtk.gdk.screen_width()+100,gtk.gdk.screen_height()+100 ] - else: - dim = self.getInfDim(self.FULLSCREEN) - return [(self.centerBoxPos[0]+self.vw)-dim[0], (self.centerBoxPos[1]+self.vh)-dim[1]] + def getInfLoc( self, full ): + if (full): + return [gtk.gdk.screen_width()+100,gtk.gdk.screen_height()+100 ] + else: + dim = self.getInfDim(self.FULLSCREEN) + return [(self.centerBoxPos[0]+self.vw)-dim[0], (self.centerBoxPos[1]+self.vh)-dim[1]] - def setEyeLocDim( self, win ): - dim = self.getEyeDim( self.FULLSCREEN ) - self.smartResize( win, dim[0], dim[1] ) - loc = self.getEyeLoc( self.FULLSCREEN ) - self.smartMove( win, loc[0], loc[1] ) + def setEyeLocDim( self, win ): + dim = self.getEyeDim( self.FULLSCREEN ) + self.smartResize( win, dim[0], dim[1] ) + loc = self.getEyeLoc( self.FULLSCREEN ) + self.smartMove( win, loc[0], loc[1] ) - def getEyeLoc( self, full ): - if (not full): - return [self.centerBoxPos[0], self.centerBoxPos[1]+self.vh] - else: - return [self.inset, gtk.gdk.screen_height()-(self.inset+self.controlBarHt)] + def getEyeLoc( self, full ): + if (not full): + return [self.centerBoxPos[0], self.centerBoxPos[1]+self.vh] + else: + return [self.inset, gtk.gdk.screen_height()-(self.inset+self.controlBarHt)] - def getEyeDim( self, full ): - if (not full): - if (self.ca.m.MODE == Constants.MODE_PHOTO): - return [self.vw, self.controlBarHt] - else: - return [self.recordButtWd, self.controlBarHt] - else: - if (self.ca.m.MODE == Constants.MODE_PHOTO): - return [gtk.gdk.screen_width()-(self.inset*2), self.controlBarHt] - else: - return [self.recordButtWd, self.controlBarHt] + def getEyeDim( self, full ): + if (not full): + if (self.ca.m.MODE == Constants.MODE_PHOTO): + return [self.vw, self.controlBarHt] + else: + return [self.recordButtWd, self.controlBarHt] + else: + if (self.ca.m.MODE == Constants.MODE_PHOTO): + return [gtk.gdk.screen_width()-(self.inset*2), self.controlBarHt] + else: + return [self.recordButtWd, self.controlBarHt] - def getInbLoc( self, full ): - return [(self.centerBoxPos[0]+self.vw)-(self.inset+self.letterBoxVW), self.centerBoxPos[1]+self.inset] + def getInbLoc( self, full ): + return [(self.centerBoxPos[0]+self.vw)-(self.inset+self.letterBoxVW), self.centerBoxPos[1]+self.inset] - def setInbLocDim( self, win ): - dim = self.getInbDim( self.FULLSCREEN ) - self.smartResize( win, dim[0], dim[1] ) - loc = self.getInbLoc(self.FULLSCREEN) - self.smartMove( win, loc[0], loc[1] ) + def setInbLocDim( self, win ): + dim = self.getInbDim( self.FULLSCREEN ) + self.smartResize( win, dim[0], dim[1] ) + loc = self.getInbLoc(self.FULLSCREEN) + self.smartMove( win, loc[0], loc[1] ) - def smartResize( self, win, w, h ): - winSize = win.get_size() - if ( (winSize[0] != w) or (winSize[1] != h) ): - win.resize( w, h ) - return True - else: - return False + def smartResize( self, win, w, h ): + winSize = win.get_size() + if ( (winSize[0] != w) or (winSize[1] != h) ): + win.resize( w, h ) + return True + else: + return False - def smartMove( self, win, x, y ): - winLoc = win.get_position() - if ( (winLoc[0] != x) or (winLoc[1] != y) ): - win.move( x, y ) - return True - else: - return False + def smartMove( self, win, x, y ): + winLoc = win.get_position() + if ( (winLoc[0] != x) or (winLoc[1] != y) ): + win.move( x, y ) + return True + else: + return False - def getDim( self, pos, full ): - if (pos == "pip"): - return self.getPipDim( full ) - elif(pos == "pgd"): - return self.getPgdDim( full ) - elif(pos == "max"): - return self.getMaxDim( full ) - elif(pos == "img"): - return self.getImgDim( full ) - elif(pos == "eye"): - return self.getEyeDim( full ) - elif(pos == "inb"): - return self.getInbDim( full ) - elif(pos == "prg"): - return self.getPrgDim( full ) - elif(pos == "inf"): - return self.getInfDim( full ) - - - def getMaxDim( self, full ): - return [self.maxw, self.maxh] + def getDim( self, pos, full ): + if (pos == "pip"): + return self.getPipDim( full ) + elif(pos == "pgd"): + return self.getPgdDim( full ) + elif(pos == "max"): + return self.getMaxDim( full ) + elif(pos == "img"): + return self.getImgDim( full ) + elif(pos == "eye"): + return self.getEyeDim( full ) + elif(pos == "inb"): + return self.getInbDim( full ) + elif(pos == "prg"): + return self.getPrgDim( full ) + elif(pos == "inf"): + return self.getInfDim( full ) + + + def getMaxDim( self, full ): + return [self.maxw, self.maxh] - def getInfDim( self, full ): - return [75, 75] - - - def getPipDim( self, full ): - return [self.pipw, self.piph] - - - def getPgdDim( self, full ): - return [self.pgdw, self.pgdh] - - - def getInbDim( self, full ): - return [self.letterBoxVW, self.letterBoxVH] - - - def getPrgDim( self, full ): - if (not full): - return [self.vw-self.recordButtWd, self.controlBarHt] - else: - return [gtk.gdk.screen_width()-(self.inset+self.inset+self.recordButtWd), self.controlBarHt] - - - def getPrgLoc( self, full ): - if (not full): - return [self.centerBoxPos[0]+self.recordButtWd, self.centerBoxPos[1]+self.vh] - else: - return [self.inset+self.recordButtWd, gtk.gdk.screen_height()-(self.inset+self.controlBarHt)] - - - def getLoc( self, pos, full ): - if (pos == "pip"): - return self.getPipLoc( full ) - elif(pos == "pgd"): - return self.getPgdLoc( full ) - elif(pos == "max"): - return self.getMaxLoc( full ) - elif(pos == "img"): - return self.getImgLoc( full ) - elif(pos == "eye"): - return self.getEyeLoc( full ) - elif(pos == "inb"): - return self.getInbLoc( full ) - elif(pos == "prg"): - return self.getPrgLoc( full ) - elif(pos == "inf"): - return self.getInfLoc( full ) - - - def _shutterClickCb( self, arg ): - self.doShutter() - - - def doShutter( self ): - if (self.UPDATE_TIMER_ID == 0): - if (not self.ca.m.RECORDING): - - self.ca.m.updateXoFullStatus() - if (self.ca.m.FULL): - self.updateButtonSensitivities() - return - - #there is no update timer running, so we need to find out if there is a timer needed - timerTime = 0 - if (self.ca.m.MODE == Constants.MODE_PHOTO): - timerTime = self.photoToolbar.getTimer() - elif (self.ca.m.MODE == Constants.MODE_VIDEO): - timerTime = self.videoToolbar.getTimer() - elif (self.ca.m.MODE == Constants.MODE_AUDIO): - timerTime = self.audioToolbar.getTimer() - - if (timerTime > 0): - self.timerStartTime = time.time() - self.UPDATE_TIMER_ID = gobject.timeout_add( 500, self._updateTimerCb ) - self.COUNTINGDOWN = True - self.ca.m.setUpdating(True) - else: - self.clickShutter() - else: - #or, if there is no countdown, it might be because we are recording - self.clickShutter() - - else: - #we're timing down something, but interrupted by user click or the timer completing - self.completeTimer() - gobject.idle_add( self.clickShutter ) - - - def completeTimer( self ): - self.COUNTINGDOWN = False - self.ca.m.setUpdating(False) - self.recordWindow.updateCountdown(-1) - self.progressWindow.updateProgress( 1, "" ) - gobject.source_remove( self.UPDATE_TIMER_ID ) - self.UPDATE_TIMER_ID = 0 - - - def _updateTimerCb( self ): - nowTime = time.time() - passedTime = nowTime - self.timerStartTime - - timerTime = 0 - if (self.ca.m.MODE == Constants.MODE_PHOTO): - timerTime = self.photoToolbar.getTimer() - elif (self.ca.m.MODE == Constants.MODE_VIDEO): - timerTime = self.videoToolbar.getTimer() - elif (self.ca.m.MODE == Constants.MODE_AUDIO): - timerTime = self.audioToolbar.getTimer() - - if (passedTime >= timerTime): - self.COUNTINGDOWN = False - self.ca.m.setUpdating(False) - self.doShutter() - return False - else: - secsRemaining = timerTime-passedTime - self.progressWindow.updateProgress( passedTime/timerTime, Constants.istrTimer + " " + Constants.istrSecondsRemaining % {"1":str(int(secsRemaining))} ) - self.recordWindow.updateCountdown( int(secsRemaining) ) - return True - - - def clickShutter( self ): - if (not self.ca.m.RECORDING): - os.system( "aplay -t wav " + str(Constants.soundClick) ) - - wasRec = self.ca.m.RECORDING - self.ca.m.doShutter() - if (wasRec): - os.system( "aplay -t wav " + str(Constants.soundClick) ) - - - def updateVideoComponents( self ): - if ( (self.LAST_MODE == self.ca.m.MODE) - and (self.LAST_FULLSCREEN == self.FULLSCREEN) - and (self.LAST_LIVE == self.LIVEMODE) - and (self.LAST_RECD_INFO == self.RECD_INFO_ON) - and (self.LAST_TRANSCODING == self.TRANSCODING) - and (self.LAST_MESHING == self.MESHING) - ): - return - - #something's changing so start counting anew - self.resetWidgetFadeTimer() - - pos = [] - if (self.RECD_INFO_ON and not self.TRANSCODING): - if (self.ca.m.MODE == Constants.MODE_PHOTO): - pos.append({"position":"pgd", "window":self.pipBgdWindow} ) - pos.append({"position":"pip", "window":self.liveVideoWindow} ) - pos.append({"position":"inb", "window":self.livePhotoWindow} ) - pos.append({"position":"inf", "window":self.infWindow} ) - elif (self.ca.m.MODE == Constants.MODE_VIDEO): - pos.append({"position":"pgd", "window":self.pipBgdWindow} ) - pos.append({"position":"pip", "window":self.slowLiveVideoWindow} ) - pos.append({"position":"inb", "window":self.playOggWindow} ) - pos.append({"position":"inf", "window":self.infWindow} ) - elif (self.ca.m.MODE == Constants.MODE_AUDIO): - pos.append({"position":"pgd", "window":self.pipBgdWindow} ) - pos.append({"position":"pip", "window":self.liveVideoWindow} ) - pos.append({"position":"inb", "window":self.livePhotoWindow} ) - pos.append({"position":"inf", "window":self.infWindow} ) - elif (not self.RECD_INFO_ON and not self.TRANSCODING): - if (self.ca.m.MODE == Constants.MODE_PHOTO): - if (self.LIVEMODE): - pos.append({"position":"img", "window":self.liveVideoWindow} ) - pos.append({"position":"max", "window":self.maxWindow} ) - pos.append({"position":"eye", "window":self.recordWindow} ) - else: - pos.append({"position":"img", "window":self.livePhotoWindow} ) - pos.append({"position":"pgd", "window":self.pipBgdWindow} ) - pos.append({"position":"pip", "window":self.liveVideoWindow} ) - if (not self.MESHING): - pos.append({"position":"max", "window":self.maxWindow} ) - pos.append({"position":"inf", "window":self.infWindow} ) - else: - pos.append({"position":"tmr", "window":self.progressWindow} ) - elif (self.ca.m.MODE == Constants.MODE_VIDEO): - if (self.LIVEMODE): - pos.append({"position":"img", "window":self.liveVideoWindow} ) - pos.append({"position":"max", "window":self.maxWindow} ) - pos.append({"position":"eye", "window":self.recordWindow} ) - pos.append({"position":"prg", "window":self.progressWindow} ) - else: - pos.append({"position":"img", "window":self.playOggWindow} ) - pos.append({"position":"pgd", "window":self.pipBgdWindow} ) - pos.append({"position":"pip", "window":self.slowLiveVideoWindow} ) - if (not self.MESHING): - pos.append({"position":"max", "window":self.maxWindow} ) - pos.append({"position":"scr", "window":self.scrubWindow} ) - pos.append({"position":"inf", "window":self.infWindow} ) - else: - pos.append({"position":"tmr", "window":self.progressWindow} ) - elif (self.ca.m.MODE == Constants.MODE_AUDIO): - if (self.LIVEMODE): - pos.append({"position":"img", "window":self.liveVideoWindow} ) - pos.append({"position":"eye", "window":self.recordWindow} ) - pos.append({"position":"prg", "window":self.progressWindow} ) - else: - pos.append({"position":"img", "window":self.livePhotoWindow} ) - pos.append({"position":"pgd", "window":self.pipBgdWindow} ) - pos.append({"position":"pip", "window":self.liveVideoWindow} ) - if (not self.MESHING): - pos.append({"position":"scr", "window":self.scrubWindow} ) - pos.append({"position":"inf", "window":self.infWindow} ) - else: - pos.append({"position":"tmr", "window":self.progressWindow} ) - elif (self.TRANSCODING): - pos.append({"position":"tmr", "window":self.progressWindow} ) - - for i in range (0, len(self.windowStack)): - self.windowStack[i].hide_all() - - self.hideAllWindows() - self.updatePos( pos ) - - for i in range (0, len(self.windowStack)): - self.windowStack[i].show_all() - - self.LAST_MODE = self.ca.m.MODE - self.LAST_FULLSCREEN = self.FULLSCREEN - self.LAST_LIVE = self.LIVEMODE - self.LAST_RECD_INFO = self.RECD_INFO_ON - self.LAST_TRANSCODING = self.TRANSCODING - self.LAST_MESHING = self.MESHING - - - def debugWindows( self ): - for i in range (0, len(self.windowStack)): - print self.windowStack[i], self.windowStack[i].get_size(), self.windowStack[i].get_position() - - - def showWidgets( self ): - pos = [] - if (self.ca.m.MODE == Constants.MODE_PHOTO): - if (not self.LIVEMODE): - pos.append({"position":"pgd", "window":self.pipBgdWindow} ) - pos.append({"position":"pip", "window":self.liveVideoWindow} ) - if (not self.MESHING): - pos.append({"position":"max", "window":self.maxWindow} ) - pos.append({"position":"inf", "window":self.infWindow} ) - else: - pos.append({"position":"max", "window":self.maxWindow} ) - pos.append({"position":"eye", "window":self.recordWindow} ) - elif (self.ca.m.MODE == Constants.MODE_VIDEO): - if (not self.LIVEMODE): - pos.append({"position":"pgd", "window":self.pipBgdWindow} ) - pos.append({"position":"pip", "window":self.slowLiveVideoWindow} ) - if (not self.MESHING): - pos.append({"position":"max", "window":self.maxWindow} ) - pos.append({"position":"scr", "window":self.scrubWindow} ) - pos.append({"position":"inf", "window":self.infWindow} ) - else: - pos.append({"position":"max", "window":self.maxWindow} ) - pos.append({"position":"eye", "window":self.recordWindow} ) - pos.append({"position":"prg", "window":self.progressWindow} ) - elif (self.ca.m.MODE == Constants.MODE_AUDIO): - if (not self.LIVEMODE): - pos.append({"position":"pgd", "window":self.pipBgdWindow} ) - pos.append({"position":"pip", "window":self.liveVideoWindow} ) - if (not self.MESHING): - pos.append({"position":"scr", "window":self.scrubWindow} ) - pos.append({"position":"inf", "window":self.infWindow} ) - else: - pos.append({"position":"eye", "window":self.recordWindow} ) - pos.append({"position":"prg", "window":self.progressWindow} ) - - self.updatePos( pos ) - - - def updatePos( self, pos ): - #now move those pieces where they need to be... - for i in range (0, len(self.windowStack)): - for j in range (0, len(pos)): - if (self.windowStack[i] == pos[j]["window"]): - if (pos[j]["position"] == "img"): - self.setImgLocDim( pos[j]["window"] ) - elif (pos[j]["position"] == "max"): - self.setMaxLocDim( pos[j]["window"] ) - elif (pos[j]["position"] == "pip"): - self.setPipLocDim( pos[j]["window"] ) - elif (pos[j]["position"] == "pgd"): - self.setPipBgdLocDim( pos[j]["window"] ) - elif (pos[j]["position"] == "eye"): - self.setEyeLocDim( pos[j]["window"] ) - elif (pos[j]["position"] == "inb"): - self.setInbLocDim( pos[j]["window"]) - elif (pos[j]["position"] == "prg"): - self.setPrgLocDim( pos[j]["window"]) - elif (pos[j]["position"] == "tmr"): - self.setTmrLocDim( pos[j]["window"]) - elif (pos[j]["position"] == "scr"): - self.setScrLocDim( pos[j]["window"]) - elif (pos[j]["position"] == "inf"): - self.setInfLocDim( pos[j]["window"]) - - - def removeThumb( self, recd ): - kids = self.thumbTray.get_children() - for i in range (0, len(kids)): - if (kids[i].recd == recd): - self.thumbTray.remove_item(kids[i]) - kids[i].cleanUp() - kids[i].disconnect( kids[i].getButtClickedId() ) - kids[i].setButtClickedId(0) - - - def addThumb( self, recd, forceScroll ): - butt = RecdButton( self, recd ) - BUTT_CLICKED_ID = butt.connect( "clicked", self._thumbClicked, recd ) - butt.setButtClickedId(BUTT_CLICKED_ID) - self.thumbTray.add_item( butt, len(self.thumbTray.get_children()) ) - butt.show() - if (forceScroll): - self.thumbTray.scroll_to_end() - - - def removeThumbs( self ): - kids = self.thumbTray.get_children() - for i in range (0, len(kids)): - self.thumbTray.remove_item(kids[i]) - kids[i].cleanUp() - if (kids[i].getButtClickedId() != 0): - kids[i].disconnect( kids[i].getButtClickedId() ) - - - def _thumbClicked( self, button, recd ): - self.showThumbSelection( recd ) - - - def infoButtonClicked( self ): - self.RECD_INFO_ON = not self.RECD_INFO_ON - - centerKid = self.centerBox.get_child() - if (centerKid != None): - self.centerBox.remove( centerKid ) - - bottomKid = self.bottomCenter.get_child() - if (bottomKid != None): - self.bottomCenter.remove( bottomKid ) - - if (not self.RECD_INFO_ON): - if (self.ca.m.MODE == Constants.MODE_PHOTO): - self.bottomCenter.add( self.namePanel ) - self.bottomCenter.show_all( ) - else: - self.centerBox.add( self.infoBox ) - self.centerBox.show_all( ) - self.bottomCenter.add( self.namePanel ) - self.bottomCenter.show_all( ) - - self.updateVideoComponents( ) - - - def showMeshRecd( self, recd ): - record.Record.log.debug('showMeshRecd: heres the downloaded recd to display...') - - #if this thumbnail is being shown, add the option to copy it now - kids = self.thumbTray.get_children() - for i in range (0, len(kids)): - if (kids[i].recd == recd): - kids[i].addCopyMenuItem() - - if (recd == self.shownRecd): - record.Record.log.debug('showMeshRecd: and since were still looking at same recd, here it is!') - self.showThumbSelection( recd ) - - - def updateMeshProgress( self, progressMade, recd ): - self.resetWidgetFadeTimer() - if (self.shownRecd != recd): - if (self.shownRecd == None): - type = Constants.mediaTypes[recd.type][Constants.keyIstr] - if (progressMade): - msg = Constants.istrDownloadingFrom% {"1":type, "2":recd.meshDownloadingFromNick} - self.progressWindow.updateProgress(recd.meshDownlodingPercent, msg) - - else: - type = Constants.mediaTypes[recd.type][Constants.keyIstr] - if (progressMade): - msg = Constants.istrDownloadingFrom% {"1":type, "2":recd.meshDownloadingFromNick} - self.progressWindow.updateProgress(recd.meshDownlodingPercent, msg) - - else: - type = Constants.mediaTypes[recd.type][Constants.keyIstr] - msg = Constants.istrCannotDownload % {"1":type} - self.progressWindow.updateProgress(0, msg) - - - def showThumbSelection( self, recd ): - lastRecd = self.shownRecd - self.shownRecd = recd - - #do we need to know the type, since we're showing based on the mode of the app? - if (recd.type == Constants.TYPE_PHOTO): - self.showPhoto( recd ) - elif (recd.type == Constants.TYPE_VIDEO): - self.showVideo( recd ) - elif (recd.type == Constants.TYPE_AUDIO): - self.showAudio( recd ) - - if (self.shownRecd != lastRecd): - self.photoXoPanel.updateXoColors(self.shownRecd.colorStroke.hex, self.shownRecd.colorFill.hex) - - bottomKid = self.bottomCenter.get_child() - if (bottomKid != None): - self.bottomCenter.remove( bottomKid ) - - if (recd.type == Constants.TYPE_PHOTO): - self.bottomCenter.add( self.namePanel ) - elif (recd.type == Constants.TYPE_VIDEO or recd.type == Constants.TYPE_AUDIO): - if (self.RECD_INFO_ON): - self.bottomCenter.add( self.namePanel ) - self.bottomCenter.show_all() + def getInfDim( self, full ): + return [75, 75] + + + def getPipDim( self, full ): + return [self.pipw, self.piph] + + + def getPgdDim( self, full ): + return [self.pgdw, self.pgdh] + + + def getInbDim( self, full ): + return [self.letterBoxVW, self.letterBoxVH] + + + def getPrgDim( self, full ): + if (not full): + return [self.vw-self.recordButtWd, self.controlBarHt] + else: + return [gtk.gdk.screen_width()-(self.inset+self.inset+self.recordButtWd), self.controlBarHt] + + + def getPrgLoc( self, full ): + if (not full): + return [self.centerBoxPos[0]+self.recordButtWd, self.centerBoxPos[1]+self.vh] + else: + return [self.inset+self.recordButtWd, gtk.gdk.screen_height()-(self.inset+self.controlBarHt)] + + + def getLoc( self, pos, full ): + if (pos == "pip"): + return self.getPipLoc( full ) + elif(pos == "pgd"): + return self.getPgdLoc( full ) + elif(pos == "max"): + return self.getMaxLoc( full ) + elif(pos == "img"): + return self.getImgLoc( full ) + elif(pos == "eye"): + return self.getEyeLoc( full ) + elif(pos == "inb"): + return self.getInbLoc( full ) + elif(pos == "prg"): + return self.getPrgLoc( full ) + elif(pos == "inf"): + return self.getInfLoc( full ) + + + def _shutterClickCb( self, arg ): + self.doShutter() + + + def doShutter( self ): + if (self.UPDATE_TIMER_ID == 0): + if (not self.ca.m.RECORDING): + + self.ca.m.updateXoFullStatus() + if (self.ca.m.FULL): + self.updateButtonSensitivities() + return + + #there is no update timer running, so we need to find out if there is a timer needed + timerTime = 0 + if (self.ca.m.MODE == Constants.MODE_PHOTO): + timerTime = self.photoToolbar.getTimer() + elif (self.ca.m.MODE == Constants.MODE_VIDEO): + timerTime = self.videoToolbar.getTimer() + elif (self.ca.m.MODE == Constants.MODE_AUDIO): + timerTime = self.audioToolbar.getTimer() + + if (timerTime > 0): + self.timerStartTime = time.time() + self.UPDATE_TIMER_ID = gobject.timeout_add( 500, self._updateTimerCb ) + self.COUNTINGDOWN = True + self.ca.m.setUpdating(True) + else: + self.clickShutter() + else: + #or, if there is no countdown, it might be because we are recording + self.clickShutter() + + else: + #we're timing down something, but interrupted by user click or the timer completing + self.completeTimer() + gobject.idle_add( self.clickShutter ) + + + def completeTimer( self ): + self.COUNTINGDOWN = False + self.ca.m.setUpdating(False) + self.recordWindow.updateCountdown(-1) + self.progressWindow.updateProgress( 1, "" ) + gobject.source_remove( self.UPDATE_TIMER_ID ) + self.UPDATE_TIMER_ID = 0 + + + def _updateTimerCb( self ): + nowTime = time.time() + passedTime = nowTime - self.timerStartTime + + timerTime = 0 + if (self.ca.m.MODE == Constants.MODE_PHOTO): + timerTime = self.photoToolbar.getTimer() + elif (self.ca.m.MODE == Constants.MODE_VIDEO): + timerTime = self.videoToolbar.getTimer() + elif (self.ca.m.MODE == Constants.MODE_AUDIO): + timerTime = self.audioToolbar.getTimer() + + if (passedTime >= timerTime): + self.COUNTINGDOWN = False + self.ca.m.setUpdating(False) + self.doShutter() + return False + else: + secsRemaining = timerTime-passedTime + self.progressWindow.updateProgress( passedTime/timerTime, Constants.istrTimer + " " + Constants.istrSecondsRemaining % {"1":str(int(secsRemaining))} ) + self.recordWindow.updateCountdown( int(secsRemaining) ) + return True + + + def clickShutter( self ): + if (not self.ca.m.RECORDING): + os.system( "aplay -t wav " + str(Constants.soundClick) ) + + wasRec = self.ca.m.RECORDING + self.ca.m.doShutter() + if (wasRec): + os.system( "aplay -t wav " + str(Constants.soundClick) ) + + + def updateVideoComponents( self ): + if ( (self.LAST_MODE == self.ca.m.MODE) + and (self.LAST_FULLSCREEN == self.FULLSCREEN) + and (self.LAST_LIVE == self.LIVEMODE) + and (self.LAST_RECD_INFO == self.RECD_INFO_ON) + and (self.LAST_TRANSCODING == self.TRANSCODING) + and (self.LAST_MESHING == self.MESHING) + ): + return + + #something's changing so start counting anew + self.resetWidgetFadeTimer() + + pos = [] + if (self.RECD_INFO_ON and not self.TRANSCODING): + if (self.ca.m.MODE == Constants.MODE_PHOTO): + pos.append({"position":"pgd", "window":self.pipBgdWindow} ) + pos.append({"position":"pip", "window":self.liveVideoWindow} ) + pos.append({"position":"inb", "window":self.livePhotoWindow} ) + pos.append({"position":"inf", "window":self.infWindow} ) + elif (self.ca.m.MODE == Constants.MODE_VIDEO): + pos.append({"position":"pgd", "window":self.pipBgdWindow} ) + pos.append({"position":"pip", "window":self.slowLiveVideoWindow} ) + pos.append({"position":"inb", "window":self.playOggWindow} ) + pos.append({"position":"inf", "window":self.infWindow} ) + elif (self.ca.m.MODE == Constants.MODE_AUDIO): + pos.append({"position":"pgd", "window":self.pipBgdWindow} ) + pos.append({"position":"pip", "window":self.liveVideoWindow} ) + pos.append({"position":"inb", "window":self.livePhotoWindow} ) + pos.append({"position":"inf", "window":self.infWindow} ) + elif (not self.RECD_INFO_ON and not self.TRANSCODING): + if (self.ca.m.MODE == Constants.MODE_PHOTO): + if (self.LIVEMODE): + pos.append({"position":"img", "window":self.liveVideoWindow} ) + pos.append({"position":"max", "window":self.maxWindow} ) + pos.append({"position":"eye", "window":self.recordWindow} ) + else: + pos.append({"position":"img", "window":self.livePhotoWindow} ) + pos.append({"position":"pgd", "window":self.pipBgdWindow} ) + pos.append({"position":"pip", "window":self.liveVideoWindow} ) + if (not self.MESHING): + pos.append({"position":"max", "window":self.maxWindow} ) + pos.append({"position":"inf", "window":self.infWindow} ) + else: + pos.append({"position":"tmr", "window":self.progressWindow} ) + elif (self.ca.m.MODE == Constants.MODE_VIDEO): + if (self.LIVEMODE): + pos.append({"position":"img", "window":self.liveVideoWindow} ) + pos.append({"position":"max", "window":self.maxWindow} ) + pos.append({"position":"eye", "window":self.recordWindow} ) + pos.append({"position":"prg", "window":self.progressWindow} ) + else: + pos.append({"position":"img", "window":self.playOggWindow} ) + pos.append({"position":"pgd", "window":self.pipBgdWindow} ) + pos.append({"position":"pip", "window":self.slowLiveVideoWindow} ) + if (not self.MESHING): + pos.append({"position":"max", "window":self.maxWindow} ) + pos.append({"position":"scr", "window":self.scrubWindow} ) + pos.append({"position":"inf", "window":self.infWindow} ) + else: + pos.append({"position":"tmr", "window":self.progressWindow} ) + elif (self.ca.m.MODE == Constants.MODE_AUDIO): + if (self.LIVEMODE): + pos.append({"position":"img", "window":self.liveVideoWindow} ) + pos.append({"position":"eye", "window":self.recordWindow} ) + pos.append({"position":"prg", "window":self.progressWindow} ) + else: + pos.append({"position":"img", "window":self.livePhotoWindow} ) + pos.append({"position":"pgd", "window":self.pipBgdWindow} ) + pos.append({"position":"pip", "window":self.liveVideoWindow} ) + if (not self.MESHING): + pos.append({"position":"scr", "window":self.scrubWindow} ) + pos.append({"position":"inf", "window":self.infWindow} ) + else: + pos.append({"position":"tmr", "window":self.progressWindow} ) + elif (self.TRANSCODING): + pos.append({"position":"tmr", "window":self.progressWindow} ) + + for i in range (0, len(self.windowStack)): + self.windowStack[i].hide_all() + + self.hideAllWindows() + self.updatePos( pos ) + + for i in range (0, len(self.windowStack)): + self.windowStack[i].show_all() + + self.LAST_MODE = self.ca.m.MODE + self.LAST_FULLSCREEN = self.FULLSCREEN + self.LAST_LIVE = self.LIVEMODE + self.LAST_RECD_INFO = self.RECD_INFO_ON + self.LAST_TRANSCODING = self.TRANSCODING + self.LAST_MESHING = self.MESHING + + + def debugWindows( self ): + for i in range (0, len(self.windowStack)): + print self.windowStack[i], self.windowStack[i].get_size(), self.windowStack[i].get_position() + + + def showWidgets( self ): + pos = [] + if (self.ca.m.MODE == Constants.MODE_PHOTO): + if (not self.LIVEMODE): + pos.append({"position":"pgd", "window":self.pipBgdWindow} ) + pos.append({"position":"pip", "window":self.liveVideoWindow} ) + if (not self.MESHING): + pos.append({"position":"max", "window":self.maxWindow} ) + pos.append({"position":"inf", "window":self.infWindow} ) + else: + pos.append({"position":"max", "window":self.maxWindow} ) + pos.append({"position":"eye", "window":self.recordWindow} ) + elif (self.ca.m.MODE == Constants.MODE_VIDEO): + if (not self.LIVEMODE): + pos.append({"position":"pgd", "window":self.pipBgdWindow} ) + pos.append({"position":"pip", "window":self.slowLiveVideoWindow} ) + if (not self.MESHING): + pos.append({"position":"max", "window":self.maxWindow} ) + pos.append({"position":"scr", "window":self.scrubWindow} ) + pos.append({"position":"inf", "window":self.infWindow} ) + else: + pos.append({"position":"max", "window":self.maxWindow} ) + pos.append({"position":"eye", "window":self.recordWindow} ) + pos.append({"position":"prg", "window":self.progressWindow} ) + elif (self.ca.m.MODE == Constants.MODE_AUDIO): + if (not self.LIVEMODE): + pos.append({"position":"pgd", "window":self.pipBgdWindow} ) + pos.append({"position":"pip", "window":self.liveVideoWindow} ) + if (not self.MESHING): + pos.append({"position":"scr", "window":self.scrubWindow} ) + pos.append({"position":"inf", "window":self.infWindow} ) + else: + pos.append({"position":"eye", "window":self.recordWindow} ) + pos.append({"position":"prg", "window":self.progressWindow} ) + + self.updatePos( pos ) + + + def updatePos( self, pos ): + #now move those pieces where they need to be... + for i in range (0, len(self.windowStack)): + for j in range (0, len(pos)): + if (self.windowStack[i] == pos[j]["window"]): + if (pos[j]["position"] == "img"): + self.setImgLocDim( pos[j]["window"] ) + elif (pos[j]["position"] == "max"): + self.setMaxLocDim( pos[j]["window"] ) + elif (pos[j]["position"] == "pip"): + self.setPipLocDim( pos[j]["window"] ) + elif (pos[j]["position"] == "pgd"): + self.setPipBgdLocDim( pos[j]["window"] ) + elif (pos[j]["position"] == "eye"): + self.setEyeLocDim( pos[j]["window"] ) + elif (pos[j]["position"] == "inb"): + self.setInbLocDim( pos[j]["window"]) + elif (pos[j]["position"] == "prg"): + self.setPrgLocDim( pos[j]["window"]) + elif (pos[j]["position"] == "tmr"): + self.setTmrLocDim( pos[j]["window"]) + elif (pos[j]["position"] == "scr"): + self.setScrLocDim( pos[j]["window"]) + elif (pos[j]["position"] == "inf"): + self.setInfLocDim( pos[j]["window"]) + + + def removeThumb( self, recd ): + kids = self.thumbTray.get_children() + for i in range (0, len(kids)): + if (kids[i].recd == recd): + self.thumbTray.remove_item(kids[i]) + kids[i].cleanUp() + kids[i].disconnect( kids[i].getButtClickedId() ) + kids[i].setButtClickedId(0) + + + def addThumb( self, recd, forceScroll ): + butt = RecdButton( self, recd ) + BUTT_CLICKED_ID = butt.connect( "clicked", self._thumbClicked, recd ) + butt.setButtClickedId(BUTT_CLICKED_ID) + self.thumbTray.add_item( butt, len(self.thumbTray.get_children()) ) + butt.show() + if (forceScroll): + self.thumbTray.scroll_to_end() + + + def removeThumbs( self ): + kids = self.thumbTray.get_children() + for i in range (0, len(kids)): + self.thumbTray.remove_item(kids[i]) + kids[i].cleanUp() + if (kids[i].getButtClickedId() != 0): + kids[i].disconnect( kids[i].getButtClickedId() ) + + + def _thumbClicked( self, button, recd ): + self.showThumbSelection( recd ) + + + def infoButtonClicked( self ): + self.RECD_INFO_ON = not self.RECD_INFO_ON + + centerKid = self.centerBox.get_child() + if (centerKid != None): + self.centerBox.remove( centerKid ) + + bottomKid = self.bottomCenter.get_child() + if (bottomKid != None): + self.bottomCenter.remove( bottomKid ) + + if (not self.RECD_INFO_ON): + if (self.ca.m.MODE == Constants.MODE_PHOTO): + self.bottomCenter.add( self.namePanel ) + self.bottomCenter.show_all( ) + else: + self.centerBox.add( self.infoBox ) + self.centerBox.show_all( ) + self.bottomCenter.add( self.namePanel ) + self.bottomCenter.show_all( ) + + self.updateVideoComponents( ) + + + def showMeshRecd( self, recd ): + record.Record.log.debug('showMeshRecd: heres the downloaded recd to display...') + + #if this thumbnail is being shown, add the option to copy it now + kids = self.thumbTray.get_children() + for i in range (0, len(kids)): + if (kids[i].recd == recd): + kids[i].addCopyMenuItem() + + if (recd == self.shownRecd): + record.Record.log.debug('showMeshRecd: and since were still looking at same recd, here it is!') + self.showThumbSelection( recd ) + + + def updateMeshProgress( self, progressMade, recd ): + self.resetWidgetFadeTimer() + if (self.shownRecd != recd): + if (self.shownRecd == None): + type = Constants.mediaTypes[recd.type][Constants.keyIstr] + if (progressMade): + msg = Constants.istrDownloadingFrom% {"1":type, "2":recd.meshDownloadingFromNick} + self.progressWindow.updateProgress(recd.meshDownlodingPercent, msg) + + else: + type = Constants.mediaTypes[recd.type][Constants.keyIstr] + if (progressMade): + msg = Constants.istrDownloadingFrom% {"1":type, "2":recd.meshDownloadingFromNick} + self.progressWindow.updateProgress(recd.meshDownlodingPercent, msg) + + else: + type = Constants.mediaTypes[recd.type][Constants.keyIstr] + msg = Constants.istrCannotDownload % {"1":type} + self.progressWindow.updateProgress(0, msg) + + + def showThumbSelection( self, recd ): + lastRecd = self.shownRecd + self.shownRecd = recd + + #do we need to know the type, since we're showing based on the mode of the app? + if (recd.type == Constants.TYPE_PHOTO): + self.showPhoto( recd ) + elif (recd.type == Constants.TYPE_VIDEO): + self.showVideo( recd ) + elif (recd.type == Constants.TYPE_AUDIO): + self.showAudio( recd ) + + if (self.shownRecd != lastRecd): + self.photoXoPanel.updateXoColors(self.shownRecd.colorStroke.hex, self.shownRecd.colorFill.hex) + + bottomKid = self.bottomCenter.get_child() + if (bottomKid != None): + self.bottomCenter.remove( bottomKid ) + + if (recd.type == Constants.TYPE_PHOTO): + self.bottomCenter.add( self.namePanel ) + elif (recd.type == Constants.TYPE_VIDEO or recd.type == Constants.TYPE_AUDIO): + if (self.RECD_INFO_ON): + self.bottomCenter.add( self.namePanel ) + self.bottomCenter.show_all() - self.resetWidgetFadeTimer() - - - def showAudio( self, recd ): - self.LIVEMODE = False - - #if (recd != self.shownRecd): - pixbuf = recd.getAudioImagePixbuf() - img = camerac.cairo_surface_from_gdk_pixbuf(pixbuf) - self.livePhotoCanvas.setImage( img ) - #self.shownRecd = recd - self.showRecdMeta(recd) - - downloading = self.ca.requestMeshDownload(recd) - self.MESHING = downloading - record.Record.log.debug("showAudio: downloading->" + str(downloading)) - if (not downloading): - self.progressWindow.updateProgress(0, "") - mediaFilepath = recd.getMediaFilepath( ) - record.Record.log.debug("showAudio: mediaFilepath->" + str(mediaFilepath)) - if (mediaFilepath != None): - videoUrl = "file://" + str( mediaFilepath ) - self.ca.gplay.setLocation(videoUrl) - self.scrubWindow.doPlay() - - self.updateVideoComponents() - - - def showVideo( self, recd ): - downloading = self.ca.requestMeshDownload(recd) - - if (not downloading): - self.progressWindow.updateProgress(0, "") - - self.MESHING = downloading - self.LIVEMODE = False - #self.shownRecd = recd - self.updateVideoComponents() - gobject.idle_add( self.showVideo2, recd, downloading ) - - - def showVideo2( self, recd, downloading ): - self.showRecdMeta(recd) + self.resetWidgetFadeTimer() + + + def showAudio( self, recd ): + self.LIVEMODE = False + + #if (recd != self.shownRecd): + pixbuf = recd.getAudioImagePixbuf() + img = camerac.cairo_surface_from_gdk_pixbuf(pixbuf) + self.livePhotoCanvas.setImage( img ) + #self.shownRecd = recd + self.showRecdMeta(recd) + + downloading = self.ca.requestMeshDownload(recd) + self.MESHING = downloading + record.Record.log.debug("showAudio: downloading->" + str(downloading)) + if (not downloading): + self.progressWindow.updateProgress(0, "") + mediaFilepath = recd.getMediaFilepath( ) + record.Record.log.debug("showAudio: mediaFilepath->" + str(mediaFilepath)) + if (mediaFilepath != None): + videoUrl = "file://" + str( mediaFilepath ) + self.ca.gplay.setLocation(videoUrl) + self.scrubWindow.doPlay() + + self.updateVideoComponents() + + + def showVideo( self, recd ): + downloading = self.ca.requestMeshDownload(recd) + + if (not downloading): + self.progressWindow.updateProgress(0, "") + + self.MESHING = downloading + self.LIVEMODE = False + #self.shownRecd = recd + self.updateVideoComponents() + gobject.idle_add( self.showVideo2, recd, downloading ) + + + def showVideo2( self, recd, downloading ): + self.showRecdMeta(recd) - ableToShowVideo = False - if (not downloading): - mediaFilepath = recd.getMediaFilepath() - if (mediaFilepath != None): - self.ca.glive.stop() - self.ca.glivex.play() - videoUrl = "file://" + str( mediaFilepath ) - self.ca.gplay.setLocation(videoUrl) - self.scrubWindow.doPlay() - ableToShowVideo = True + ableToShowVideo = False + if (not downloading): + mediaFilepath = recd.getMediaFilepath() + if (mediaFilepath != None): + self.ca.glive.stop() + self.ca.glivex.play() + videoUrl = "file://" + str( mediaFilepath ) + self.ca.gplay.setLocation(videoUrl) + self.scrubWindow.doPlay() + ableToShowVideo = True - if (not ableToShowVideo): - # FIXME is this correct? - self.ca.glive.stop() - self.ca.glivex.play() - thumbFilepath = recd.getThumbFilepath( ) - thumbUrl = "file://" + str( thumbFilepath ) - self.ca.gplay.setLocation(thumbUrl) + if (not ableToShowVideo): + # FIXME is this correct? + self.ca.glive.stop() + self.ca.glivex.play() + thumbFilepath = recd.getThumbFilepath( ) + thumbUrl = "file://" + str( thumbFilepath ) + self.ca.gplay.setLocation(thumbUrl) - def deleteThumbSelection( self, recd ): - self.ca.m.deleteRecorded( recd ) - self.removeThumb( recd ) - self.removeIfSelectedRecorded( recd ) + def deleteThumbSelection( self, recd ): + self.ca.m.deleteRecorded( recd ) + self.removeThumb( recd ) + self.removeIfSelectedRecorded( recd ) - def removeIfSelectedRecorded( self, recd ): - if (recd == self.shownRecd): - if (recd.type == Constants.TYPE_PHOTO): - self.livePhotoCanvas.setImage( None ) - elif (recd.type == Constants.TYPE_VIDEO): - self.ca.gplay.stop() - self.startLiveVideo( False ) - elif (recd.type == Constants.TYPE_AUDIO): - self.livePhotoCanvas.setImage( None ) - self.startLiveAudio() + def removeIfSelectedRecorded( self, recd ): + if (recd == self.shownRecd): + if (recd.type == Constants.TYPE_PHOTO): + self.livePhotoCanvas.setImage( None ) + elif (recd.type == Constants.TYPE_VIDEO): + self.ca.gplay.stop() + self.startLiveVideo( False ) + elif (recd.type == Constants.TYPE_AUDIO): + self.livePhotoCanvas.setImage( None ) + self.startLiveAudio() - self.LIVEMODE = True - self.updateVideoComponents() + self.LIVEMODE = True + self.updateVideoComponents() - self.showLiveVideoTags() + self.showLiveVideoTags() - def startLiveAudio( self ): - self.ca.m.setUpdating(True) - self.ca.gplay.stop() + def startLiveAudio( self ): + self.ca.m.setUpdating(True) + self.ca.gplay.stop() - self.liveVideoWindow.set_glive(self.ca.glive) + self.liveVideoWindow.set_glive(self.ca.glive) - self.showLiveVideoTags() - self.LIVEMODE = True - self.updateVideoComponents() - self.ca.m.setUpdating(False) + self.showLiveVideoTags() + self.LIVEMODE = True + self.updateVideoComponents() + self.ca.m.setUpdating(False) - def showPostProcessGfx( self, show ): - #not self.FULLSCREEN - centerKid = self.centerBox.get_child() - if (centerKid != None): - self.centerBox.remove( centerKid ) + def showPostProcessGfx( self, show ): + #not self.FULLSCREEN + centerKid = self.centerBox.get_child() + if (centerKid != None): + self.centerBox.remove( centerKid ) - if ( show ): - self.centerBox.add( self.backgdCanvasBox ) - self.centerBox.show_all() - else: - self.backgdCanvas.setImage( None ) + if ( show ): + self.centerBox.add( self.backgdCanvasBox ) + self.centerBox.show_all() + else: + self.backgdCanvas.setImage( None ) - def setPostProcessPixBuf( self, pixbuf ): - if (pixbuf.get_width()>self.__class__.dim_THUMB_WIDTH): - pixbuf = pixbuf.scale_simple(self.__class__.dim_THUMB_WIDTH, self.__class__.dim_THUMB_HEIGHT, gtk.gdk.INTERP_NEAREST) + def setPostProcessPixBuf( self, pixbuf ): + if (pixbuf.get_width()>self.__class__.dim_THUMB_WIDTH): + pixbuf = pixbuf.scale_simple(self.__class__.dim_THUMB_WIDTH, self.__class__.dim_THUMB_HEIGHT, gtk.gdk.INTERP_NEAREST) - pixbuf = utils.grayScalePixBuf(pixbuf, True) - img = camerac.cairo_surface_from_gdk_pixbuf(pixbuf) - self.backgdCanvas.setImage(img) + pixbuf = utils.grayScalePixBuf(pixbuf, True) + img = camerac.cairo_surface_from_gdk_pixbuf(pixbuf) + self.backgdCanvas.setImage(img) - def showRecdMeta( self, recd ): - self.photographerNameLabel.set_label( recd.recorderName ) - self.nameTextfield.set_text( recd.title ) - self.nameTextfield.set_sensitive( True ) - self.tagsBuffer.set_text( recd.tags ) - self.dateDateLabel.set_label( utils.getDateString(recd.time) ) + def showRecdMeta( self, recd ): + self.photographerNameLabel.set_label( recd.recorderName ) + self.nameTextfield.set_text( recd.title ) + self.nameTextfield.set_sensitive( True ) + self.tagsBuffer.set_text( recd.tags ) + self.dateDateLabel.set_label( utils.getDateString(recd.time) ) - self.photographerPanel.show() - self.namePanel.show() - self.datePanel.show() - self.tagsPanel.show() - self.tagsField.set_sensitive(True) + self.photographerPanel.show() + self.namePanel.show() + self.datePanel.show() + self.tagsPanel.show() + self.tagsField.set_sensitive(True) - def setWaitCursor( self, win ): - win.set_cursor( gtk.gdk.Cursor(gtk.gdk.WATCH) ) + def setWaitCursor( self, win ): + win.set_cursor( gtk.gdk.Cursor(gtk.gdk.WATCH) ) - def setDefaultCursor( self, win ): - win.set_cursor( None ) + def setDefaultCursor( self, win ): + win.set_cursor( None ) class PhotoCanvas(P5): - def __init__(self): - P5.__init__(self) - self.img = None - self.drawImg = None - self.SCALING_IMG_ID = 0 - self.cacheWid = -1 - self.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - self.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) + def __init__(self): + P5.__init__(self) + self.img = None + self.drawImg = None + self.SCALING_IMG_ID = 0 + self.cacheWid = -1 + self.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + self.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) - def draw(self, ctx, w, h): - self.background( ctx, Constants.colorBlack, w, h ) + def draw(self, ctx, w, h): + self.background( ctx, Constants.colorBlack, w, h ) - if (self.img != None): + if (self.img != None): - if (w == self.img.get_width()): - self.cacheWid == w - self.drawImg = self.img + if (w == self.img.get_width()): + self.cacheWid == w + self.drawImg = self.img - #only scale images when you need to, otherwise you're wasting cycles, fool! - if (self.cacheWid != w): - if (self.SCALING_IMG_ID == 0): - self.drawImg = None - self.SCALING_IMG_ID = gobject.idle_add( self.resizeImage, w, h ) + #only scale images when you need to, otherwise you're wasting cycles, fool! + if (self.cacheWid != w): + if (self.SCALING_IMG_ID == 0): + self.drawImg = None + self.SCALING_IMG_ID = gobject.idle_add( self.resizeImage, w, h ) - if (self.drawImg != None): - #center the image based on the image size, and w & h - ctx.set_source_surface(self.drawImg, (w/2)-(self.drawImg.get_width()/2), (h/2)-(self.drawImg.get_height()/2)) - ctx.paint() + if (self.drawImg != None): + #center the image based on the image size, and w & h + ctx.set_source_surface(self.drawImg, (w/2)-(self.drawImg.get_width()/2), (h/2)-(self.drawImg.get_height()/2)) + ctx.paint() - self.cacheWid = w + self.cacheWid = w - def setImage(self, img): - self.cacheWid = -1 - self.img = img - self.drawImg = None - self.queue_draw() + def setImage(self, img): + self.cacheWid = -1 + self.img = img + self.drawImg = None + self.queue_draw() - def resizeImage(self, w, h): - self.SCALING_IMG_ID = 0 - if (self.img == None): - return + def resizeImage(self, w, h): + self.SCALING_IMG_ID = 0 + if (self.img == None): + return - #use image size in case 640 no more - scaleImg = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h) - sCtx = cairo.Context(scaleImg) - sScl = (w+0.0)/(self.img.get_width()+0.0) - sCtx.scale( sScl, sScl ) - sCtx.set_source_surface( self.img, 0, 0 ) - sCtx.paint() - self.drawImg = scaleImg - self.cacheWid = w - self.queue_draw() + #use image size in case 640 no more + scaleImg = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h) + sCtx = cairo.Context(scaleImg) + sScl = (w+0.0)/(self.img.get_width()+0.0) + sCtx.scale( sScl, sScl ) + sCtx.set_source_surface( self.img, 0, 0 ) + sCtx.paint() + self.drawImg = scaleImg + self.cacheWid = w + self.queue_draw() class xoPanel(P5): - def __init__(self): - P5.__init__(self) - self.xoGuy = None - self.lastStroke = None - self.lastFill = None + def __init__(self): + P5.__init__(self) + self.xoGuy = None + self.lastStroke = None + self.lastFill = None - def updateXoColors( self, strokeHex, fillHex ): - if (self.lastStroke != None): - if ((self.lastStroke == strokeHex) and (self.lastFill == fillHex)): - return + def updateXoColors( self, strokeHex, fillHex ): + if (self.lastStroke != None): + if ((self.lastStroke == strokeHex) and (self.lastFill == fillHex)): + return - lastStroke = strokeHex - lastFill = fillHex - self.xoGuy = utils.loadSvg(Constants.xoGuySvgData, strokeHex, fillHex) - self.queue_draw() + lastStroke = strokeHex + lastFill = fillHex + self.xoGuy = utils.loadSvg(Constants.xoGuySvgData, strokeHex, fillHex) + self.queue_draw() - def draw(self, ctx, w, h): - #todo: 2x buffer - self.background( ctx, Constants.colorButton, w, h ) + def draw(self, ctx, w, h): + #todo: 2x buffer + self.background( ctx, Constants.colorButton, w, h ) - if (self.xoGuy != None): - #todo: scale mr xo to fit in his box - ctx.scale( .6, .6 ) - self.xoGuy.render_cairo( ctx ) + if (self.xoGuy != None): + #todo: scale mr xo to fit in his box + ctx.scale( .6, .6 ) + self.xoGuy.render_cairo( ctx ) class ScrubberWindow(gtk.Window): - def __init__(self, ui): - gtk.Window.__init__(self) - self.ui = ui - self.UPDATE_INTERVAL = 500 - self.UPDATE_SCALE_ID = 0 - self.CHANGED_ID = 0 - self.was_playing = False - self.p_position = gst.CLOCK_TIME_NONE - self.p_duration = gst.CLOCK_TIME_NONE - - self.hbox = gtk.HBox() - self.hbox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - self.hbox.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) - self.add( self.hbox ) - - self.button = gtk.Button() - buttBox = gtk.EventBox() - buttBox.add(self.button) - buttBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - self.button.set_image( Constants.recPlayImg ) - self.button.set_property('can-default', True) - self.button.set_relief(gtk.RELIEF_NONE) - self.button.set_size_request( self.ui.recordButtWd, self.ui.recordButtWd ) - buttBox.set_size_request( self.ui.recordButtWd, self.ui.recordButtWd ) - #self.button.set_border_width( UI.dim_INSET/2 ) - self.button.show() - - buttBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - self.button.modify_bg( gtk.STATE_ACTIVE, Constants.colorBlack.gColor ) - - self.button.connect('clicked', self._buttonClickedCb) - self.hbox.pack_start(buttBox, expand=False) - - self.adjustment = gtk.Adjustment(0.0, 0.00, 100.0, 0.1, 1.0, 1.0) - self.hscale = gtk.HScale(self.adjustment) - self.hscale.set_draw_value(False) - self.hscale.set_update_policy(gtk.UPDATE_CONTINUOUS) - hscaleBox = gtk.EventBox() - hscaleBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - hscaleBox.add( self.hscale ) - self.hscale.connect('button-press-event', self._scaleButtonPressCb) - self.hscale.connect('button-release-event', self._scaleButtonReleaseCb) - self.hbox.pack_start(hscaleBox, expand=True) - - - def removeCallbacks( self ): - if (self.UPDATE_SCALE_ID != 0): - gobject.source_remove(self.UPDATE_SCALE_ID) - self.UPDATE_SCALE_ID = 0 - if (self.CHANGED_ID != 0): - gobject.source_remove(self.CHANGED_ID) - self.CHANGED_ID = 0 + def __init__(self, ui): + gtk.Window.__init__(self) + self.ui = ui + self.UPDATE_INTERVAL = 500 + self.UPDATE_SCALE_ID = 0 + self.CHANGED_ID = 0 + self.was_playing = False + self.p_position = gst.CLOCK_TIME_NONE + self.p_duration = gst.CLOCK_TIME_NONE + + self.hbox = gtk.HBox() + self.hbox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + self.hbox.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) + self.add( self.hbox ) + + self.button = gtk.Button() + buttBox = gtk.EventBox() + buttBox.add(self.button) + buttBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + self.button.set_image( Constants.recPlayImg ) + self.button.set_property('can-default', True) + self.button.set_relief(gtk.RELIEF_NONE) + self.button.set_size_request( self.ui.recordButtWd, self.ui.recordButtWd ) + buttBox.set_size_request( self.ui.recordButtWd, self.ui.recordButtWd ) + #self.button.set_border_width( UI.dim_INSET/2 ) + self.button.show() + + buttBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + self.button.modify_bg( gtk.STATE_ACTIVE, Constants.colorBlack.gColor ) + + self.button.connect('clicked', self._buttonClickedCb) + self.hbox.pack_start(buttBox, expand=False) + + self.adjustment = gtk.Adjustment(0.0, 0.00, 100.0, 0.1, 1.0, 1.0) + self.hscale = gtk.HScale(self.adjustment) + self.hscale.set_draw_value(False) + self.hscale.set_update_policy(gtk.UPDATE_CONTINUOUS) + hscaleBox = gtk.EventBox() + hscaleBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + hscaleBox.add( self.hscale ) + self.hscale.connect('button-press-event', self._scaleButtonPressCb) + self.hscale.connect('button-release-event', self._scaleButtonReleaseCb) + self.hbox.pack_start(hscaleBox, expand=True) + + + def removeCallbacks( self ): + if (self.UPDATE_SCALE_ID != 0): + gobject.source_remove(self.UPDATE_SCALE_ID) + self.UPDATE_SCALE_ID = 0 + if (self.CHANGED_ID != 0): + gobject.source_remove(self.CHANGED_ID) + self.CHANGED_ID = 0 - def reset(self): - self.adjustment.set_value(0) + def reset(self): + self.adjustment.set_value(0) - def _buttonClickedCb(self, widget): - self.play_toggled() + def _buttonClickedCb(self, widget): + self.play_toggled() - def set_button_play(self): - self.button.set_image(Constants.recPlayImg) + def set_button_play(self): + self.button.set_image(Constants.recPlayImg) - def set_button_pause(self): - self.button.set_image(Constants.recPauseImg) + def set_button_pause(self): + self.button.set_image(Constants.recPauseImg) - def play_toggled(self): - self.p_position, self.p_duration = self.ui.ca.gplay.queryPosition() - if (self.p_position == self.p_duration): - self.ui.ca.gplay.seek(0) - self.ui.ca.gplay.pause() + def play_toggled(self): + self.p_position, self.p_duration = self.ui.ca.gplay.queryPosition() + if (self.p_position == self.p_duration): + self.ui.ca.gplay.seek(0) + self.ui.ca.gplay.pause() - if self.ui.ca.gplay.is_playing(): - self.ui.ca.gplay.pause() - self.set_button_play() - else: - #if self.ui.ca.gplay.error: - # #todo: check if we have "error", and also to disable everything - # self.button.set_disabled() - #else: - self.doPlay() + if self.ui.ca.gplay.is_playing(): + self.ui.ca.gplay.pause() + self.set_button_play() + else: + #if self.ui.ca.gplay.error: + # #todo: check if we have "error", and also to disable everything + # self.button.set_disabled() + #else: + self.doPlay() - def doPlay(self): - self.ui.ca.gplay.play() - if self.UPDATE_SCALE_ID == 0: - self.UPDATE_SCALE_ID = gobject.timeout_add(self.UPDATE_INTERVAL, self._updateScaleCb) - self.set_button_pause() + def doPlay(self): + self.ui.ca.gplay.play() + if self.UPDATE_SCALE_ID == 0: + self.UPDATE_SCALE_ID = gobject.timeout_add(self.UPDATE_INTERVAL, self._updateScaleCb) + self.set_button_pause() - def _scaleButtonPressCb(self, widget, event): - #self.button.set_sensitive(False) - self.was_playing = self.ui.ca.gplay.is_playing() - if self.was_playing: - self.ui.ca.gplay.pause() + def _scaleButtonPressCb(self, widget, event): + #self.button.set_sensitive(False) + self.was_playing = self.ui.ca.gplay.is_playing() + if self.was_playing: + self.ui.ca.gplay.pause() - # don't timeout-update position during seek - if self.UPDATE_SCALE_ID != 0: - gobject.source_remove(self.UPDATE_SCALE_ID) - self.UPDATE_SCALE_ID = 0 + # don't timeout-update position during seek + if self.UPDATE_SCALE_ID != 0: + gobject.source_remove(self.UPDATE_SCALE_ID) + self.UPDATE_SCALE_ID = 0 - # make sure we get changed notifies - if self.CHANGED_ID == 0: - self.CHANGED_ID = self.hscale.connect('value-changed', self._scaleValueChangedCb) + # make sure we get changed notifies + if self.CHANGED_ID == 0: + self.CHANGED_ID = self.hscale.connect('value-changed', self._scaleValueChangedCb) - def _scaleButtonReleaseCb(self, widget, event): - # see seek.cstop_seek - widget.disconnect(self.CHANGED_ID) - self.CHANGED_ID = 0 + def _scaleButtonReleaseCb(self, widget, event): + # see seek.cstop_seek + widget.disconnect(self.CHANGED_ID) + self.CHANGED_ID = 0 - #self.button.set_sensitive(True) - if self.was_playing: - self.ui.ca.gplay.play() + #self.button.set_sensitive(True) + if self.was_playing: + self.ui.ca.gplay.play() - if self.UPDATE_SCALE_ID != 0: - pass - #print('Had a previous update timeout id') - else: - self.UPDATE_SCALE_ID = gobject.timeout_add(self.UPDATE_INTERVAL, self._updateScaleCb) + if self.UPDATE_SCALE_ID != 0: + pass + #print('Had a previous update timeout id') + else: + self.UPDATE_SCALE_ID = gobject.timeout_add(self.UPDATE_INTERVAL, self._updateScaleCb) - def _scaleValueChangedCb(self, scale): - real = long(scale.get_value() * self.p_duration / 100) # in ns - self.ui.ca.gplay.seek(real) - # allow for a preroll - self.ui.ca.gplay.get_state(timeout=50*gst.MSECOND) # 50 ms + def _scaleValueChangedCb(self, scale): + real = long(scale.get_value() * self.p_duration / 100) # in ns + self.ui.ca.gplay.seek(real) + # allow for a preroll + self.ui.ca.gplay.get_state(timeout=50*gst.MSECOND) # 50 ms - def _updateScaleCb(self): - self.p_position, self.p_duration = self.ui.ca.gplay.queryPosition() - if self.p_position != gst.CLOCK_TIME_NONE: - value = self.p_position * 100.0 / self.p_duration - if (value > 99): - value = 99 - elif (value < 0): - value = 0 + def _updateScaleCb(self): + self.p_position, self.p_duration = self.ui.ca.gplay.queryPosition() + if self.p_position != gst.CLOCK_TIME_NONE: + value = self.p_position * 100.0 / self.p_duration + if (value > 99): + value = 99 + elif (value < 0): + value = 0 - self.adjustment.set_value(value) + self.adjustment.set_value(value) - if self.ui.ca.gplay.is_playing() and (self.p_position == self.p_duration): - self.ui.ca.gplay.pause() - self.set_button_play() + if self.ui.ca.gplay.is_playing() and (self.p_position == self.p_duration): + self.ui.ca.gplay.pause() + self.set_button_play() - return True + return True class MaxButton(P5Button): - def __init__(self, ui): - P5Button.__init__(self) - self.ui = ui - - self.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - self.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) - - xs = [] - ys = [] - xs.append(0) - ys.append(0) - xs.append(self.ui.maxw) - ys.append(0) - xs.append(self.ui.maxw) - ys.append(self.ui.maxh) - xs.append(0) - ys.append(self.ui.maxh) - poly = Polygon( xs, ys ) - butt = Button( poly, 0, 0) - butt.addActionListener( self ) - self.maxS = "max" - butt.setActionCommand( self.maxS ) - self._butts.append( butt ) - - - def draw(self, ctx, w, h): - if (self.ui.FULLSCREEN): - Constants.maxEnlargeSvg.render_cairo( ctx ) - else: - Constants.maxReduceSvg.render_cairo( ctx ) - - - def fireButton(self, actionCommand): - if (actionCommand == self.maxS): - self.ui.doFullscreen() + def __init__(self, ui): + P5Button.__init__(self) + self.ui = ui + + self.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + self.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) + + xs = [] + ys = [] + xs.append(0) + ys.append(0) + xs.append(self.ui.maxw) + ys.append(0) + xs.append(self.ui.maxw) + ys.append(self.ui.maxh) + xs.append(0) + ys.append(self.ui.maxh) + poly = Polygon( xs, ys ) + butt = Button( poly, 0, 0) + butt.addActionListener( self ) + self.maxS = "max" + butt.setActionCommand( self.maxS ) + self._butts.append( butt ) + + + def draw(self, ctx, w, h): + if (self.ui.FULLSCREEN): + Constants.maxEnlargeSvg.render_cairo( ctx ) + else: + Constants.maxReduceSvg.render_cairo( ctx ) + + + def fireButton(self, actionCommand): + if (actionCommand == self.maxS): + self.ui.doFullscreen() class InfButton(P5Button): - #todo: just a gtk.Image here, no? - def __init__(self, ui): - P5Button.__init__(self) - self.ui = ui + #todo: just a gtk.Image here, no? + def __init__(self, ui): + P5Button.__init__(self) + self.ui = ui - self.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - self.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) + self.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + self.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) - self.set_size_request( 75, 75 ) + self.set_size_request( 75, 75 ) - xs = [] - ys = [] - xs.append(0) - ys.append(0) - xs.append(75) - ys.append(0) - xs.append(75) - ys.append(75) - xs.append(0) - ys.append(75) - poly = Polygon( xs, ys ) - butt = Button( poly, 0, 0) - butt.addActionListener( self ) - self.infS = "inf" - butt.setActionCommand( self.infS ) - self._butts.append( butt ) + xs = [] + ys = [] + xs.append(0) + ys.append(0) + xs.append(75) + ys.append(0) + xs.append(75) + ys.append(75) + xs.append(0) + ys.append(75) + poly = Polygon( xs, ys ) + butt = Button( poly, 0, 0) + butt.addActionListener( self ) + self.infS = "inf" + butt.setActionCommand( self.infS ) + self._butts.append( butt ) - def draw(self, ctx, w, h): - self.background( ctx, Constants.colorBlack, w, h ) - Constants.infoOnSvg.render_cairo( ctx ) + def draw(self, ctx, w, h): + self.background( ctx, Constants.colorBlack, w, h ) + Constants.infoOnSvg.render_cairo( ctx ) - def fireButton(self, actionCommand): - if (actionCommand == self.infS): - self.ui.infoButtonClicked() + def fireButton(self, actionCommand): + if (actionCommand == self.infS): + self.ui.infoButtonClicked() class RecordButton(gtk.Button): - def __init__(self): - gtk.Button.__init__(self) - self.sens = True - self.img = None - #todo: check on record state, compare button imgs + def __init__(self): + gtk.Button.__init__(self) + self.sens = True + self.img = None + #todo: check on record state, compare button imgs - def set_sensitive(self, sen, full): - if (sen == self.sens): - return - self.sens = sen + def set_sensitive(self, sen, full): + if (sen == self.sens): + return + self.sens = sen - if (self.sens): - self.set_image( Constants.recImg ) - else: - if (full): - self.set_image( Constants.fullInsensitiveImg ) - else: - self.set_image( Constants.recInsensitiveImg ) + if (self.sens): + self.set_image( Constants.recImg ) + else: + if (full): + self.set_image( Constants.fullInsensitiveImg ) + else: + self.set_image( Constants.recInsensitiveImg ) - super(RecordButton, self).set_sensitive(self.sens) + super(RecordButton, self).set_sensitive(self.sens) - def doRecordButton(self): - if (not self.sens): - return - self.set_image( Constants.recRedImg ) + def doRecordButton(self): + if (not self.sens): + return + self.set_image( Constants.recRedImg ) - def doNormalButton(self): - if (not self.sens): - return - self.set_image( Constants.recImg ) + def doNormalButton(self): + if (not self.sens): + return + self.set_image( Constants.recImg ) class RecordWindow(gtk.Window): - def __init__(self, ui): - gtk.Window.__init__(self) - self.ui = ui - self.num = -1 + def __init__(self, ui): + gtk.Window.__init__(self) + self.ui = ui + self.num = -1 - self.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + self.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - self.shutterButton = RecordButton() - self.shutterButton.set_size_request(self.ui.recordButtWd, self.ui.recordButtWd) - self.shutterButton.set_relief(gtk.RELIEF_NONE) - self.shutterButton.set_image( Constants.recImg ) - self.shutterButton.connect("clicked", self.ui._shutterClickCb) + self.shutterButton = RecordButton() + self.shutterButton.set_size_request(self.ui.recordButtWd, self.ui.recordButtWd) + self.shutterButton.set_relief(gtk.RELIEF_NONE) + self.shutterButton.set_image( Constants.recImg ) + self.shutterButton.connect("clicked", self.ui._shutterClickCb) - shutterBox = gtk.EventBox() - shutterBox.add( self.shutterButton ) - shutterBox.set_size_request( self.ui.controlBarHt, self.ui.controlBarHt ) + shutterBox = gtk.EventBox() + shutterBox.add( self.shutterButton ) + shutterBox.set_size_request( self.ui.controlBarHt, self.ui.controlBarHt ) - shutterBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - self.shutterButton.modify_bg( gtk.STATE_ACTIVE, Constants.colorBlack.gColor ) + shutterBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + self.shutterButton.modify_bg( gtk.STATE_ACTIVE, Constants.colorBlack.gColor ) - hbox = gtk.HBox() - self.add( hbox ) - leftPanel = gtk.VBox() - self.leftEvent = gtk.EventBox() - self.leftEvent.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - self.leftEvent.add( leftPanel ) - self.leftEvent.set_size_request(self.ui.vw/2-self.ui.controlBarHt, -1) - hbox.pack_start( self.leftEvent, expand=True ) + hbox = gtk.HBox() + self.add( hbox ) + leftPanel = gtk.VBox() + self.leftEvent = gtk.EventBox() + self.leftEvent.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + self.leftEvent.add( leftPanel ) + self.leftEvent.set_size_request(self.ui.vw/2-self.ui.controlBarHt, -1) + hbox.pack_start( self.leftEvent, expand=True ) - hbox.pack_start( shutterBox, expand=False ) + hbox.pack_start( shutterBox, expand=False ) - rightPanel = gtk.VBox() - self.rightEvent = gtk.EventBox() - self.rightEvent.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - self.rightEvent.add( rightPanel ) - hbox.pack_start( self.rightEvent, expand=True ) + rightPanel = gtk.VBox() + self.rightEvent = gtk.EventBox() + self.rightEvent.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + self.rightEvent.add( rightPanel ) + hbox.pack_start( self.rightEvent, expand=True ) - self.rightPanelLabel = gtk.Label() - rightPanel.pack_start( self.rightPanelLabel ) + self.rightPanelLabel = gtk.Label() + rightPanel.pack_start( self.rightPanelLabel ) - def updateCountdown(self, num): - if(num>0): - if (num != self.num): - ok = self.getCairoCountdown(num) - self.shutterButton.set_image(ok) - self.num = num - else: - self.num = -1 + def updateCountdown(self, num): + if(num>0): + if (num != self.num): + ok = self.getCairoCountdown(num) + self.shutterButton.set_image(ok) + self.num = num + else: + self.num = -1 - def getCairoCountdown(self, num): - return Constants.countdownImgs[int(num)] + def getCairoCountdown(self, num): + return Constants.countdownImgs[int(num)] - def minimize( self ): - self.leftEvent.set_size_request(-1, -1) - self.rightEvent.set_size_request(-1, -1) + def minimize( self ): + self.leftEvent.set_size_request(-1, -1) + self.rightEvent.set_size_request(-1, -1) - def maximize( self ): - w = self.ui.vw/2-self.ui.controlBarHt - self.rightEvent.set_size_request(w, -1) - self.leftEvent.set_size_request(w, -1) + def maximize( self ): + w = self.ui.vw/2-self.ui.controlBarHt + self.rightEvent.set_size_request(w, -1) + self.leftEvent.set_size_request(w, -1) - def displayDiscFullText( self, full ): - if (not full or self.ui.ca.m.MODE != Constants.MODE_PHOTO): - self.rightPanelLabel.set_text("") - self.minimize() - else: - fullMessage = Constants.istrYourDiskIsFull % {"1":Constants.istrJournal} - self.rightPanelLabel.set_text("" + fullMessage + "") - self.rightPanelLabel.set_use_markup( True ) - self.rightPanelLabel.set_alignment(1, 1) - self.maximize() + def displayDiscFullText( self, full ): + if (not full or self.ui.ca.m.MODE != Constants.MODE_PHOTO): + self.rightPanelLabel.set_text("") + self.minimize() + else: + fullMessage = Constants.istrYourDiskIsFull % {"1":Constants.istrJournal} + self.rightPanelLabel.set_text("" + fullMessage + "") + self.rightPanelLabel.set_use_markup( True ) + self.rightPanelLabel.set_alignment(1, 1) + self.maximize() class ProgressWindow(gtk.Window): - def __init__(self, ui): - gtk.Window.__init__(self) - self.ui = ui - self.update = "" - - self.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - self.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) - - eb = gtk.EventBox() - eb.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - eb.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) - self.add( eb ) - - vb = gtk.VBox() - vb.set_border_width(5) #todo: use variable - eb.add(vb) - - self.progBar = gtk.ProgressBar() - self.progBar.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) - self.progBar.modify_bg( gtk.STATE_ACTIVE, Constants.colorBlack.gColor ) - self.progBar.modify_bg( gtk.STATE_PRELIGHT, Constants.colorBlack.gColor ) - self.progBar.modify_bg( gtk.STATE_SELECTED, Constants.colorBlack.gColor ) - self.progBar.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) - vb.add( self.progBar ) - - hbox = gtk.HBox() - vb.add( hbox ) - self.infoLabel = gtk.Label() - self.infoLabel.set_alignment( 1, .5 ) - self.infoLabel.set_text( "SPACE") - self.infoLabel.set_use_markup( True ) - hbox.pack_start(self.infoLabel) - - - def updateProgress( self, amt, update, color='white' ): - self.progBar.set_fraction( amt ) - if (update != None and update != self.update): - self.update = update - self.infoLabel.set_text( ""+self.update+"") - self.infoLabel.set_use_markup( True ) - - if (self.update==""): - self.infoLabel.set_text( "SPACE") - self.infoLabel.set_use_markup( True ) - - if (amt >= 1): - self.progBar.set_fraction( 0 ) + def __init__(self, ui): + gtk.Window.__init__(self) + self.ui = ui + self.update = "" + + self.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + self.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) + + eb = gtk.EventBox() + eb.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + eb.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) + self.add( eb ) + + vb = gtk.VBox() + vb.set_border_width(5) #todo: use variable + eb.add(vb) + + self.progBar = gtk.ProgressBar() + self.progBar.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) + self.progBar.modify_bg( gtk.STATE_ACTIVE, Constants.colorBlack.gColor ) + self.progBar.modify_bg( gtk.STATE_PRELIGHT, Constants.colorBlack.gColor ) + self.progBar.modify_bg( gtk.STATE_SELECTED, Constants.colorBlack.gColor ) + self.progBar.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) + vb.add( self.progBar ) + + hbox = gtk.HBox() + vb.add( hbox ) + self.infoLabel = gtk.Label() + self.infoLabel.set_alignment( 1, .5 ) + self.infoLabel.set_text( "SPACE") + self.infoLabel.set_use_markup( True ) + hbox.pack_start(self.infoLabel) + + + def updateProgress( self, amt, update, color='white' ): + self.progBar.set_fraction( amt ) + if (update != None and update != self.update): + self.update = update + self.infoLabel.set_text( ""+self.update+"") + self.infoLabel.set_use_markup( True ) + + if (self.update==""): + self.infoLabel.set_text( "SPACE") + self.infoLabel.set_use_markup( True ) + + if (amt >= 1): + self.progBar.set_fraction( 0 ) class PhotoToolbar(gtk.Toolbar): - def __init__(self): - gtk.Toolbar.__init__(self) + def __init__(self): + gtk.Toolbar.__init__(self) - img = ToolButton('media-photo') - img.connect('clicked', self._shutterClickCb) - img.get_icon_widget().set_property( 'fill-color', Instance.colorFill.hex ) - img.get_icon_widget().set_property( 'stroke-color', Instance.colorStroke.hex ) - self.insert(img, -1) - img.set_sensitive(False) - img.show() + img = ToolButton('media-photo') + img.connect('clicked', self._shutterClickCb) + img.get_icon_widget().set_property( 'fill-color', Instance.colorFill.hex ) + img.get_icon_widget().set_property( 'stroke-color', Instance.colorStroke.hex ) + self.insert(img, -1) + img.set_sensitive(False) + img.show() - separator = gtk.SeparatorToolItem() - separator.set_draw(False) - separator.set_expand(True) - self.insert(separator, -1) - separator.show() + separator = gtk.SeparatorToolItem() + separator.set_draw(False) + separator.set_expand(True) + self.insert(separator, -1) + separator.show() - timerCbb = gtk.combo_box_new_text() - self.timerCb = ToolComboBox(combo=timerCbb, label_text=Constants.istrTimer) - for i in range (0, len(Constants.TIMERS)): - if (i == 0): - self.timerCb.combo.append_text( Constants.istrNow ) - else: - self.timerCb.combo.append_text( Constants.istrSeconds % {"1":(str(Constants.TIMERS[i]))} ) - self.timerCb.combo.set_active(0) - self.insert( self.timerCb, -1 ) + timerCbb = gtk.combo_box_new_text() + self.timerCb = ToolComboBox(combo=timerCbb, label_text=Constants.istrTimer) + for i in range (0, len(Constants.TIMERS)): + if (i == 0): + self.timerCb.combo.append_text( Constants.istrNow ) + else: + self.timerCb.combo.append_text( Constants.istrSeconds % {"1":(str(Constants.TIMERS[i]))} ) + self.timerCb.combo.set_active(0) + self.insert( self.timerCb, -1 ) - def _shutterClickCb(self, button): - pass - #self.ui.doShutter() + def _shutterClickCb(self, button): + pass + #self.ui.doShutter() - def getTimer(self): - return Constants.TIMERS[self.timerCb.combo.get_active()] + def getTimer(self): + return Constants.TIMERS[self.timerCb.combo.get_active()] class VideoToolbar(gtk.Toolbar): - def __init__(self): - gtk.Toolbar.__init__(self) + def __init__(self): + gtk.Toolbar.__init__(self) - img = ToolButton('media-video') - img.connect('clicked', self._shutterClickCb) - img.get_icon_widget().set_property( 'fill-color', Instance.colorFill.hex ) - img.get_icon_widget().set_property( 'stroke-color', Instance.colorStroke.hex ) - self.insert(img, -1) - img.set_sensitive(False) - img.show() + img = ToolButton('media-video') + img.connect('clicked', self._shutterClickCb) + img.get_icon_widget().set_property( 'fill-color', Instance.colorFill.hex ) + img.get_icon_widget().set_property( 'stroke-color', Instance.colorStroke.hex ) + self.insert(img, -1) + img.set_sensitive(False) + img.show() - separator = gtk.SeparatorToolItem() - separator.set_draw(False) - separator.set_expand(True) - self.insert(separator, -1) - separator.show() + separator = gtk.SeparatorToolItem() + separator.set_draw(False) + separator.set_expand(True) + self.insert(separator, -1) + separator.show() - timerCbb = gtk.combo_box_new_text() - self.timerCb = ToolComboBox(combo=timerCbb, label_text=Constants.istrTimer) - for i in range (0, len(Constants.TIMERS)): - if (i == 0): - self.timerCb.combo.append_text( Constants.istrNow ) - else: - self.timerCb.combo.append_text( Constants.istrSeconds % {"1":(str(Constants.TIMERS[i]))} ) - self.timerCb.combo.set_active(0) - self.insert( self.timerCb, -1 ) + timerCbb = gtk.combo_box_new_text() + self.timerCb = ToolComboBox(combo=timerCbb, label_text=Constants.istrTimer) + for i in range (0, len(Constants.TIMERS)): + if (i == 0): + self.timerCb.combo.append_text( Constants.istrNow ) + else: + self.timerCb.combo.append_text( Constants.istrSeconds % {"1":(str(Constants.TIMERS[i]))} ) + self.timerCb.combo.set_active(0) + self.insert( self.timerCb, -1 ) - separator2 = gtk.SeparatorToolItem() - separator2.set_draw(False) - separator2.set_expand(False) - separator2.set_size_request(UI.dim_INSET, -1) - self.insert( separator2, -1 ) + separator2 = gtk.SeparatorToolItem() + separator2.set_draw(False) + separator2.set_expand(False) + separator2.set_size_request(UI.dim_INSET, -1) + self.insert( separator2, -1 ) - durCbb = gtk.combo_box_new_text() - self.durCb = ToolComboBox(combo=durCbb, label_text=Constants.istrDuration) - for i in range (0, len(Constants.DURATIONS)): - self.durCb.combo.append_text( Constants.istrMinutes % {"1":(str(Constants.DURATIONS[i]))} ) - self.durCb.combo.set_active(0) - self.insert(self.durCb, -1 ) + durCbb = gtk.combo_box_new_text() + self.durCb = ToolComboBox(combo=durCbb, label_text=Constants.istrDuration) + for i in range (0, len(Constants.DURATIONS)): + self.durCb.combo.append_text( Constants.istrMinutes % {"1":(str(Constants.DURATIONS[i]))} ) + self.durCb.combo.set_active(0) + self.insert(self.durCb, -1 ) - def _shutterClickCb(self, button): - pass - #self.ui.doShutter() + def _shutterClickCb(self, button): + pass + #self.ui.doShutter() - def getTimer(self): - return Constants.TIMERS[self.timerCb.combo.get_active()] + def getTimer(self): + return Constants.TIMERS[self.timerCb.combo.get_active()] - def getDuration(self): - return 60 * Constants.DURATIONS[self.durCb.combo.get_active()] + def getDuration(self): + return 60 * Constants.DURATIONS[self.durCb.combo.get_active()] class AudioToolbar(gtk.Toolbar): - def __init__(self): - gtk.Toolbar.__init__(self) - - img = ToolButton('media-audio') - img.connect('clicked', self._shutterClickCb) - img.get_icon_widget().set_property( 'fill-color', Instance.colorFill.hex ) - img.get_icon_widget().set_property( 'stroke-color', Instance.colorStroke.hex ) - self.insert(img, -1) - img.set_sensitive(False) - img.show() - - separator = gtk.SeparatorToolItem() - separator.set_draw(False) - separator.set_expand(True) - self.insert(separator, -1) - separator.show() - - timerCbb = gtk.combo_box_new_text() - self.timerCb = ToolComboBox(combo=timerCbb, label_text=Constants.istrTimer) - for i in range (0, len(Constants.TIMERS)): - if (i == 0): - self.timerCb.combo.append_text( Constants.istrNow ) - else: - self.timerCb.combo.append_text( Constants.istrSeconds % {"1":(str(Constants.TIMERS[i]))} ) - self.timerCb.combo.set_active(0) - self.insert( self.timerCb, -1 ) - - separator2 = gtk.SeparatorToolItem() - separator2.set_draw(False) - separator2.set_expand(False) - separator2.set_size_request(UI.dim_INSET, -1) - self.insert( separator2, -1 ) - - durCbb = gtk.combo_box_new_text() - self.durCb = ToolComboBox(combo=durCbb, label_text=Constants.istrDuration) - for i in range (0, len(Constants.DURATIONS)): - self.durCb.combo.append_text( Constants.istrMinutes % {"1":(str(Constants.DURATIONS[i]))} ) - self.durCb.combo.set_active(0) - self.insert(self.durCb, -1 ) - - - def _shutterClickCb(self, button): - pass - #self.ui.doShutter() - - - def getTimer(self): - return Constants.TIMERS[self.timerCb.combo.get_active()] - - - def getDuration(self): - return 60 * Constants.DURATIONS[self.durCb.combo.get_active()] + def __init__(self): + gtk.Toolbar.__init__(self) + + img = ToolButton('media-audio') + img.connect('clicked', self._shutterClickCb) + img.get_icon_widget().set_property( 'fill-color', Instance.colorFill.hex ) + img.get_icon_widget().set_property( 'stroke-color', Instance.colorStroke.hex ) + self.insert(img, -1) + img.set_sensitive(False) + img.show() + + separator = gtk.SeparatorToolItem() + separator.set_draw(False) + separator.set_expand(True) + self.insert(separator, -1) + separator.show() + + timerCbb = gtk.combo_box_new_text() + self.timerCb = ToolComboBox(combo=timerCbb, label_text=Constants.istrTimer) + for i in range (0, len(Constants.TIMERS)): + if (i == 0): + self.timerCb.combo.append_text( Constants.istrNow ) + else: + self.timerCb.combo.append_text( Constants.istrSeconds % {"1":(str(Constants.TIMERS[i]))} ) + self.timerCb.combo.set_active(0) + self.insert( self.timerCb, -1 ) + + separator2 = gtk.SeparatorToolItem() + separator2.set_draw(False) + separator2.set_expand(False) + separator2.set_size_request(UI.dim_INSET, -1) + self.insert( separator2, -1 ) + + durCbb = gtk.combo_box_new_text() + self.durCb = ToolComboBox(combo=durCbb, label_text=Constants.istrDuration) + for i in range (0, len(Constants.DURATIONS)): + self.durCb.combo.append_text( Constants.istrMinutes % {"1":(str(Constants.DURATIONS[i]))} ) + self.durCb.combo.set_active(0) + self.insert(self.durCb, -1 ) + + + def _shutterClickCb(self, button): + pass + #self.ui.doShutter() + + + def getTimer(self): + return Constants.TIMERS[self.timerCb.combo.get_active()] + + + def getDuration(self): + return 60 * Constants.DURATIONS[self.durCb.combo.get_active()] diff --git a/utils.py b/utils.py index d91633c..36159ba 100644 --- a/utils.py +++ b/utils.py @@ -14,105 +14,105 @@ from sugar import util import camerac def getStringFromPixbuf(pixbuf): - data = [""] - pixbuf.save_to_callback(_saveDataToBufferCb, "png", {}, data) - return base64.b64encode(str(data[0])) + data = [""] + pixbuf.save_to_callback(_saveDataToBufferCb, "png", {}, data) + return base64.b64encode(str(data[0])) def _saveDataToBufferCb(buf, data): - data[0] += buf - return True + data[0] += buf + return True def getPixbufFromString(str): - pbl = gtk.gdk.PixbufLoader() - data = base64.b64decode( str ) - pbl.write(data) - pbl.close() - return pbl.get_pixbuf() + pbl = gtk.gdk.PixbufLoader() + data = base64.b64decode( str ) + pbl.write(data) + pbl.close() + return pbl.get_pixbuf() def loadSvg( data, stroke, fill ): - if ((stroke == None) or (fill == None)): - return rsvg.Handle( data=data ) + if ((stroke == None) or (fill == None)): + return rsvg.Handle( data=data ) - entity = '' % fill - data = re.sub('', entity, data) + entity = '' % fill + data = re.sub('', entity, data) - entity = '' % stroke - data = re.sub('', entity, data) + entity = '' % stroke + data = re.sub('', entity, data) - return rsvg.Handle( data=data ) + return rsvg.Handle( data=data ) def getUniqueFilepath( path, i ): - pathOb = os.path.abspath( path ) - newPath = os.path.join( os.path.dirname(pathOb), str( str(i) + os.path.basename(pathOb) ) ) - if (os.path.exists(newPath)): - i = i + 1 - return getUniqueFilepath( pathOb, i ) - else: - return os.path.abspath( newPath ) + pathOb = os.path.abspath( path ) + newPath = os.path.join( os.path.dirname(pathOb), str( str(i) + os.path.basename(pathOb) ) ) + if (os.path.exists(newPath)): + i = i + 1 + return getUniqueFilepath( pathOb, i ) + else: + return os.path.abspath( newPath ) def md5File( filepath ): - md = md5() - f = file( filepath, 'rb' ) - md.update( f.read() ) - digest = md.hexdigest() - hash = util.printable_hash(digest) - return hash + md = md5() + f = file( filepath, 'rb' ) + md.update( f.read() ) + digest = md.hexdigest() + hash = util.printable_hash(digest) + return hash def generateThumbnail( pixbuf, scale, thumbw, thumbh ): - #need to generate thumbnail version here - thumbImg = cairo.ImageSurface(cairo.FORMAT_ARGB32, thumbw, thumbh) - tctx = cairo.Context(thumbImg) - img = camerac.cairo_surface_from_gdk_pixbuf(pixbuf) - tctx.scale(scale, scale) - tctx.set_source_surface(img, 0, 0) - tctx.paint() - gc.collect() - return thumbImg + #need to generate thumbnail version here + thumbImg = cairo.ImageSurface(cairo.FORMAT_ARGB32, thumbw, thumbh) + tctx = cairo.Context(thumbImg) + img = camerac.cairo_surface_from_gdk_pixbuf(pixbuf) + tctx.scale(scale, scale) + tctx.set_source_surface(img, 0, 0) + tctx.paint() + gc.collect() + return thumbImg def scaleSvgToDim( handle, dim ): - #todo... - scale = 1.0 + #todo... + scale = 1.0 - svgDim = handle.get_dimension_data() - if (svgDim[0] > dim[0]): - pass + svgDim = handle.get_dimension_data() + if (svgDim[0] > dim[0]): + pass - return scale + return scale def getDateString( when ): - return strftime( "%a, %b %d, %I:%M:%S %p", time.localtime(when) ) + return strftime( "%a, %b %d, %I:%M:%S %p", time.localtime(when) ) def grayScalePixBuf2( pb, copy ): - arr = pb.get_pixels_array() - if (copy): - arr = arr.copy() - for row in arr: - for pxl in row: - y = 0.3*pxl[0][0]+0.59*pxl[1][0]+0.11*pxl[2][0] - pxl[0][0] = y - pxl[1][0] = y - pxl[2][0] = y - return gtk.gdk.pixbuf_new_from_array(arr, pb.get_colorspace(), pb.get_bits_per_sample()) + arr = pb.get_pixels_array() + if (copy): + arr = arr.copy() + for row in arr: + for pxl in row: + y = 0.3*pxl[0][0]+0.59*pxl[1][0]+0.11*pxl[2][0] + pxl[0][0] = y + pxl[1][0] = y + pxl[2][0] = y + return gtk.gdk.pixbuf_new_from_array(arr, pb.get_colorspace(), pb.get_bits_per_sample()) def grayScalePixBuf( pb, copy ): - pb2 = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, pb.get_width(), pb.get_height()) - pb.saturate_and_pixelate(pb2, 0, 0) - return pb2 + pb2 = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, pb.get_width(), pb.get_height()) + pb.saturate_and_pixelate(pb2, 0, 0) + return pb2 def getFreespaceKb( ): - stat = os.statvfs("/home") - freebytes = stat[statvfs.F_BSIZE] * stat[statvfs.F_BAVAIL] - freekb = freebytes / 1024 - return freekb + stat = os.statvfs("/home") + freebytes = stat[statvfs.F_BSIZE] * stat[statvfs.F_BAVAIL] + freekb = freebytes / 1024 + return freekb -- cgit v0.9.1