#!/usr/bin/env python # Copyright (c) 2008, Media Modifications Ltd. #Permission is hereby granted, free of charge, to any person obtaining a copy #of this software and associated documentation files (the "Software"), to deal #in the Software without restriction, including without limitation the rights #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #copies of the Software, and to permit persons to whom the Software is #furnished to do so, subject to the following conditions: #The above copyright notice and this permission notice shall be included in #all copies or substantial portions of the Software. #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN #THE SOFTWARE. import gtk import gobject import os import threading from threading import * import time import hippo import shutil import urllib import random from sugar.graphics.toggletoolbutton import ToggleToolButton from sugar.graphics.toolbutton import ToolButton from sugar.activity import activity from sugar.graphics import style from filepicker import FilePicker from constants import Constants from webviewer import WebViewer from server import Server from logic import ServerLogic from result import ServerResult from instance import Instance from constants import Constants from model import Model from tray import HTray from photocanvas import PhotoCanvas from p5 import P5 from gplay import Gplay from gplay import PlayVideoWindow import serialize import utils from button import SavedButton from savedmap import SavedMap import _camera # sharing import telepathy from dbus.service import method, signal from dbus.gobject_service import ExportedGObject from sugar.graphics.alert import NotifyAlert from sugar.presence import presenceservice from sugar.presence.tubeconn import TubeConnection SERVICE = "org.laptop.map" IFACE = SERVICE PATH = "/org/laptop/map" imgWidth = 180 imgHeight = 135 webWidth = imgWidth*4 webHeight = imgHeight*3 class Map(activity.Activity): #temp values until they get assigned cometPort = 8889 ajaxPort = 8890 initLat = '48.224' initLng = '-11.07' initZoom = '3' initType = 'terr' popW = 320 popH = 240 popB = 10 def __init__(self, handle): activity.Activity.__init__(self, handle) Instance(self) Constants(self) self.modify_bg( gtk.STATE_NORMAL, Constants.colorBg.gColor ) gobject.idle_add(self._initme, None) def _initme( self, userdata=None ): self.basePath = activity.get_bundle_path() self.htmlPath = os.path.join(self.basePath, "html") self.libPath = "/home/olpc/Library/MapPack/" self.m = Model(self) self.cond = Condition() self.SAVING_SEARCH = False self.shownSave = None self.shownRecd = None #these get updated whenever we hear back from the server self.NOW_MAP_CENTER_LAT = self.__class__.initLat self.NOW_MAP_CENTER_LNG = self.__class__.initLng self.NOW_MAP_ZOOM = self.__class__.initZoom self.NOW_MAP_TAGS = "" #calc unique ports h = hash(Instance.instanceId) self.__class__.cometPort = 1024 + (h%32255) * 2 self.__class__.ajaxPort = self.__class__.cometPort + 1 #ui self.windowStack = [] self.toolbox = activity.ActivityToolbox(self) self.set_toolbox(self.toolbox) self.searchToolbar = SearchToolbar(self) self.searchToolbar.connect("address-update", self._addressUpdateCb) self.searchToolbar.connect("zoom-in", self._zoomInCb) self.searchToolbar.connect("zoom-out", self._zoomOutCb) self.searchToolbar.connect("save-search", self._saveSearchCb) self.searchToolbar.connect("search-update", self._searchUpdateCb) self.searchToolbar.set_sensitive(False) self.toolbox.add_toolbar( Constants.istrSearch, self.searchToolbar ) self.addToolbar = AddToolbar(self) self.toolbox.add_toolbar( Constants.istrAnnotate, self.addToolbar ) self.addToolbar.connect("add-media", self._addMediaCb) self.addToolbar.connect("add-kml", self._addKMLCb) self.addToolbar.connect("add-info", self._addInfoCb) self.addToolbar.connect("delete-media", self._deleteMediaCb) self.addToolbar.connect("measure", self._measureCb) self.addToolbar.connect("olpcmap", self._olpcmapCb) self.addToolbar.connect("panoramio", self._panoramioCb) self.addToolbar.connect("local-wiki", self._localwikiCb) self.addToolbar.connect("wikimapia",self._wikimapiaCb) self.addToolbar.set_sensitive(False) self.firstSearch = True self.toolbox.set_current_toolbar(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.colorBg.get_int(), background_color=Constants.colorBg.get_int(), box_height=style.TOOLBOX_SEPARATOR_HEIGHT, border_bottom=style.LINE_WIDTH) separator.set_root(box) self.toolbox.separator = separator self.toolbox._notebook.set_property("can-focus", False) self.toolbox.show() #add components vbox = gtk.VBox() vboxNorth = gtk.VBox() vbox.pack_start(vboxNorth) buttNorthFiller = gtk.EventBox() buttNorthFiller.modify_bg( gtk.STATE_NORMAL, Constants.colorBg.gColor ) buttNorthFiller.modify_bg( gtk.STATE_ACTIVE, Constants.colorBg.gColor ) buttNorthFiller.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBg.gColor ) vboxNorth.pack_start(buttNorthFiller, expand=True) buttNorthEventBox = gtk.EventBox() buttNorthEventBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBg.gColor ) buttNorthEventBox.modify_bg( gtk.STATE_ACTIVE, Constants.colorBg.gColor ) buttNorthEventBox.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBg.gColor ) self.buttNorth = gtk.Button() self.buttNorth.set_property("can-focus", False) self.buttNorth.modify_bg( gtk.STATE_NORMAL, Constants.colorBg.gColor ) self.buttNorth.modify_bg( gtk.STATE_ACTIVE, Constants.colorBg.gColor ) self.buttNorth.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBg.gColor ) buttNorthEventBox.add(self.buttNorth) self.buttNorth.set_image( Constants.northImgClr ) self.buttNorth.connect('clicked', self._buttNorthCb) vboxNorth.pack_start(buttNorthEventBox, expand=False) self.buttNorth.set_relief(gtk.RELIEF_NONE) hbox = gtk.HBox() self.htmlScale = 1.43 hbox.set_size_request(-1, int(webHeight*self.htmlScale)) vbox.pack_start(hbox, expand=False) vboxSouth = gtk.VBox() vbox.pack_start(vboxSouth) buttSouthEventBox = gtk.EventBox() buttSouthEventBox.modify_bg( gtk.STATE_ACTIVE, Constants.colorBg.gColor ) buttSouthEventBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBg.gColor ) buttSouthEventBox.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBg.gColor ) vboxSouth.pack_start(buttSouthEventBox, expand=False) self.buttSouth = gtk.Button() self.buttSouth.set_property("can-focus", False) self.buttSouth.modify_bg( gtk.STATE_NORMAL, Constants.colorBg.gColor ) self.buttSouth.modify_bg( gtk.STATE_ACTIVE, Constants.colorBg.gColor ) self.buttSouth.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBg.gColor ) buttSouthEventBox.add(self.buttSouth) self.buttSouth.set_image(Constants.southImgClr) self.buttSouth.connect('clicked', self._buttSouthCb) buttSouthFiller = gtk.EventBox() buttSouthFiller.modify_bg( gtk.STATE_NORMAL, Constants.colorBg.gColor ) buttSouthFiller.modify_bg( gtk.STATE_ACTIVE, Constants.colorBg.gColor ) buttSouthFiller.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBg.gColor ) vboxSouth.pack_start(buttSouthFiller, expand=True) self.buttSouth.set_relief(gtk.RELIEF_NONE) self.tray = HTray() self.tray.set_size_request(-1, 130) self.tray.connect("enter-notify-event", self._trayMouseCb) self.tray.viewport.connect("enter-notify-event", self._trayMouseCb) self.tray.viewport.traybar.connect("enter-notify-event", self._trayMouseCb) self.tray.scroll_left.connect("enter-notify-event", self._trayMouseCb) self.tray.scroll_right.connect("enter-notify-event", self._trayMouseCb) self.tray.scroll_left_event.connect("enter-notify-event", self._trayMouseCb) self.tray.scroll_right_event.connect("enter-notify-event", self._trayMouseCb) fakeTray = gtk.VBox() fakeTray.set_size_request(-1, 130) fakeTray.modify_bg( gtk.STATE_NORMAL, Constants.colorBg.gColor ) fakeTrayEvent = gtk.EventBox() fakeTrayEvent.modify_bg( gtk.STATE_NORMAL, Constants.colorBg.gColor ) fakeTrayEvent.set_size_request(-1, 130) fakeTrayEvent.add( fakeTray ) self.trayBox = gtk.Notebook() self.trayBox.set_size_request(-1, 130) self.trayBox.set_show_tabs(False) vbox.pack_start(self.trayBox, expand=False) self.trayBox.append_page(self.tray) self.trayBox.append_page(fakeTrayEvent) self.realTrayIndex = self.trayBox.page_num(self.tray) self.fakeTrayIndex = self.trayBox.page_num(fakeTrayEvent) self.trayBox.set_current_page(self.realTrayIndex) fakeTrayEvent.add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK) fakeTrayEvent.connect_after("visibility-notify-event", self._fakeTrayVisibleNotifyCb) hboxWest = gtk.HBox() hbox.pack_start(hboxWest) buttWestFiller = gtk.EventBox() buttWestFiller.modify_bg( gtk.STATE_ACTIVE, Constants.colorBg.gColor ) buttWestFiller.modify_bg( gtk.STATE_NORMAL, Constants.colorBg.gColor ) buttWestFiller.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBg.gColor ) hboxWest.pack_start(buttWestFiller, expand=True) buttWestEventBox = gtk.EventBox() hboxWest.pack_start(buttWestEventBox, expand=False) buttWestEventBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBg.gColor ) buttWestEventBox.modify_bg( gtk.STATE_ACTIVE, Constants.colorBg.gColor ) buttWestEventBox.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBg.gColor ) self.buttWest = gtk.Button() self.buttWest.set_property("can-focus", False) buttWestEventBox.add(self.buttWest) self.buttWest.modify_bg( gtk.STATE_NORMAL, Constants.colorBg.gColor ) self.buttWest.modify_bg( gtk.STATE_ACTIVE, Constants.colorBg.gColor ) self.buttWest.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBg.gColor ) self.buttWest.set_image( Constants.westImgClr ) self.buttWest.connect('clicked', self._buttWestCb) self.buttWest.set_relief(gtk.RELIEF_NONE) self.browseBox = gtk.VBox() self.browser = WebViewer() self.browser.set_size_request(int(webWidth*self.htmlScale), int(webHeight*self.htmlScale)) self.browseBox.pack_start(self.browser) self.browseBox.set_size_request(int(webWidth*self.htmlScale), int(webHeight*self.htmlScale)) hbox.pack_start(self.browseBox, expand=False) hboxEast = gtk.HBox() hbox.pack_start(hboxEast) buttEastEventBox = gtk.EventBox() hboxEast.pack_start(buttEastEventBox, expand=False) buttEastEventBox.modify_bg( gtk.STATE_ACTIVE, Constants.colorBg.gColor ) buttEastEventBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBg.gColor ) buttEastEventBox.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBg.gColor ) self.buttEast = gtk.Button() self.buttEast.set_property("can-focus", False) self.buttEast.modify_bg( gtk.STATE_ACTIVE, Constants.colorBg.gColor ) self.buttEast.modify_bg( gtk.STATE_NORMAL, Constants.colorBg.gColor ) self.buttEast.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBg.gColor ) buttEastEventBox.add(self.buttEast) self.buttEast.set_image(Constants.eastImgClr) buttEastFiller = gtk.EventBox() hboxEast.pack_start(buttEastFiller, expand=True) buttEastFiller.modify_bg( gtk.STATE_ACTIVE, Constants.colorBg.gColor ) buttEastFiller.modify_bg( gtk.STATE_NORMAL, Constants.colorBg.gColor ) buttEastFiller.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBg.gColor ) self.buttEast.connect('clicked', self._buttEastCb) self.buttEast.set_relief(gtk.RELIEF_NONE) #important to call these in this order to ensure they show up self.set_canvas(vbox) self.browser.show() #fire up the web engine, spiderman! self.cometLogic = ServerLogic(self) self.ajaxServer = ServerThread(self.__class__.ajaxPort, self.cometLogic) self.ajaxServer.start() self.cometServer = ServerThread(self.__class__.cometPort, self.cometLogic) self.cometServer.start() self.browser.load_uri("file://" + self.htmlPath + "/staticmap2.html?ajaxPort=" + str(self.__class__.ajaxPort) + "&cometPort=" + str(self.__class__.cometPort) + "&xo=true" + "&lat=" + str(self.NOW_MAP_CENTER_LAT) + "&lng=" + str(self.NOW_MAP_CENTER_LNG) + "&zoom=" + str(self.NOW_MAP_ZOOM) + "&type=" + self.__class__.initType + "&" + Constants.istrLang) self.loaded = True self.loadingWindow = gtk.Window() self.addToWindowStack( self.loadingWindow, self ) self.loadingWindow.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) loadingVBox = gtk.VBox() self.loadingWindow.add(loadingVBox) loadingTopEventBox = gtk.EventBox() loadingTopEventBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) loadingVBox.pack_start(loadingTopEventBox, expand=True) self.loadingCanvas = PhotoCanvas() self.loadingCanvas.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.loadingCanvas.set_size_request( 1200, 600 ) loadingVBox.pack_start(self.loadingCanvas, expand=True) loadingInfo = gtk.Label() loadingInfo.set_alignment( .5, 0 ) loadingInfo.set_text( "" + Constants.istrConnecting + "") loadingInfo.set_use_markup( True ) loadingVBox.pack_start(loadingInfo, expand=False) loadingBotEventBox = gtk.EventBox() loadingBotEventBox.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) loadingVBox.pack_start(loadingBotEventBox, expand=True) self.loadingWindow.resize( gtk.gdk.screen_width(), gtk.gdk.screen_height()-(self.toolbox.allocation.height) ) self.moveWinOffscreen(self.loadingWindow) self.popWindow = gtk.Window() self.addToWindowStack( self.popWindow, self.loadingWindow ) self.popWindow.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.popWindow.resize( self.popW+(2*self.popB), self.popH+(2*self.popB) ) self.popUpBg = PopUpP5() self.popWindow.add( self.popUpBg ) self.moveWinOffscreen(self.popWindow) self.popWindow.show_all() self.mediaWindow = gtk.Window() self.addToWindowStack(self.mediaWindow, self.popWindow) self.moveWinOffscreen(self.mediaWindow) self.mediaWindow.show_all() self.infoWindow = gtk.Window() self._fillInInfoWindow() self.addToWindowStack(self.infoWindow, self.mediaWindow) self.moveWinOffscreen(self.infoWindow) self.infoWindow.show_all() self.selectWindow = gtk.Window() self.selectWindow.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) self.addToWindowStack(self.selectWindow, self.infoWindow) self.moveWinOffscreen(self.selectWindow) self.selectWindow.show_all() self.photoCanvas = PhotoCanvas() self.gplayWin = PlayVideoWindow( Constants.colorBlack.gColor ) self.gplay = Gplay() self.gplay.window = self.gplayWin self.connect("destroy", self.destroy) self.TOOLBOX_SIZE_ALLOCATE_ID = self.toolbox.connect_after("size-allocate", self._sizeAllocateCb) self.show_all() # break loading screen self.loaded = True self.enableNavigation() # add sharing self.maptube = None # Shared session self.initiating = False self.pservice = presenceservice.get_instance() owner = self.pservice.get_owner() self.owner = owner self.connect('shared', self._shared_cb) self.connect('joined', self._joined_cb) self.mediaType = "photo" return False def _received_cb(self, text): if(text.find(",") != -1): params = text.split(",") if(params[0] == "loc"): # other XO's map location has moved [lat,lng,zoom] self.preComet() self.cometLogic.handleReceivedMap(params[1],params[2],params[3]) self.postComet() elif(params[0] == "mar"): # other XO has added or modded info marker [lat,lng,infoText,iconImg] if(self.cometLogic.addKMLSet == 0): self.preComet() self.cometLogic.handleAddMarker(params[1], params[2], params[3], params[4]) self.m.setInfo(params[1],params[2],params[3],params[4]) #self.cometLogic.handleEndKML() if(self.cometLogic.addKMLSet == 0): self.postComet() elif(params[0] == "del"): # delete a marker (not working) self.preComet() self.cometLogic.handleDelete() self.postComet() elif(params[0] == "smap"): # add SavedMap [lat,lng,zoom,info] + not-new reminder self.addSavedMap(params[1],params[2],params[3],params[4],False) elif(params[0] == "line"): # add a line if(self.cometLogic.addKMLSet == 0): self.preComet() self.cometLogic.handleLine(params[1],params[2],params[3],params[4]) self.addLine(params[1],params[2],params[3],params[4],0) #self.cometLogic.handleEndKML() if(self.cometLogic.addKMLSet == 0): self.postComet() elif(params[0] == "endkml"): self.cometLogic.handleEndKML(0) self.postComet() elif(params[0] == "startkml"): self.preComet() self.cometLogic.startKML(0) def updateMapMetaData( self, ctrlat, ctrlng, zoom, showx, showy ): self.NOW_MAP_CENTER_LAT = ctrlat self.NOW_MAP_CENTER_LNG = ctrlng self.NOW_MAP_ZOOM = zoom # calculate where to put media overlay showx = int(showx) + 60 showy = int(showy) + 125 if(showx > 60) and (showx < 700) and (showy > 125) and (showy < 400): # open media overlay if(self.mediaType == "photo"): # mediaWindow contains a photo self.mediaWindow.show() self.smartMove(self.mediaWindow, self.htmlScale * showx, self.htmlScale * showy ) else: # popWindow contains a video player self.popWindow.show() self.smartMove(self.popWindow, self.htmlScale * showx, self.htmlScale * showy ) self.popWindow.hide() self.mediaWindow.show_all() else: self.mediaWindow.hide() self.popWindow.hide() if(self.maptube is not None): # update XO group location self.maptube.SendText("loc," + ctrlat + "," + ctrlng + "," + zoom) def _trayMouseCb( self, events, args): if (self.shownRecd != None): self.hideMedia() self.preComet() self.cometLogic.handleClear( ) self.postComet() return True #def loadMapV3( self ): # self.browser.load_uri("file://" + self.htmlPath + "/map3.html?ajaxPort=" + str(self.__class__.ajaxPort) + "&cometPort=" + str(self.__class__.cometPort) + "&xo=true" + "&lat=" + str(self.NOW_MAP_CENTER_LAT) + "&lng=" + str(self.NOW_MAP_CENTER_LNG) + "&zoom=" + str(self.NOW_MAP_ZOOM) + "&type=" + self.__class__.initType) def _tagsBufferEditedCb(self, widget): if (self.shownSave != None): txt = self.tagsBuffer.get_text( self.tagsBuffer.get_start_iter(), self.tagsBuffer.get_end_iter() ) if (txt != self.shownSave.notes): self.shownSave.notes = txt def _hideInfoCb( self, butt ): self.hideSearchResult() def hideSearchResult(self): #self.shownSave = None self.infoWindow.set_property("accept-focus", False) self.moveWinOffscreen( self.infoWindow ) self.enableNavigation() def showFileLoadBlocker( self, show ): if (show): self.smartMove( self.selectWindow, 0, 0 ) self.smartResize( self.selectWindow, gtk.gdk.screen_width(), gtk.gdk.screen_height() ) else: self.moveWinOffscreen( self.selectWindow ) def _sizeAllocateCb( self, widget, event ): self.toolbox.disconnect( self.TOOLBOX_SIZE_ALLOCATE_ID) self.smartMove(self.loadingWindow, 0, self.toolbox.allocation.height) self.loadingWindow.resize( gtk.gdk.screen_width(), gtk.gdk.screen_height()-(self.toolbox.allocation.height) ) return False def remoteServerActive(self, loaded): if (self.loaded): return else: self.loaded = loaded #add search results from load_file for i in range(0, len(self.m.savedMaps)): smap = self.m.savedMaps[i] self.addThumb( smap, False ) self.searchToolbar.set_sensitive(True) self.addToolbar.set_sensitive(True) browserW = self.browseBox.allocation.width browserH = self.browseBox.allocation.height self.smartResize( self.infoWindow, browserW, browserH ) self.moveWinOffscreen(self.loadingWindow) 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 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 smartMove( self, win, x, y ): winLoc = win.get_position() if ( (winLoc[0] != x) or (winLoc[1] != y) ): win.move( int(x), int(y) ) 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 preComet(self): self.cond.acquire() def postComet(self): self.cond.notifyAll() self.cond.release() time.sleep(.1) def read_file(self, file): serialize.fillMediaHash(file, self.m) def close( self ): self.hide() activity.Activity.close( self ) def write_file(self, file): dom = serialize.saveMediaHash(self.m) xmlFile = open( file, "w" ) dom.writexml(xmlFile) xmlFile.close() def _addressUpdateCb( self, otets, address ): if(address.find(',') != -1): if(len(address.split(',')) == 3): addSplit = address.split(',') if(addSplit[2] == 'm'): # add a marker at this lat,lng self.preComet() self.cometLogic.handleAddMarker(addSplit[0],addSplit[1],addSplit[0]+","+addSplit[1],"magenta") self.cometLogic.handleEndKML() self.postComet() self.addInfoMarker(addSplit[0],addSplit[1],addSplit[0]+","+addSplit[1],"magenta",True) return elif(os.path.exists(self.libPath)): mp_address = address.lower().replace(' ','').replace('-','') zoom="13" lat="-190" lng="-190" places = open(self.libPath + "Places.csv", 'r') for place in places: pData = place.split(',') pData[0] = pData[0].lower().replace(' ','').replace('-','') if(pData[0] == mp_address): lat = pData[1] lng = pData[2] if(pData[3] != "-1"): zoom = pData[3] self.preComet() self.cometLogic.handleReceivedMap(lat,lng,zoom) self.postComet() return self.preComet() self.cometLogic.handleAddressUpdate(address) self.postComet() def _searchUpdateCb( self, otets, tags ): self.NOW_MAP_TAGS = tags self.preComet() self.cometLogic.handleTagSearch(tags) self.postComet() def _buttEastCb( self, butt ): self.hideMedia() self.preComet() self.cometLogic.handleCompassUpdate("e") self.postComet() def _buttWestCb( self, butt ): self.hideMedia() self.preComet() self.cometLogic.handleCompassUpdate("w") self.postComet() def _buttNorthCb( self, butt ): self.hideMedia() self.preComet() self.cometLogic.handleCompassUpdate("n") self.postComet() def _buttSouthCb( self, butt ): self.hideMedia() self.preComet() self.cometLogic.handleCompassUpdate("s") self.postComet() def _zoomInCb( self, butt ): self.hideMedia() self.preComet() self.cometLogic.handleZoomUpdate("+") self.postComet() def _zoomOutCb( self, butt ): self.hideMedia() self.preComet() self.cometLogic.handleZoomUpdate("-") self.postComet() def _saveSearchCb( self, otets ): self._saveSearch() def _saveSearch( self ): #1st: cover up the tray when grabbing a screenshot #this will take a moment, so disable all buttons while we wait self.SAVING_SEARCH = True self.disableNavigation() self.savingSearchMediaLoc = self.mediaWindow.get_position() self.moveWinOffscreen( self.mediaWindow ) self.hideTray(True) def hideTray( self, hide ): if (hide): self.trayBox.set_current_page(self.fakeTrayIndex) else: self.trayBox.set_current_page(self.realTrayIndex) def _fakeTrayVisibleNotifyCb( self, widget, event ): #if (event.state == gtk.gdk.VISIBILITY_UNOBSCURED): #this is not used, bc a popup might be over it if (self.SAVING_SEARCH): gobject.idle_add( self._saveSearch2 ) def _saveSearch2( self ): # add SavedMap window = self.canvas.window width, height = window.get_size() screenshot = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, has_alpha=False, bits_per_sample=8, width=width, height=height) screenshot.get_from_drawable(window, window.get_colormap(), 0, 0, 0, 0, width, height) popW, popH = [self.popW+(2*self.popB), self.popH+(2*self.popB) ] popScreenshot = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, has_alpha=False, bits_per_sample=8, width=width, height=height) popScreenshot.get_from_drawable(self.popWindow.window, self.popWindow.window.get_colormap(), 0, 0, 0, 0, popW, popH) popLoc = self.popWindow.get_position() popLocX = popLoc[0] popLocY = popLoc[1] - self.toolbox.allocation.height popScreenshot.composite(screenshot, popLocX, popLocY, #move the actual mini-canvas (but not its internals (?)) popW, popH, #actual size of the mini-canvas popLocX, popLocY, #offx, y of the painting (irrespective of the mini-canvas) 1, 1, #scalex,y gtk.gdk.INTERP_BILINEAR, 255) screenshotPath = os.path.join(Instance.instancePath, "savedMap.jpg") screenshotPath = utils.getUniqueFilepath(screenshotPath, 0) screenshot.save( screenshotPath, "jpeg", {} ) smallHeight = 120 smallWidth = (width*smallHeight) / height screenshotSmall = screenshot.scale_simple(smallWidth, smallHeight, gtk.gdk.INTERP_NEAREST) screenshotSmallPath = os.path.join(Instance.instancePath, "savedMapThumb.jpg") screenshotSmallPath = utils.getUniqueFilepath(screenshotSmallPath, 0) screenshotSmall.save( screenshotSmallPath, "jpeg", {} ) sm = SavedMap( self.NOW_MAP_CENTER_LAT, self.NOW_MAP_CENTER_LNG, self.NOW_MAP_ZOOM, screenshotPath, screenshotSmallPath, "Describe the map", self.NOW_MAP_TAGS ) if (self.shownRecd != None): sm.addViewedRecd(self.shownRecd.datastoreId, self.shownRecd.latitude, self.shownRecd.longitude) self.m.addSavedMap( sm ) self.addThumb( sm, True ) self.hideTray(False) self.enableNavigation() self.smartMove( self.mediaWindow, self.savingSearchMediaLoc[0], self.savingSearchMediaLoc[1] ) if(self.maptube is not None): self.maptube.SendText("smap," + str(self.NOW_MAP_CENTER_LAT) + "," + str(self.NOW_MAP_CENTER_LNG) + "," + str(self.NOW_MAP_ZOOM) + ",Describe this map") def addLine(self,id,color,thickness,pts,isNew): self.m.setLine(id,color,thickness,pts) if((self.maptube is not None) and (isNew == 1)): self.maptube.SendText("line," + id + "," + color + "," + thickness + "," + pts) def lineMode(self,type): self.preComet() self.cometLogic.lineMode(type) self.postComet() def addSavedMap(self,lat,lng,zoom,info,isNew): # add SavedMap received from internet or other XO, use Google Static Maps window = self.canvas.window width, height = window.get_size() screenshotPath = os.path.join(Instance.instancePath, "savedMap.jpg") urllib.urlretrieve("http://maps.google.com/staticmap?key=ABQIAAAAxkKtrWN5q-vPTLRVmO_r6RRFDCLHCbUG3VrjXnZmMRXvQdFL3RS-b-ld9hTrkIgQlYsxPQ1kYq6y9A&size=200x120&format=jpg¢er=" + str(lat) + "," + str(lng) + "&zoom=" + str(int(zoom)-1), screenshotPath) smallHeight = 120 smallWidth = 200 sm = SavedMap( lat, lng, zoom, screenshotPath, screenshotPath, info, "" ) self.m.addSavedMap( sm ) self.addThumb( sm, True ) if(isNew == True): if(self.maptube is not None): # user created SaveMap, send to others self.maptube.SendText("smap," + lat + "," + lng + "," + zoom + "," + info) def addInfoMarker(self,lat,lng,info,icon,sendUpdate): # add/update InfoMarker in model self.m.setInfo(lat, lng, info, icon) if(sendUpdate == True): if(self.maptube is not None): # send added/updated info marker self.maptube.SendText("mar," + lat + "," + lng + "," + info + "," + icon) else: # put InfoMarker on own map self.preComet() self.cometLogic.handleAddMarker(lat,lng,info,icon) self.postComet() def removeThumb( self, sm ): kids = self.tray.get_children() for i in range (0, len(kids)): if (kids[i].data == sm): self.tray.remove_item(kids[i]) kids[i].cleanUp() kids[i].disconnect( kids[i].getButtClickedId() ) kids[i].setButtClickedId(0) if (sm == self.shownSave): self.hideSearchResult() self.m.savedMaps.remove(sm) def addThumb( self, sm, forceScroll ): butt = SavedButton( self, sm ) BUTT_CLICKED_ID = butt.connect( "clicked", self._thumbClickedCb, sm ) butt.setButtClickedId(BUTT_CLICKED_ID) self.tray.add_item( butt, len(self.tray.get_children()) ) butt.show() if (forceScroll): self.tray.scroll_to_end() #1 way to see a sr def _thumbClickedCb( self, button, smap ): self.showSearchResult(smap) self.preComet() self.cometLogic.handleSavedMap(smap.lat,smap.lng,smap.zoom,smap.notes) self.postComet() def showSearchResult( self, smap ): self.shownSave = smap self.updateSearchResultTags(smap) self.searchToolbar._setTagsString( smap.tags ) def updateSearchResultTags( self, smap ): self.shownSave = smap self.lngValueLabel.set_text( str(smap.lng) ) self.latValueLabel.set_text( str(smap.lat) ) self.tagsBuffer.set_text( smap.notes ) def _fillInInfoWindow( self ): hbox = gtk.HBox() self.infoWindow.add(hbox) clr = Constants.colorGrey inset = 10 self.infoWindow.modify_bg( gtk.STATE_NORMAL, clr.gColor ) ltBox = gtk.VBox() ltBox.set_border_width(inset) rtBox = gtk.VBox() hbox.pack_start(ltBox) hbox.pack_start(rtBox, expand=False) latHBox = gtk.HBox() ltBox.pack_start(latHBox, expand=False) latLabel = gtk.Label("" + Constants.istrLatitude + " ") latLabel.set_use_markup(True) latLabel.set_alignment(0, .5) latHBox.pack_start(latLabel, expand=False) self.latValueLabel = gtk.Label() self.latValueLabel.set_alignment(0, .5) latHBox.pack_start(self.latValueLabel) fillb1 = gtk.HBox() fillb1.set_size_request(inset,inset) ltBox.pack_start(fillb1, expand=False) lngHBox = gtk.HBox() ltBox.pack_start(lngHBox, expand=False) lngLabel = gtk.Label("" + Constants.istrLongitude + " ") lngLabel.set_use_markup(True) lngLabel.set_alignment(0, .5) lngHBox.pack_start(lngLabel, expand=False) self.lngValueLabel = gtk.Label() self.lngValueLabel.set_alignment(0, .5) lngHBox.pack_start(self.lngValueLabel) fillb2 = gtk.HBox() fillb2.set_size_request(inset,inset) ltBox.pack_start(fillb2, expand=False) tagLabelBox = gtk.HBox() ltBox.pack_start(tagLabelBox, expand=False) tagsLabel = gtk.Label("" + Constants.istrTags + "") tagsLabel.set_use_markup(True) tagsLabel.set_alignment(0, .5) tagLabelBox.pack_start(tagsLabel, expand=False) tagBox = gtk.HBox() self.tagsBuffer = gtk.TextBuffer() self.tagsBuffer.set_text("please edit me!") self.tagsBuffer.connect('changed', self._tagsBufferEditedCb) self.tagsField = gtk.TextView(self.tagsBuffer) ltBox.pack_start(self.tagsField, expand=True) rtFill = gtk.VBox() rtFill.set_spacing( 0 ) rtFill.set_border_width( 0 ) rtBox.pack_start(rtFill, expand=True) buttImg = gtk.Image() buttPixb = Constants.infoOnSvg.get_pixbuf() buttImg.set_from_pixbuf( buttPixb ) buttImg.show() rtButt = gtk.Button() rtButt.set_image(buttImg) rtButt.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) rtButt.modify_bg( gtk.STATE_ACTIVE, Constants.colorBlack.gColor ) rtButt.modify_bg( gtk.STATE_INSENSITIVE, Constants.colorBlack.gColor ) rtButt.set_relief(gtk.RELIEF_NONE) rtButt.set_property('can-default', True) rtButt.set_property('can-focus', False) rtButt.set_property('yalign', 1) rtButt.set_size_request( 75, 75 ) rtButt.connect("clicked", self._hideInfoCb) grr = gtk.EventBox() grr.modify_bg( gtk.STATE_NORMAL, Constants.colorBlack.gColor ) grr.add(rtButt) rtBox.pack_start(grr, expand=False) hbox.show_all() def showSearchResultTags( self, smap ): self.updateSearchResultTags( smap ) #avoid popups lingering self.hideMedia() self.preComet() self.cometLogic.handleClear() self.postComet() self.disableNavigation() browserLoc = self.browseBox.translate_coordinates(self, 0, 0) self.infoWindow.show_all() self.smartMove(self.infoWindow, browserLoc[0], browserLoc[1]) browserW = self.browseBox.allocation.width browserH = self.browseBox.allocation.height self.smartResize(self.infoWindow, browserW, browserH) self.infoWindow.set_property("accept-focus", True) def copyToClipboard( self, smap ): tmpImgPath = self.doClipboardCopyStart( smap ) gtk.Clipboard().set_with_data( [('text/uri-list', 0, 0)], self._clipboardGetFuncCb, self._clipboardClearFuncCb, tmpImgPath ) return True def doClipboardCopyStart( self, smap ): tmpImgPath = utils.getUniqueFilepath(smap.imgPath, 0) shutil.copyfile( smap.imgPath, 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 _addMediaCb( self, ot, datastoreOb ): self.addMeToMapObj = datastoreOb self.hideMedia() self.preComet() self.cometLogic.handlePreAdd() self.postComet() def _addKMLCb( self, ot, datastoreOb ): self.readKML(open(datastoreOb.file_path, 'r')) def readKML(self, kml): firstLine = kml.readline() if(firstLine.find('') for node in xmlarray: #if(node.find('') != -1): dataTable = dataTable + '' if(dataTable is not None): if(kmlline.find('' if(kmlline.find('" + kmlline[kmlline.find('" if(kmlline.find('') != -1): dataTable = dataTable + "" + kmlline[kmlline.find('')+7:kmlline.find('')] + "" elif(kmlline.find('') != -1): dataTable = dataTable + '' if(kmlline.find('') != -1): if(placemarkType == 'info'): lng = kmlline[kmlline.find('')+13:kmlline.find(',')] lat = kmlline[kmlline.find(',')+1:kmlline.rfind(',')] else: if(kmlline.find('') == -1): morePts = True kmlline = kmlline.replace('','').replace('','') coordList = kmlline.split(' ') elif(morePts == True): if(kmlline.find('') != -1): morePts = False kmlline = kmlline.replace('','') coordList.extend(kmlline.split(' ')) if(kmlline.find('') != -1): placename = kmlline[kmlline.find('')+6:kmlline.find('')] if(kmlline.find('') != -1): description = kmlline[kmlline.find('')+13:len(kmlline)] if(kmlline.find('') == -1): # need to read in more lines stillDescribing = True else: description = description[0:description.find('','') elif(stillDescribing == True): description = description + kmlline if(kmlline.find('') != -1): stillDescribing = False description = description[0:description.find('','') if(kmlline.find('')!=-1): icon = kmlline[kmlline.find('')+12:kmlline.find('')] if((kmlline.find('') != -1) or (kmlline.find('') != -1)): # finish this placemark if(lat is not None): if(description is None): description = "" else: description=description.replace("width:300","width:60").replace("max-height:400","max-height:80") if(dataTable is not None): description = dataTable + description if(placename is not None): description = '

' + placename + '

' + description if(icon is None): icon="null" self.cometLogic.handleAddMarker(lat,lng,description,icon) self.addInfoMarker(lat,lng,description,icon,True) if(coordList is not None): ptList = [] maxInterval = 1 if(len(coordList) > 50): maxInterval = int(len(coordList) / 50) interval = 1 for pt in coordList: ptloc = pt.split(',') interval = interval - 1 if((len(ptloc) > 1) and (interval < 2)): ptList.append(ptloc[1]+"|"+ptloc[0]) interval = maxInterval if(lineType == 'line'): lineID = str(random.getrandbits(128)) self.cometLogic.handleLine(lineID,"B22222","5",'|'.join(ptList)) self.addLine(lineID,"B22222","5",'|'.join(ptList),1) elif(lineType == 'poly'): lineID = "poly-" + str(random.getrandbits(128)) self.cometLogic.handleLine(lineID,"7CFC00","5",'|'.join(ptList)) self.addLine(lineID,"7CFC00","5",'|'.join(ptList),1) #elif(placemarkType == 'overlay'): lat = None lng = None description = None placename = None placemarkType = None coordList = None dataTable = None if(isOSM == True): # read in an OSM style file osmNodes = {} readingInNodeID = None readingInWayID = None for osm in kml: if(osm.find('') == -1): readingInNodeID = nodeID elif(readingInNodeID is not None): # reading in tag-values for the point if(osm.find('') != -1): readingInNodeID = None else: if(osm.find('') != -1): readingInWayID = None else: if(osm.find('"+tag+""+str(value)+"" description=description+"" self.cometLogic.handleAddMarker(osmNodes[node]["latitude"],osmNodes[node]["longitude"],description,"null") self.addInfoMarker(osmNodes[node]["latitude"],osmNodes[node]["longitude"],description,"null",True) elif(isGeoRSS == True): # scan in GeoRSS placeLink = None lat = None lng = None description = None placename = None stillDescribing = False #self.preComet() for rss in kml: if(rss.find('')+1:rss.find('')] if(rss.find('')+1:rss.find('')] if(rss.find('')+1:rss.find('')].split(' ') lat = latlng[0] lng = latlng[1] if(rss.find('') != -1): description = rss[rss.find('')+13:len(rss)] if(rss.find('') == -1): # need to read in more lines stillDescribing = True else: description = description[0:description.find('') != -1): stillDescribing = False description = description[0:description.find('') != -1): # publish the point if(lat is not None): if(description == None): description = "" if(placeLink is not None): description = placeLink + "
" + description if(placename is not None): description = '

' + placename + '

' + description description=description.replace("'","\\'").replace('"','\\"') description=description.replace("\n","
").replace("\r","
") description=description.replace("","") self.cometLogic.handleAddMarker(lat,lng,description,"null") self.addInfoMarker(lat,lng,description,"null",True) placeLink = None lat = None lng = None placename = None description = None stillDescribing = False self.cometLogic.handleEndKML(1) self.postComet() def _addInfoCb(self,ot): self.preComet() self.cometLogic.handlePreAddInfo() self.postComet() def _measureCb(self,ot): self.preComet() self.cometLogic.handleMeasure() self.postComet() def _olpcmapCb(self,ot): self.preComet() self.cometLogic.handleOlpcMAP() self.postComet() def _panoramioCb(self,ot): self.preComet() self.cometLogic.handlePanoramio() self.postComet() def _localwikiCb(self,ot): self.preComet() self.cometLogic.handleLocalWiki() self.postComet() def _wikimapiaCb(self,ot): self.preComet() self.cometLogic.handleWikiMapia() self.postComet() def disableNavigation( self ): #disable the nav buttons self.buttEast.set_image(Constants.eastImgBw) self.buttEast.set_sensitive(False) self.buttWest.set_image(Constants.westImgBw) self.buttWest.set_sensitive(False) self.buttNorth.set_image(Constants.northImgBw) self.buttNorth.set_sensitive(False) self.buttSouth.set_image(Constants.southImgBw) self.buttSouth.set_sensitive(False) #disable the toolbar buttons self.addToolbar.set_sensitive( False ) self.searchToolbar.set_sensitive( False ) def enableNavigation( self ): #enable the nav buttons self.buttEast.set_image(Constants.eastImgClr) self.buttEast.set_sensitive(True) self.buttWest.set_image(Constants.westImgClr) self.buttWest.set_sensitive(True) self.buttNorth.set_image(Constants.northImgClr) self.buttNorth.set_sensitive(True) self.buttSouth.set_image(Constants.southImgClr) self.buttSouth.set_sensitive(True) #enable the toolbar buttons self.addToolbar.set_sensitive( True ) self.searchToolbar.set_sensitive( True ) def placeAddMedia( self, lat, lng ): self.enableNavigation() #append to the map recd = self.m.addMedia( lat, lng, self.addMeToMapObj ) #now show the new addition to the map self.preComet() self.cometLogic.handlePostAdd( recd ) self.postComet() # send image to others #if(self.maptube is not None): # self.maptube.SendText("mar," + lat + "," + lng + "," + utils.getStringFromPixbuf(recd.getPixBuf()) ) def sendEndKML(self): self.maptube.SendText("endkml,now") def sendStartKML(self): self.maptube.SendText("startkml,now") def _deleteMediaCb( self, ot ): self.preComet() self.cometLogic.handleDelete() self.postComet() def showMedia(self, id, x, y, up, rt): recd = self.m.getMediaByThumbFilename(id) if (recd == None): return self.shownRecd = recd thumbPath = recd.getThumbPath() thumbPixbuf = gtk.gdk.pixbuf_new_from_file(thumbPath) px, py = [self.popW, self.popH] scl = (self.popW+0.0) / (thumbPixbuf.get_width()+0.0) thumbCairo = utils.generateThumbnail( thumbPixbuf, scl, px, py ) self.popUpBg.updatePopInfo( recd.colorStroke, recd.colorFill, thumbCairo, up, rt, self.popB, self.popB, self.htmlScale ) browserLoc = self.browseBox.translate_coordinates( self, 0, 0 ) x = int(x) * self.htmlScale y = int(y) * self.htmlScale x = browserLoc[0]+x y = browserLoc[1]+y if (not rt): x = x - (self.popW + (2*self.popB)) if (not up): y = y - (self.popH + (2*self.popB)) self.smartMove( self.popWindow, x, y ) kid = self.mediaWindow.get_child() if (kid != None): self.gplay.stop() self.mediaWindow.remove( kid ) self.mediaWindow.modify_bg(gtk.STATE_NORMAL, recd.colorFill.gColor) if (recd.type == Constants.TYPE_PHOTO): self.mediaType = 'photo' self.popWindow.hide() self.mediaWindow.show() self.smartResize( self.mediaWindow, self.popW, self.popH ) self.smartMove( self.mediaWindow, x+self.popB, y+self.popB) pbuf = recd.getPixBuf() img = _camera.cairo_surface_from_gdk_pixbuf(pbuf) self.photoCanvas.modify_bg(gtk.STATE_NORMAL, recd.colorFill.gColor) self.photoCanvas.set_size_request(self.popW, self.popH) self.photoCanvas.setImage(img) self.mediaWindow.add(self.photoCanvas) self.photoCanvas.show_all() elif (recd.type == Constants.TYPE_VIDEO): self.mediaType = 'video' self.popWindow.show() self.mediaWindow.show() self.smartResize( self.mediaWindow, self.popW, self.popH ) self.smartMove( self.mediaWindow, x+self.popB, y+self.popB) self.smartMove( self.popWindow, x+self.popB, y+self.popB) self.mediaWindow.add(self.gplayWin) self.gplayWin.modify_bg(gtk.STATE_NORMAL, recd.colorFill.gColor) self.popWindow.hide() self.mediaWindow.show() self.gplayWin.show_all() videoUrl = "file://" + str( recd.getFilepath() ) self.gplay.setLocation( videoUrl ) self.gplay.play() def hideMedia( self ): self.shownRecd = None self.moveWinOffscreen( self.popWindow ) self.moveWinOffscreen( self.mediaWindow ) self.gplay.pause() def destroy(self, *args): self.hide_all() os._exit(0) #needed to kill all threads gtk.main_quit() def _shared_cb(self, activity): self.initiating = True self._sharing_setup() id = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferDBusTube(SERVICE, {}) def _sharing_setup(self): if self._shared_activity is None: return self.conn = self._shared_activity.telepathy_conn self.tubes_chan = self._shared_activity.telepathy_tubes_chan self.text_chan = self._shared_activity.telepathy_text_chan self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal('NewTube', self._new_tube_cb) def _list_tubes_reply_cb(self, tubes): for tube_info in tubes: self._new_tube_cb(*tube_info) # joining a pre-existing activity def _joined_cb(self, activity): if not self._shared_activity: return self.initiating = False self._sharing_setup() self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].ListTubes(reply_handler=self._list_tubes_reply_cb,error_handler=self.tubes_error) # display error raised by XO-XO connection on map def tubes_error(self,e): self.preComet() self.cometLogic.handleCompassUpdate("Error: %s",e) self.postComet() def _new_tube_cb(self, id, initiator, type, service, params, state): if (type == telepathy.TUBE_TYPE_DBUS and service == 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.maptube = TextSync(tube_conn, self.initiating, self._received_cb, self.tubes_error, self._get_buddy) # _get_buddy may not be necessary. Borrowed from HelloMesh def _get_buddy(self, cs_handle): group = self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP] my_csh = group.GetSelfHandle() if my_csh == cs_handle: handle = self.conn.GetSelfHandle() elif group.GetGroupFlags() & telepathy.CHANNEL_GROUP_FLAG_CHANNEL_SPECIFIC_HANDLES: handle = group.GetHandleOwners([cs_handle])[0] else: handle = cs_handle return self.pservice.get_buddy_by_telepathy_handle(self.conn.service_name, self.conn.object_path, handle) class TextSync(ExportedGObject): def __init__(self, tube, is_initiator, text_received_cb, alert, get_buddy): super(TextSync, self).__init__(tube, PATH) self.tube = tube self.is_initiator = is_initiator self.text_received_cb = text_received_cb self._alert = alert self.entered = False # Have we set up the tube? self.text = '' # State that gets sent or received self._get_buddy = get_buddy # Converts handle to Buddy object self.tube.watch_participants(self.participant_change_cb) def participant_change_cb(self, added, removed): for handle, bus_name in added: buddy = self._get_buddy(handle) for handle in removed: buddy = self._get_buddy(handle) if not self.entered: if self.is_initiator: self.add_hello_handler() else: self.Hello() self.entered = True @signal(dbus_interface=IFACE, signature='') def Hello(self): self.bogus = 1 @method(dbus_interface=IFACE, in_signature='s', out_signature='') def World(self, text): if not self.text: self.text = text self.text_received_cb(text) self.add_hello_handler() def add_hello_handler(self): self.tube.add_signal_receiver(self.hello_cb, 'Hello', IFACE, path=PATH, sender_keyword='sender') self.tube.add_signal_receiver(self.sendtext_cb, 'SendText', IFACE, path=PATH, sender_keyword='sender') def hello_cb(self, sender=None): if sender == self.tube.get_unique_name(): return self.tube.get_object(sender, PATH).World(self.text, dbus_interface=IFACE) def sendtext_cb(self, text, sender=None): if sender == self.tube.get_unique_name(): return self.text = text self.text_received_cb(text) @signal(dbus_interface=IFACE, signature='s') def SendText(self, text): self.text = text class SearchToolbar(gtk.Toolbar): __gsignals__ = { 'address-update': (gobject.SIGNAL_RUN_FIRST, None, [object]), 'search': (gobject.SIGNAL_RUN_FIRST, None, [object]), 'zoom-in': (gobject.SIGNAL_RUN_FIRST, None, []), 'zoom-out': (gobject.SIGNAL_RUN_FIRST, None, []), 'save-search': (gobject.SIGNAL_RUN_FIRST, None, []), 'search-update': (gobject.SIGNAL_RUN_FIRST, None, [object]) } def __init__(self, pc): gtk.Toolbar.__init__(self) self.ca = pc addressLabel = gtk.Label( Constants.istrSearchAddress ) addressLabel.show() toolAddressLabel = gtk.ToolItem() toolAddressLabel.add(addressLabel) self.insert(toolAddressLabel, -1) toolAddressLabel.show() self._insertSep() self.addressField = gtk.Entry() self.addressField.connect('activate', self._addressActivateCb) addressItem = gtk.ToolItem() addressItem.set_expand(True) addressItem.add(self.addressField) self.addressField.show() self.insert( addressItem, -1 ) addressItem.show() self._insertSep() self._insertSep() self._insertSep() self._insertSep() searchLabel = gtk.Label( Constants.istrSearchMedia ) searchLabel.show() toolSearchLabel = gtk.ToolItem() toolSearchLabel.add(searchLabel) self.insert(toolSearchLabel, -1) toolSearchLabel.show() self._insertSep() self.searchField = gtk.Entry() self.searchField.connect('activate', self._searchActivateCb) searchItem = gtk.ToolItem() searchItem.set_expand(True) searchItem.add(self.searchField) self.searchField.show() self.insert( searchItem, -1 ) searchItem.show() self._insertSep() saveButt = ToolButton("save-search") saveButt.set_tooltip(Constants.istrSaveSearch) saveButt.connect('clicked', self._saveCb) self.insert(saveButt, -1) saveButt.show() self._insertSep() zout = ToolButton('map-icon-zoomOut') zout.set_tooltip(Constants.istrZoomOut) self.insert( zout, -1 ) zout.connect('clicked', self._zoomOutCb) zin = ToolButton('map-icon-zoomIn') zin.set_tooltip(Constants.istrZoomIn) self.insert( zin, -1 ) zin.connect('clicked', self._zoomInCb) def _setTagsString( self, tags ): self.searchField.set_text(tags) def _insertSep( self ): separator = gtk.SeparatorToolItem() separator.set_draw(False) separator.set_expand(False) separator.set_size_request(Constants.ui_dim_INSET, -1) self.insert( separator, -1 ) def _addressActivateCb(self, widget): address = widget.props.text self.emit('address-update', address) def _saveCb(self, widget): self.emit('save-search') def _searchActivateCb(self, widget): search = widget.props.text self.emit('search-update', search) def _zoomInCb(self, button): self.emit('zoom-in') def _zoomOutCb(self, button): self.emit('zoom-out') class PopUpP5(P5): def __init__(self): P5.__init__(self) self.fill = None self.stroke = None self.previewCairoImg = None self.up = None self.rt = None self.scale = None self.insetX = 0 self.insetY = 0 def updatePopInfo(self, stroke, fill, cairoThumb, up, rt, insetX, insetY, scale): self.fill = fill self.stroke = stroke self.previewCairoImg = cairoThumb self.up = up self.rt = rt self.scale = scale self.insetX = insetX self.insetY = insetY self.queue_draw() def draw(self, ctx, w, h): #for stroking self.fillRect( ctx, self.fill, w, h ) lw = 5 hlw = lw/2 ctx.set_line_width( lw*self.scale ) ctx.rectangle(0, 0, w, h) self.setColor(ctx, self.stroke) ctx.stroke() #for the popup bubble's handle if (not self.up): ctx.translate(0, h-(3*self.scale)) if (not self.rt): ctx.translate(w-((hlw+21)*self.scale), 0) else: ctx.translate(hlw*self.scale, 0) ctx.rectangle(0, 0, 21*self.scale, 3*self.scale) self.setColor(ctx, self.fill) ctx.fill() ctx.identity_matrix() ctx.set_source_surface(self.previewCairoImg, self.insetX, self.insetY) ctx.paint() class AddToolbar(gtk.Toolbar): __gsignals__ = { 'add-media': (gobject.SIGNAL_RUN_FIRST, None, [object]), 'add-kml': (gobject.SIGNAL_RUN_FIRST, None, [object]), 'web-media': (gobject.SIGNAL_RUN_FIRST, None, []), 'delete-media': (gobject.SIGNAL_RUN_FIRST, None, []), 'measure': (gobject.SIGNAL_RUN_FIRST, None, []), 'olpcmap': (gobject.SIGNAL_RUN_FIRST, None, []), 'panoramio':(gobject.SIGNAL_RUN_FIRST, None, []), 'local-wiki':(gobject.SIGNAL_RUN_FIRST, None, []), 'wikimapia':(gobject.SIGNAL_RUN_FIRST, None, []), 'add-info': (gobject.SIGNAL_RUN_FIRST, None, []) } def __init__(self, pc): gtk.Toolbar.__init__(self) self.ca = pc self.addButt = ToolButton('add-icon') self.addButt.set_tooltip(Constants.istrAddMedia) self.insert(self.addButt, -1) self.addButt.connect('clicked', self._addCb) infoButt = ToolButton('info-marker') infoButt.set_tooltip(Constants.istrAddInfo) self.insert(infoButt, -1) infoButt.connect('clicked', self._addInfoCb) delButt = ToolButton('delete-icon') delButt.set_tooltip(Constants.istrDeleteMedia) self.insert(delButt, -1) delButt.connect('clicked', self._delCb) self._insertSep() # add line tools lineButt = ToolButton('tool-shape-line') lineButt.set_tooltip(Constants.LineButton) self.insert(lineButt, -1) lineButt.connect('clicked', self._lineCb) polyButt = ToolButton('tool-polygon') polyButt.set_tooltip(Constants.PolyButton) self.insert(polyButt,-1) polyButt.connect('clicked', self._polyCb) self._insertSep() measButt = ToolButton('measure-icon') measButt.set_tooltip(Constants.istrMeasure) self.insert(measButt, -1) measButt.connect('clicked', self._measCb) self._insertSep() # Maps4xo library webButt = ToolButton('web-icon') webButt.set_tooltip(Constants.istrWebMedia) self.insert(webButt, -1) webButt.connect('clicked', self._webCb) # OurMaps Wiki staticButt = ToolButton('static-icon') staticButt.set_tooltip(Constants.istrStaticMaps) self.insert(staticButt, -1) staticButt.connect('clicked', self._toStaticCb) panorButt = ToolButton('panoramio') panorButt.set_tooltip(Constants.istrPanoramio) self.insert(panorButt,-1) panorButt.connect('clicked', self._toPanoramioCb) lwButt = ToolButton('localwiki') lwButt.set_tooltip(Constants.istrLocalWiki) self.insert(lwButt,-1) lwButt.connect('clicked', self._toLocalWikiCb) mapiaButt = ToolButton('wikimapia') mapiaButt.set_tooltip(Constants.istrWikiMapia) self.insert(mapiaButt,-1) mapiaButt.connect('clicked', self._toWikiMapiaCb) def _insertSep( self ): separator = gtk.SeparatorToolItem() separator.set_draw(False) separator.set_expand(False) separator.set_size_request(25 + Constants.ui_dim_INSET, -1) self.insert( separator, -1 ) def _addCb(self, button): self.ca.showFileLoadBlocker(True) fp = FilePicker() dOb = fp.show() if (dOb != None): if (dOb.file_path != None): if(dOb.metadata['mime_type']=="video/ogg") or (dOb.metadata['mime_type']=="image/jpeg"): self.emit("add-media", dOb) elif(dOb.metadata['mime_type']=="audio/ogg"): self.emit("add-media", dOb) else: self.emit("add-kml", dOb) #else: # self.emit("add-info") self.ca.showFileLoadBlocker(False) def _addInfoCb(self, button): self.emit("add-info") def _delCb(self, button): self.emit("delete-media") def _webCb(self, button): self.ca.browser.load_uri("http://maptonomy.appspot.com/maps4xo?ajaxPort=" + str(self.ca.__class__.ajaxPort) + "&cometPort=" + str(self.ca.__class__.cometPort) + "&xo=true&lat=" + str(self.ca.NOW_MAP_CENTER_LAT) + "&lng=" + str(self.ca.NOW_MAP_CENTER_LNG) + "&z=" + str(self.ca.NOW_MAP_ZOOM) + "&" + Constants.istrLang ) def _measCb(self, button): # start a measure tool (rect area or polyline) - calculation handled in HTML/JavaScript self.emit("measure") def _toStaticCb(self, button): # Map wiki through maptonomy.appspot.com/ourmap.html #self.ca.browser.load_uri("http://maptonomy.appspot.com/ourmap.html?ajaxPort=" + str(self.ca.__class__.ajaxPort) + "&cometPort=" + str(self.ca.__class__.cometPort) + "&xo=true&lat=" + str(self.ca.NOW_MAP_CENTER_LAT) + "&lng=" + str(self.ca.NOW_MAP_CENTER_LNG) + "&zoom=" + str(self.ca.NOW_MAP_ZOOM) + "&" + Constants.istrLang ) self.emit("olpcmap") #self.ca.preComet() #self.ca.cometLogic.handleOlpcMAP() #self.ca.postComet() def _toPanoramioCb(self, button): self.emit("panoramio") def _toLocalWikiCb(self, button): self.emit("local-wiki") def _toWikiMapiaCb(self, button): self.emit("wikimapia") def _lineCb(self, button): self.ca.lineMode('line') def _polyCb(self, button): self.ca.lineMode('polygon') class ServerThread(threading.Thread): def __init__(self, port, logic): threading.Thread.__init__(self) self.server = Server( ("127.0.0.1", port), logic) def run(self): try: self.server.serve_forever() except: self.run() def stop(self): #self.server.shutdown() r = 2