diff options
author | Nick Doiron <ndoiron@mapmeld.com> | 2011-05-10 20:07:11 (GMT) |
---|---|---|
committer | Nick Doiron <ndoiron@mapmeld.com> | 2011-05-10 20:07:11 (GMT) |
commit | 6f64fe14ea678edba5b7ed3ea1a97aac3ffe20b1 (patch) | |
tree | 1260de00b8633c35483013d06a30d2354235bb4b |
64 files changed, 7614 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3cd0564 --- /dev/null +++ b/Makefile @@ -0,0 +1,35 @@ +PYVER=`python -c "import sys; print '%s.%s' % (sys.version_info[0], sys.version_info[1])"` +PYTHON=python$(PYVER) + +GLIB_INCLUDES=`pkg-config --cflags glib-2.0` +GLIB_LIBS=`pkg-config --libs glib-2.0` + +GTK_INCLUDES=`pkg-config --cflags gtk+-2.0` +GTK_LIBS=`pkg-config --libs gtk+-2.0` + +PYGTK_INCLUDES=`pkg-config --cflags pygtk-2.0` +PYGTK_LIBS=`pkg-config --libs pygtk-2.0` + +CAIRO_INCLUDES=`pkg-config --cflags cairo` +CAIRO_LIBS=`pkg-config --libs cairo` + +PYCAIRO_INCLUDES=`pkg-config --cflags pycairo` +PYCAIRO_LIBS=`pkg-config --libs pycairo` + +INCLUDES=-I. -I/usr/include/${PYTHON} ${GLIB_INCLUDES} ${PYGTK_INCLUDES} ${CAIRO_INCLUDES} ${PYCAIRO_INCLUDES} ${GTK_INCLUDES} +ARCHFLAGS=-m32 -march=i386 -mtune=generic +OPTFLAGS=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -fasynchronous-unwind-tables +CFLAGS=-g -fPIC -DPIC +LDFLAGS=-shared -nostdlib -Wl,--export-dynamic -pthread + +all: build link + +build: + gcc ${INCLUDES} ${ARCHFLAGS} ${OPTFLAGS} ${CFLAGS} -c _camera.c -o _camera.o + +link: + g++ ${LDFLAGS} _camera.o ${GLIB_LIBS} ${PYGTK_LIBS} ${CAIRO_LIBS} ${PYCAIRO_LIBS} ${GTK_LIBS} -Wl,-soname -Wl,_camera.so -o _camera.so + +clean: + @find -name "*.o" -exec rm {} \; + @find -name "*.so" -exec rm {} \; diff --git a/_camera.c b/_camera.c new file mode 100644 index 0000000..694f0a4 --- /dev/null +++ b/_camera.c @@ -0,0 +1,276 @@ +#include <Python.h> + +#include "pycairo.h" +#include <glib.h> + +#include <pygobject.h> + +static PyTypeObject *_PyGObject_Type; +#define PyGObject_Type (*_PyGObject_Type) +Pycairo_CAPI_t *Pycairo_CAPI; +static PyTypeObject *_PyGdkPixbuf_Type; +#define PyGdkPixbuf_Type (*_PyGdkPixbuf_Type) + +#include <cairo.h> +#include <gdk/gdkpixbuf.h> +#include <gdk/gdkpixmap.h> +#include <cairo-xlib.h> +#include <gdk/gdkcairo.h> + +static cairo_surface_t * +_cairo_surface_from_pixbuf (GdkPixbuf *pixbuf) +{ +/* Ripped from GooCanvas */ + gint width = gdk_pixbuf_get_width (pixbuf); + gint height = gdk_pixbuf_get_height (pixbuf); + guchar *gdk_pixels = gdk_pixbuf_get_pixels (pixbuf); + int gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf); + int n_channels = gdk_pixbuf_get_n_channels (pixbuf); + guchar *cairo_pixels; + cairo_format_t format; + cairo_surface_t *surface; + static const cairo_user_data_key_t key; + int j; + + if (n_channels == 3) + format = CAIRO_FORMAT_RGB24; + else + format = CAIRO_FORMAT_ARGB32; + + cairo_pixels = g_malloc (4 * width * height); + surface = cairo_image_surface_create_for_data ((unsigned char *)cairo_pixels, + format, + width, height, 4 * width); + cairo_surface_set_user_data (surface, &key, + cairo_pixels, (cairo_destroy_func_t)g_free); + + for (j = height; j; j--) + { + guchar *p = gdk_pixels; + guchar *q = cairo_pixels; + + if (n_channels == 3) + { + guchar *end = p + 3 * width; + + while (p < end) + { +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + q[0] = p[2]; + q[1] = p[1]; + q[2] = p[0]; +#else + q[1] = p[0]; + q[2] = p[1]; + q[3] = p[2]; +#endif + p += 3; + q += 4; + } + } + else + { + guchar *end = p + 4 * width; + guint t1,t2,t3; + +#define MULT(d,c,a,t) G_STMT_START { t = c * a; d = ((t >> 8) + t) >> 8; } G_STMT_END + + while (p < end) + { +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + MULT(q[0], p[2], p[3], t1); + MULT(q[1], p[1], p[3], t2); + MULT(q[2], p[0], p[3], t3); + q[3] = p[3]; +#else + q[0] = p[3]; + MULT(q[1], p[0], p[3], t1); + MULT(q[2], p[1], p[3], t2); + MULT(q[3], p[2], p[3], t3); +#endif + + p += 4; + q += 4; + } + +#undef MULT + } + + gdk_pixels += gdk_rowstride; + cairo_pixels += 4 * width; + } + + return surface; +} + +static PyObject* +_wrap_camera_cairo_surface_from_gdk_pixbuf(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "pixbuf", NULL }; + PyGObject *child; + cairo_surface_t *surface; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:camera.cairo_surface_from_gdk_pixbuf", kwlist, &PyGdkPixbuf_Type, &child)) + return NULL; + + surface = _cairo_surface_from_pixbuf(GDK_PIXBUF (child->obj)); + if (surface == NULL) { + PyErr_SetString(PyExc_RuntimeError, "surface could not be converted"); + return NULL; + } + + return PycairoSurface_FromSurface(surface, NULL); +} + +static GdkPixbuf * +_pixbuf_from_cairo_surface (cairo_surface_t * sf) +{ + GdkPixmap * pixmap; + GdkPixbuf * pixbuf = NULL; + cairo_surface_type_t type; + gint width = 0, height = 0, depth = 0; + int format; + cairo_t * cr; + GdkColormap * cm; + + type = cairo_surface_get_type (sf); + switch (type) { + case CAIRO_SURFACE_TYPE_IMAGE: + width = cairo_image_surface_get_width (sf); + height = cairo_image_surface_get_height (sf); + format = cairo_image_surface_get_format (sf); + if (format == CAIRO_FORMAT_ARGB32) + depth = 32; + else if (format == CAIRO_FORMAT_RGB24) + depth = 24; + else if (format == CAIRO_FORMAT_A8) + depth = 8; + else if (format == CAIRO_FORMAT_A1) + depth = 1; + else if (format == CAIRO_FORMAT_RGB16_565) + depth = 16; + break; + case CAIRO_SURFACE_TYPE_XLIB: + width = cairo_xlib_surface_get_width (sf); + height = cairo_xlib_surface_get_height (sf); + depth = cairo_xlib_surface_get_depth (sf); + break; + default: + break; + } + if (!depth) + return NULL; + + pixmap = gdk_pixmap_new (NULL, width, height, depth); + if (!pixmap) + return NULL; + + cr = gdk_cairo_create (pixmap); + if (!cr) + goto release_pixmap; + + cairo_set_source_surface (cr, sf, 0, 0); + cairo_paint (cr); + cairo_destroy (cr); + + cm = gdk_colormap_get_system (); + pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, cm, 0, 0, 0, 0, -1, -1); + +release_pixmap: + gdk_pixmap_unref (pixmap); + + return pixbuf; +} + + +static PyObject* +_wrap_camera_gdk_pixbuf_from_cairo_surface(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "surface", NULL }; + PyGObject *child; + GdkPixbuf * pixbuf; + PyTypeObject *type = &PycairoSurface_Type; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:camera.gdk_pixbuf_from_cairo_surface", kwlist, type, &child)) + return NULL; + + pixbuf = _pixbuf_from_cairo_surface((cairo_surface_t *)(child->obj)); + if (pixbuf == NULL) { + PyErr_SetString(PyExc_RuntimeError, "pixbuf could not be converted"); + return NULL; + } + + return pygobject_new ((GObject *) pixbuf); +} + +const PyMethodDef py_camera_functions[] = { + { "cairo_surface_from_gdk_pixbuf", (PyCFunction)_wrap_camera_cairo_surface_from_gdk_pixbuf, + METH_VARARGS|METH_KEYWORDS, NULL }, + { "gdk_pixbuf_from_cairo_surface", (PyCFunction)_wrap_camera_gdk_pixbuf_from_cairo_surface, + METH_VARARGS|METH_KEYWORDS, NULL }, + { NULL, NULL, 0, NULL } +}; + + +/* ----------- enums and flags ----------- */ + +void +py_sugar_add_constants(PyObject *module, const gchar *strip_prefix) +{ +} + +/* initialise stuff extension classes */ +void +py_camera_register_classes(PyObject *d) +{ + PyObject *module; + + if ((module = PyImport_ImportModule("gobject")) != NULL) { + _PyGObject_Type = (PyTypeObject *)PyObject_GetAttrString(module, "GObject"); + if (_PyGObject_Type == NULL) { + PyErr_SetString(PyExc_ImportError, + "cannot import name GObject from gobject"); + return ; + } + _PyGObject_Type = (PyTypeObject *)PyObject_GetAttrString(module, "GObject"); + if (_PyGObject_Type == NULL) { + PyErr_SetString(PyExc_ImportError, + "cannot import name GObject from gobject"); + return ; + } + } else { + PyErr_SetString(PyExc_ImportError, + "could not import gobject"); + return ; + } + if ((module = PyImport_ImportModule("gtk.gdk")) != NULL) { + _PyGdkPixbuf_Type = (PyTypeObject *)PyObject_GetAttrString(module, "Pixbuf"); + if (_PyGdkPixbuf_Type == NULL) { + PyErr_SetString(PyExc_ImportError, + "cannot import name Pixbuf from gtk.gdk"); + return ; + } + } else { + PyErr_SetString(PyExc_ImportError, + "could not import gtk.gdk"); + return ; + } + + Pycairo_IMPORT; +} + +DL_EXPORT(void) +init_camera(void) +{ + PyObject *m, *d; + + Pycairo_IMPORT; + + m = Py_InitModule ("_camera", py_camera_functions); + d = PyModule_GetDict (m); + + py_camera_register_classes (d); + if (PyErr_Occurred ()) { + Py_FatalError ("can't initialise module _camera"); + } +} diff --git a/_camera.o b/_camera.o Binary files differnew file mode 100644 index 0000000..e126c76 --- /dev/null +++ b/_camera.o diff --git a/_camera.so b/_camera.so Binary files differnew file mode 100644 index 0000000..c57a12b --- /dev/null +++ b/_camera.so diff --git a/activity/activity-map.svg b/activity/activity-map.svg new file mode 100644 index 0000000..a768956 --- /dev/null +++ b/activity/activity-map.svg @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"[ + <!ENTITY stroke_color "#010101"> + <!ENTITY fill_color "#FFFFFF"> +]> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + width="74.5px" height="74px" viewBox="0 0 74.5 74" enable-background="new 0 0 74.5 74" xml:space="preserve"> +<g> + <path fill="&fill_color;" d="M74.563,55.001c0,10.692-8.748,19.44-19.44,19.44H18.67c-10.692,0-19.44-8.748-19.44-19.44V18.882 + c0-10.692,8.748-19.44,19.44-19.44h36.454c10.692,0,19.44,8.748,19.44,19.44V55.001z"/> +</g> +<g> + <line fill="none" stroke="&stroke_color;" stroke-width="3.5" x1="37.124" y1="13.641" x2="37.124" y2="23.035"/> + <path fill="none" stroke="&stroke_color;" stroke-width="3.5" d="M43.213,29.176c0,3.406-2.762,6.168-6.166,6.168 + c-3.406,0-6.167-2.762-6.167-6.168c0-3.404,2.761-6.141,6.167-6.141C40.451,23.035,43.213,25.771,43.213,29.176z M21.735,59.275 + L34.298,34.5"/> + <line fill="none" stroke="&stroke_color;" stroke-width="3.5" x1="27.88" y1="47.344" x2="54.881" y2="47.344"/> + <line fill="none" stroke="&stroke_color;" stroke-width="3.5" x1="39.949" y1="34.434" x2="52.546" y2="59.275"/> +</g> +</svg> diff --git a/activity/activity.info b/activity/activity.info new file mode 100644 index 0000000..127473f --- /dev/null +++ b/activity/activity.info @@ -0,0 +1,9 @@ +[Activity] +name = Map +activity_version = 12 +host_version = 1 +license = MIT +icon = activity-map +service_name = org.laptop.map +class = map.Map +show_launcher = 1
\ No newline at end of file diff --git a/button.py b/button.py new file mode 100644 index 0000000..d09791d --- /dev/null +++ b/button.py @@ -0,0 +1,79 @@ +import gtk +import os +import gobject +import rsvg +import gc + +from sugar.graphics.palette import Palette +from sugar.graphics.tray import TrayButton +from sugar.graphics.icon import Icon +from sugar.graphics import style +from constants import Constants +import utils + +class SavedButton(TrayButton, gobject.GObject): + def __init__(self, ui, savedmapData): + TrayButton.__init__(self) + self.ui = ui + self.data = savedmapData + + img = self.getImg() + self.set_icon_widget( img ) + + self.setup_rollover_options() + + + def getImg( self ): + pb = gtk.gdk.pixbuf_new_from_file(self.data.thumbPath) + + img = gtk.Image() + img.set_from_pixbuf(pb) + img.show() + + return img + + + def setButtClickedId( self, id ): + self.BUTT_CLICKED_ID = id + + + def getButtClickedId( self ): + return self.BUTT_CLICKED_ID + + + def setup_rollover_options( self ): + palette = Palette( Constants.istrSavedMap ) + self.set_palette(palette) + + self.tag_menu_item = gtk.MenuItem( Constants.istrTagMap ) + self.ACTIVATE_TAG_ID = self.tag_menu_item.connect('activate', self._tagCb) + palette.menu.append(self.tag_menu_item) + self.tag_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.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 ) + self.copy_menu_item.disconnect( self.ACTIVATE_COPY_ID ) + self.tag_menu_item.disconnect( self.ACTIVATE_TAG_ID) + + + def _tagCb(self, widget): + self.ui.showSearchResultTags( self.data ) + + + def _itemRemoveCb(self, widget): + self.ui.removeThumb( self.data ) + + + def _itemCopyToClipboardCb(self, widget): + self.ui.copyToClipboard( self.data ) diff --git a/color.py b/color.py new file mode 100644 index 0000000..8c8903e --- /dev/null +++ b/color.py @@ -0,0 +1,75 @@ +# 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 + +class Color: + + 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 + + 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 ) + + + 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 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 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)) + + + def getCanvasColor(self): + return str(self._ro) + "," + str(self._go) + "," + str(self._bo)
\ No newline at end of file diff --git a/constants.py b/constants.py new file mode 100644 index 0000000..9ae1ecf --- /dev/null +++ b/constants.py @@ -0,0 +1,131 @@ +import os +import gtk +from gettext import gettext as _ + +import sugar.graphics.style +from sugar.activity import activity +from sugar import profile + +from instance import Instance +from color import Color +import utils + +class Constants: + + VERSION = 8 + + SERVICE = "org.laptop.Map" + IFACE = SERVICE + PATH = "/org/laptop/Map" + activityId = None + + gfxPath = os.path.join(activity.get_bundle_path(), "gfx") + htmlPath = os.path.join(activity.get_bundle_path(), "html") + iconsPath = os.path.join(activity.get_bundle_path(), "icons") + + istrAnnotate = _("Edit") + istrSearch = _("Search") + istrSearchAddress = _('Find:') + istrSearchMedia = _("Tags:") + istrSaveSearch = _("Save Search") + istrConnecting = _("Connecting to Map Server") + istrZoomIn = _("Zoom In") + istrZoomOut = _("Zoom Out") + istrSaveSearch = _("Save") + istrDensity = _("Density") + istrSavedMap = _("Saved Map") + istrTagMap = _("Describe Map") + istrRemove = _("Remove Map") + istrCopyToClipboard = _("Copy to Clipboard") + istrAddMedia = _("Add Media") + istrAddInfo = _("Add Info") + istrDeleteMedia = _("Delete") + istrWebMedia = _("Library") + istrMeasure = _("Measure") + istrStaticMaps = _("olpcMAP.net") + istrPanoramio = _("Panoramio") + istrLocalWiki = _("LocationWiki") + istrWikiMapia = _("WikiMapia") + istrLatitude = _("Latitude:") + istrLongitude = _("Longitude:") + istrTags = _("Description:") + istrLang = _("lang=en") + LineButton = _("Add Line") + PolyButton = _("Add Shape") + + TYPE_PHOTO = 0 + TYPE_VIDEO = 1 + + ui_dim_INSET = 4 + + recdAlbum = "map" + recdLat = "lat" + recdLng = "lng" + recdDatastoreId = "datastore" + recdInfo = "info" + recdMapItem = "mapItem" + recdSavedMapItem = "savedMap" + recdInfoMarker = "infoMarker" + recdIcon = "icon" + recdZoom = "zoom" + recdNotes = "notes" + recdMapImg = "mapImg" + recdTags = "tags" + recdMapThumbImg = "mapThumbImg" + recdRecdId = "recdId" + recdRecdLat = "recdLat" + recdRecdLng = "recdLng" + recdDensity = "density" + recdLine = "line" + lineID = "lid" + lineColor = "lcolor" + lineThick = "lthickness" + linePts = "lpts" + mapLat="lat" + mapLng="lng" + mapZoom="zoom" + + 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) + colorGrey = Color() + colorGrey.init_gdk( sugar.graphics.style.COLOR_BUTTON_GREY ) + colorBg = colorBlack + + def __init__( self, ca ): + self.__class__.activityId = ca._activity_id + self.__class__.northImgClr, self.__class__.northImgBw = self.loadSvgImg('map-icon-croseN.svg') + self.__class__.southImgClr, self.__class__.southImgBw = self.loadSvgImg('map-icon-croseS.svg') + self.__class__.eastImgClr, self.__class__.eastImgBw = self.loadSvgImg('map-icon-croseE.svg') + self.__class__.westImgClr, self.__class__.westImgBw = self.loadSvgImg('map-icon-croseW.svg') + + infoOnSvgPath = os.path.join(self.__class__.iconsPath, 'corner-info.svg') + infoOnSvgFile = open(infoOnSvgPath, 'r') + infoOnSvgData = infoOnSvgFile.read() + self.__class__.infoOnSvg = utils.loadSvg(infoOnSvgData, None, None ) + infoOnSvgFile.close() + + def loadSvgImg(self, fileName): + SvgPath = os.path.join(self.__class__.iconsPath, fileName) + SvgFile = open(SvgPath, 'r') + SvgData = SvgFile.read() + SvgFile.close() + + ColorSvg = utils.loadSvg(SvgData, Instance.colorStroke.hex, Instance.colorFill.hex) + ColorPixBuf = ColorSvg.get_pixbuf() + ColorImg = gtk.Image() + ColorImg.set_from_pixbuf(ColorPixBuf) + + MonoSvg = utils.loadSvg(SvgData, self.__class__.colorGrey.hex, self.__class__.colorWhite.hex) + MonoPixBuf = MonoSvg.get_pixbuf() + MonoImg = gtk.Image() + MonoImg.set_from_pixbuf(MonoPixBuf) + + return [ColorImg, MonoImg] diff --git a/filepicker.py b/filepicker.py new file mode 100644 index 0000000..cabc295 --- /dev/null +++ b/filepicker.py @@ -0,0 +1,46 @@ +# Copyright (C) 2007, One Laptop Per Child +# Copyright (c) 2008, Media Modifications Ltd. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import gtk + +from sugar.graphics.objectchooser import ObjectChooser + +class FilePicker: + + def __init__(self): + pass + + + def show(self): + title = None + parent = None + file = None + job = None + chooser = ObjectChooser() + + try: + result = chooser.run() + if result == gtk.RESPONSE_ACCEPT: + jobject = chooser.get_selected_object() + if (jobject and jobject.file_path): + job = jobject + + finally: + chooser.destroy() + del chooser + + return job diff --git a/gplay.py b/gplay.py new file mode 100644 index 0000000..3ceb353 --- /dev/null +++ b/gplay.py @@ -0,0 +1,154 @@ +# 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. + +#look at jukeboxactivity.py + +import gtk +import pygtk +pygtk.require('2.0') +import sys +import pygst +pygst.require('0.10') +import gst +import gst.interfaces +import gobject +import time +gobject.threads_init() + +class Gplay: + + 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() + + 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 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): + print("setLocation: ", 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:] + if (ext == "jpg"): + self.pause() + print("all played?") + + + 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 + + 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 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 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 is_playing(self): + return self.playing + + + +class PlayVideoWindow(gtk.EventBox): + def __init__(self, bgd): + gtk.EventBox.__init__(self) + + 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) + + + 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 diff --git a/html/MediaMarker.js b/html/MediaMarker.js new file mode 100644 index 0000000..a47b00b --- /dev/null +++ b/html/MediaMarker.js @@ -0,0 +1,21 @@ +function MediaMarker(){ +return{ + initialize:function(pt, markerServer, markerId, tags, info, icon) + {this.markerServer=markerServer; + this.markerId=markerId; + this.pt=pt; + this.tags=tags; + this.info=info; + if(icon==null){icon="null";} + this.icon=icon; + this.iconDiv=null; + if((this.tags == undefined)||(this.tags==null)) + {this.tags = "";} + }, + getLatLng:function(){return this.pt;}, + get_position:function(){return this.pt;}, + get_info:function(){return this.info;}, + getMarkerServer:function(){return this.markerServer;}, + getMarkerId:function(){return this.markerId;} +}; +}
\ No newline at end of file diff --git a/html/staticMapCanvas.js b/html/staticMapCanvas.js new file mode 100644 index 0000000..422c373 --- /dev/null +++ b/html/staticMapCanvas.js @@ -0,0 +1,148 @@ +var GMapCanvas2={ + initialize: function(prefLat, prefLng, prefZoom, prefType) + { this.map = document.getElementById("map"); + this.center = [prefLat*1,prefLng*1]; + this.zoom=prefZoom; + this.resolution="480x303"; + this.factor=0.75; + this.yfactor=0.75; + switch(prefType){ + case "terrain": + this.mapType = "terrain";break; + case "sat": + this.mapType = "satellite";break; + case "terr": + this.mapType = "hybrid";break; + case "hyb": + this.mapType = "hybrid";break; + case "osm": + this.mapType = "osm";break; + default: + this.mapType = "roadmap";break; + } + document.getElementById(this.mapType).className="selectmaptype"; + this.markerList=[]; + this.lineColor="ff0000"; + this.updateImg(); + return this; + }, + get_center:function(){return this.center;}, + get_zoom:function(){return this.zoom;}, + get_type:function(){return this.mapType;}, + get_bounds:function(){ + var sw=[1*this.center[0]-0.55618*this.factor*Math.pow(2,(9-1*this.zoom)),this.center[1]*1 - 0.98877*this.factor*Math.pow(2,(9-1*this.zoom))]; + var ne=[1*this.center[0]+0.55618*this.factor*Math.pow(2,(9-1*this.zoom)),this.center[1]*1 + 0.98877*this.factor*Math.pow(2,(9-1*this.zoom))]; + return [sw,ne]; + }, + set_center:function(latlng){ + if(latlng[0]>85){latlng=[85,latlng[1]]} + if(latlng[0]<-85){latlng=[-85,latlng[1]]} + this.center = latlng; + this.updateImg(); + updateLoc() + }, + set_zoom:function(z){this.zoom = z;this.updateImg();}, + set_type:function(type){ + if(type==this.mapType){return;} + try{document.getElementById(this.mapType).className = "maptype";document.getElementById(type).className = "selectmaptype";} + catch(e){} + this.mapType=type; + this.updateImg(); + }, + fitBounds:function(bounds){ + this.bounds=bounds; + this.center=[(bounds[0][0]*1.0+1.0*bounds[1][0])/2.0,(bounds[0][1]*1.0+1.0*bounds[1][1])/2.0]; + var latDiff=Math.abs(bounds[0][0]-bounds[1][0]); + var lngDiff=Math.abs(bounds[0][1]-bounds[1][1]); + if(latDiff/lngDiff>0.628){this.zoom=Math.floor(10-Math.log(latDiff/0.556)/0.301);} + else{this.zoom=Math.floor(10-Math.log(lngDiff/0.8789)/0.301);} + this.zoom=Math.min(Math.max(this.zoom,3),15); + this.updateImg(); + }, + setLineLayer:function(data){ + if((this.lineLayer)&&(mapData)){this.lineLayer+="&path=color:0x"+this.lineColor+"|weight:5|"+data;} + else{this.lineLayer = data;} + }, + setLineColor:function(color){this.lineColor = color;}, + setResolution:function(res){this.resolution = res;}, + updateImg:function(){ + params=[]; + if(this.mapType!="osm"){ + params.push("center="+this.center[0].toFixed(6)+","+this.center[1].toFixed(6)); + params.push("zoom="+this.zoom); + params.push("maptype="+this.mapType); + if(this.markerList.length>0){ + var lls=""; + var bounds=this.get_bounds(); + for(var m=0;m<this.markerList.length;m++){ + var mar=this.markerList[m]; + if(mar.icon=="null"){lls +="|"+ mar.getLatLng()[0].toFixed(6)+","+mar.getLatLng()[1].toFixed(6);} + else{ + if(!mar.iconDiv){ + mar.iconDiv=document.createElement("img"); + mar.iconDiv.src=mar.icon; + var px=pixel(mar.pt,bounds); + mar.iconDiv.style.left=parseInt(px[0]-mar.iconDiv.width/2)+"px"; + mar.iconDiv.style.top=parseInt(px[1]-mar.iconDiv.height/2)+"px"; + mar.iconDiv.style.position="absolute"; + mar.iconDiv.style.display="block"; + mar.iconDiv.id=mar.markerId; + mar.iconDiv.onclick=function(event){showInfo(mrkWithId(event.target.id).get_info())}; + document.body.appendChild(mar.iconDiv); + } + if((mar.pt[0]<bounds[1][0])&&(mar.pt[0]>bounds[0][0])&&(mar.pt[1]>bounds[0][1])&&(mar.pt[1]<bounds[1][1])){ + mar.iconDiv.style.display="block"; + var px=pixel(mar.pt,bounds); + mar.iconDiv.style.left=parseInt(px[0]-mar.iconDiv.width/2)+"px"; + mar.iconDiv.style.top=parseInt(px[1]-mar.iconDiv.height/2)+"px"; + } + else{ mar.iconDiv.style.display="none" } + } + } + if(lls!=""){params.push("markers=size:mid" + lls);} + } + if(this.lineLayer){params.push("path=color:0x" + this.lineColor + "|weight:5|" + this.lineLayer);} + if((this.mapType=="roadmap")||(this.mapType=="satellite")){params.push("mobile=true");} + if(doRep){this.map.src="http://maptonomy.appspot.com/maps4xo/report?size=" + this.resolution + "&format=jpg&mc="+this.markerList.length+"&lc="+lineList.length+"&"+params.join("&");doRep = false;} + else{this.map.src="http://maps.google.com/maps/api/staticmap?sensor=false&size=" + this.resolution + "&format=jpg&" + params.join("&");} + }else{ + params.push("center="+this.center[1].toFixed(6)+","+this.center[0].toFixed(6)); + params.push("zoom="+this.zoom); + var lls=""; + for(var m=0;m<this.markerList.length;m++){ + var mar=this.markerList[m]; + if(mar.icon=="null"){lls +=mar.getLatLng()[1]+","+mar.getLatLng()[0]+";"} + else{ + if(!mar.iconDiv){ + mar.iconDiv=document.createElement("img"); + mar.iconDiv.src=mar.icon; + var px=pixel(mar.pt,bounds); + mar.iconDiv.style.left=parseInt(px[0]-mar.iconDiv.width/2)+"px"; + mar.iconDiv.style.top=parseInt(px[1]-mar.iconDiv.height/2)+"px"; + mar.iconDiv.style.position="absolute"; + mar.iconDiv.style.display="block"; + mar.iconDiv.id=mar.markerId; + mar.iconDiv.onclick=function(event){showInfo(mrkWithId(event.target.id).get_info())}; + document.body.appendChild(mar.iconDiv); + } + if(bounds.contains(mar.pt)){ + mar.iconDiv.style.display="block"; + var px=pixel(mar.pt,bounds); + mar.iconDiv.style.left=parseInt(px[0]-mar.iconDiv.width/2)+"px"; + mar.iconDiv.style.top=parseInt(px[1]-mar.iconDiv.height/2)+"px" + } + else{ mar.iconDiv.style.display="none"} + } + } + if(lls!=""){params.push("points="+lls)} + if(this.lineLayer){ + var linefill=[]; + var linebunch=this.lineLayer.split("|"); + for(var p=0;p<linebunch.length;p++){if(linebunch[p].indexOf(",")!=-1){linefill.push(linebunch[p].split(",")[1] + "," + linebunch[p].split(",")[0])}} + if(this.lineLayer.indexOf("fill")>-1){params.push("polygons="+linefill.join(",")+",thickness:5,transparency:50")} + else{params.push("paths="+linefill.join(",")+",thickness:5,transparency:50")} + } + this.map.src="http://dev.openstreetmap.org/~pafciu17/?module=map&width=480&height=303&imgType=jpg&"+params.join("&"); + } + } +} diff --git a/html/staticmap2.html b/html/staticmap2.html new file mode 100644 index 0000000..960e1c5 --- /dev/null +++ b/html/staticmap2.html @@ -0,0 +1,734 @@ +<html id="html"> +<head id="head"> +<script src="MediaMarker.js" type="text/javascript"></script> +<script src="staticMapCanvas.js?v=2" type="text/javascript"></script> +<script type="text/javascript"> +var canvas,ajaxPort,cometPort,mediaWin,mMrkrs,justSetMap,mapData,mID,mapCover; +var xo=false; +var addingMedia=false; +var tagFilter=""; +var infoMarkers=[]; +var lineList=[]; +var isMedia=true; +var mDist=0; +var mesrTime=false; +var addingInfo=false; +var isFirstSearch=true; +var isSecondSearch=true; +var mapData=null; +var doRep=false; +var editTxt="Edit"; +var addTxt="Add"; +var describeTxt="Describe this place"; +var mapYSPAN = 404; +var mapXSPAN = 640; +var mapXOFF = 80; +var addingLines=false; +var currentLine=-1; +function gup(nm){nm=nm.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");var rxS="[\\?&]"+nm+"=([^&#]*)";var rx=new RegExp(rxS);var rs=rx.exec(window.location.href);if(!rs){return null;}else{return rs[1];}} +function load(){ + ajaxPort = gup("ajaxPort"); + cometPort = gup("cometPort"); + mapCover = $("mapCover").getContext("2d"); + var initLat = gup('lat'); + var initLng = gup('lng'); + var initZoom = gup('zoom'); + if((!initLat)||(!initLng)||(!initZoom)){initLat=29.978;initLng=31.133;initZoom=2} + initZoom = parseInt(initZoom); + justSetMap = [initLat,initLng,initZoom]; + if(gup("xo")=="true"){xo=true;} + canvas = GMapCanvas2.initialize(initLat, initLng, initZoom, gup("type")); + if(xo){lhCometInit();lhMediaQuery();} + else{alert("You need an XO to control the map");} + closeiWin(); + setInterval(sendReport, 180000); + setTimeout(sendReport, 60000); + $("toolbar-en").href="http://maptonomy.appspot.com/toolbar.html?aj="+ajaxPort+"&cm="+cometPort+"&lang=en"; + $("toolbar-es").href="http://maptonomy.appspot.com/toolbar.html?aj="+ajaxPort+"&cm="+cometPort+"&lang=es"; + if(gup("lang")=="es"){ + $("roadmap").innerHTML="Mapa"; + $("satellite").innerHTML="Satélite"; + $("hybrid").innerHTML="Híbrido"; + $("terrain").innerHTML="Relieve"; + $("center").innerHTML="Centro"; + $("zoom").innerHTML="Magnificar"; + editTxt="Editar"; + addTxt="Crear"; + describeTxt="Escribe algo aquí"; + $("toolbar-en").style.display="none"; + $("special").innerHTML="<br/><a href='#' onclick='proyecto()' style='font-size:10pt;'>Proyecto</a><span style='color:#f00;font-size:7pt;vertical-align:top;'>Nuevo</span>"; + } + else if(gup("lang")=="mn"){ + $("roadmap").innerHTML="газрын зураг"; + $("satellite").innerHTML="Фото"; + $("hybrid").innerHTML="гибрид"; + $("terrain").innerHTML="топограф"; + $("center").innerHTML="төв"; + editTxt="засварлах"; + addTxt="хийх"; + describeTxt="тодорхойлох"; + } + mapXSPAN = ($("map").width+"").replace("px","").replace("pt","")*1.0000000000; + mapYSPAN = ($("map").height+"").replace("px","").replace("pt","")*1.0000000000; + mapXOFF = ($("map").width+"").replace("px","").replace("pt","")*0.125000000000; + canvas.factor=canvas.factor*640/mapXSPAN; + canvas.yfactor=canvas.factor*404/mapYSPAN; +} +function sendReport(){doRep=true;} +function lineMode(type){ + if(addingLines){ + addingLines = false; + $("mapCover").className = "-moz-grab"; + $("map").className = "-moz-grab"; + var newScript = document.createElement('script'); + var dLine = lineList[currentLine]; + var ptOutput = []; + for(var p=0;p<dLine.pts.length;p++){ + ptOutput.push(dLine.pts[p][0] + "|" + dLine.pts[p][1]); + } + ptOutput = ptOutput.join("|"); + newScript.src = "http://127.0.0.1:" + ajaxPort + "/addLine.js?id=" + dLine.id + "&col=" + dLine.color.replace("#","") + "&thick=4&pts=" + ptOutput; + newScript.type = "text/javascript"; + newScript.onload = lhAjax; + $("head").appendChild(newScript); + //showInfo(newScript.src); + currentLine = -1; + updateLines(); + } + else{ + addingLines = true; + $("mapCover").className = "crosshairMap"; + $("map").className = "crosshairMap"; + var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"; + var colorchars = "0123456789abcdef"; + var string_length = 8; + var lineID = ''; + for(var i=0; i<string_length; i++) { + var rnum = Math.floor(Math.random() * chars.length); + lineID += chars.substring(rnum,rnum+1); + } + if(type.indexOf("poly") != -1){ + lineID = "poly-" + lineID; + } + var randColor = ""; + for(var i=0; i<3; i++){ + var rnum = Math.floor(Math.random() * colorchars.length); + randColor += colorchars.substring(rnum,rnum+1); + } + currentLine = lineList.length; + addLine(lineID,randColor,5,[]); + } +} +function placeVertex(event){ + var vert = toLatLngArray(event.clientX,event.clientY); + lineList[currentLine].pts.push(vert) + updateLines(); +} +function addLine(line_id,line_color,line_thick,line_pts){ + try{ + if(line_pts.indexOf("|") != -1){ + //in |-separated format from Python + line_pts_b = line_pts.split("|"); + line_pts=[]; + for(var lpi=0;lpi<line_pts_b.length;lpi+=2){ + line_pts.push([line_pts_b[lpi],line_pts_b[lpi+1]]); + } + } + } + catch(e){} + for(var l=0;l<lineList.length;l++){ + if(lineList[l].id==line_id){ + lineList[l].color="#"+line_color; + lineList[l].thickness=line_thick; + lineList[l].pts=line_pts; + updateLines(); + return; + } + } + lineList.push({id:line_id,color:"#"+line_color,thickness:line_thick,pts:line_pts}); + showInfo("Click the line button again to stop.<br/><br/>Clic el boton de linea otra vez a terminar"); + if(!addingLines){ + currentLine=lineList.length-1; + addingLines=true; + lineMode('new'); + } +} +function updateLines(){ + if(lineList.length == 0){ return } + $("mapCover").width=$("mapCover").width; + for(var l=0;l<lineList.length;l++){ + var dLine=lineList[l]; + if(dLine.pts.length < 2){continue} + var lastPt=dLine.pts[0]; + var drewLast=false; + var firstPt=lastPt; + if(dLine.id.indexOf("poly")==-1){ + mapCover.strokeStyle=dLine.color; + mapCover.lineWidth=dLine.thickness; + } + else{ + mapCover.fillStyle=dLine.color; + mapCover.lineWidth=0; + //mapCover.strokeStyle="#000"; + drewLast=true; + } + if(inBounds(pixelprse(lastPt[0],lastPt[1]))||drewLast){ + drewLast = true; + mapCover.beginPath(); + mapCover.moveTo(parseInt(pixelprse(lastPt[0],lastPt[1])[0]),parseInt(pixelprse(lastPt[0],lastPt[1])[1])); + } + for(var p=1;p<dLine.pts.length;p++){ + var thisPt=dLine.pts[p]; + if(drewLast){ + mapCover.lineTo(parseInt(pixelprse(thisPt[0],thisPt[1])[0]),parseInt(pixelprse(thisPt[0],thisPt[1])[1])); + } + else{ + if(inBounds(pixelprse(lastPt[0],lastPt[1]))){ + drewLast=true; + mapCover.beginPath(); + mapCover.moveTo(parseInt(pixelprse(lastPt[0],lastPt[1])[0]),parseInt(pixelprse(lastPt[0],lastPt[1])[1])); + mapCover.lineTo(parseInt(pixelprse(thisPt[0],thisPt[1])[0]),parseInt(pixelprse(thisPt[0],thisPt[1])[1])); + } + } + lastPt=thisPt; + } + if(drewLast){ + if(dLine.id.indexOf("poly")==-1){ + mapCover.stroke(); + } + else{ + mapCover.closePath(); + mapCover.fill(); + } + } + } + if(currentLine>=0){ + //draw a square at each point in the line or polygon + for(var p=0;p<lineList[currentLine].pts.length;p++){ + var thisPt=lineList[currentLine].pts[p]; + mapCover.fillStyle="#000"; + mapCover.fillRect(parseInt(pixelprse(thisPt[0],thisPt[1])[0])-6,parseInt(pixelprse(thisPt[0],thisPt[1])[1])-6,12,12); + } + } +} +function inBounds(px){ + if(px[0]<0){return false;} + if(px[0]>820){return false;} + if(px[1]<0){return false;} + if(px[1]>520){return false;} + return true; +} +function infoImg(id){ + showMedia('<div style="color:#fff;font-size:45pt;width:200;">a<br/>b<br/><Media>a</div>'); + var newScript=document.createElement('script'); + newScript.src="http://127.0.0.1:" + ajaxPort + "/showMedia.js?id=" + id + "&x=" + ($("iEnc").offsetLeft*1 + 25) + "&y=" + ($("iEnc").offsetTop*1 + 10) + "&up=true&rt=true"; + newScript.type="text/javascript"; + newScript.onload=lhAjax; + $("head").appendChild(newScript); +} +function moveToAddress(swlat,swlng,nelat,nelng,longname){ + showInfo("Found " + longname + "<br/>..."); + canvas.fitBounds([[swlat,swlng],[nelat,nelng]]); + updateLoc(); +} +function panoramio(){ + var panScript=document.createElement('script'); + var bounds=canvas.get_bounds(); + var southwest=bounds[0]; + var northeast=bounds[1]; + panScript.src="http://www.panoramio.com/map/get_panoramas.php?set=public&from=0&to=15&minx="+southwest[1]+"&miny="+southwest[0]+"&maxx="+northeast[1]+"&maxy="+northeast[0]+"&size=medium&mapfilter=true&callback=panorProcess"; + panScript.type="text/javascript"; + panScript.onload=lhAjax; + $("head").appendChild(panScript); +} +function panorProcess(panPhotoApi){ + for(var p=0;p<panPhotoApi.photos.length;p++){ + addInfoMarker(panPhotoApi.photos[p].latitude,panPhotoApi.photos[p].longitude,'img::'+panPhotoApi.photos[p].photo_file_url,'http://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=location|DD0033',true); + } + canvas.updateImg() +} +function wikimapia(){ + var wmScript=document.createElement('script'); + var bounds=canvas.get_bounds(); + var southwest=bounds[0]; + var northeast=bounds[1]; + wmScript.src="http://api.wikimapia.org/?function=box&key=BF98697A-C9DB9950-55508AB4-9643CB1A-23509969-23D9FFF3-5B19C5D2-E9CF5DEB&bbox="+southwest[1]+","+southwest[0]+","+northeast[1]+","+northeast[0]+"&count=20&format=jsonp&jsoncallback=processWM"; + wmScript.type="text/javascript"; + wmScript.onload=lhAjax; + $("head").appendChild(wmScript); +} +function processWM(wikiMapiaApi){ + for(var w=0;w<wikiMapiaApi.folder.length;w++){ + var newplist=[]; + for(var ppt=0;ppt<wikiMapiaApi.folder[w].polygon.length;ppt++){ + newplist.push([wikiMapiaApi.folder[w].polygon[ppt].y,wikiMapiaApi.folder[w].polygon[ppt].x]); + } + newplist.push(newplist[0]); + //lineMode('poly'); + lineMode('new'); + lineList[lineList.length-1].pts=newplist; + addInfoMarker(wikiMapiaApi.folder[w].location.north,wikiMapiaApi.folder[w].location.east,wikiMapiaApi.folder[w].name + "<br/><small>WikiMapia</small>",'http://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=location|DD0033',true); + } + updateLines(); + canvas.updateImg(); +} +function wikiloc(){ + var wikiScript=document.createElement('script'); + var ctr=canvas.get_center(); + wikiScript.src="http://api.wikilocation.org/articles?lat="+ctr[0]+"&lng="+ctr[1]+"&limit=15&jsonp=wikiprocess&radius=5000"; + wikiScript.type="text/javascript"; + wikiScript.onload=lhAjax; + $("head").appendChild(wikiScript); +} +function wikiprocess(wikiLocApi){ + for(var w=0;w<wikiLocApi.articles.length;w++){ + var art=wikiLocApi.articles[w]; + addInfoMarker(art.lat*1,art.lng*1,'<small>WikiLocation.org</small>wikiEN::'+art.title,'http://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=location|DD0033',true); + } + canvas.updateImg(); +} +function preAddInfo(){ + closeiWin(); + addingInfo=true; + hidePics(); + $("mapCover").className = "crosshairMap"; + $("map").className = "crosshairMap"; +} +function placeInfoMarker(event){ + addingInfo = false; + loc = toLatLng(event.clientX,event.clientY); + addInfoMarker(loc[0],loc[1],describeTxt,"null",true); + addedMedia(); +} +function addInfoMarker(lat,lng,info,icon,showNow){ + for(var i=0;i<infoMarkers.length;i++){ + if(infoMarkers[i].getLatLng()[0] == lat){ + if(infoMarkers[i].getLatLng()[1] == lng){ + infoMarkers[i].info = unescape(info); + return; + } + } + } + var mk = MediaMarker(); + mID="info-"+infoMarkers.length; + mk.initialize([lat,lng],null,mID,null,unescape(info),icon); + infoMarkers.push(mk); + canvas.markerList.push( mk ); + hidePics(); + if(showNow){ + isMedia = false; + mID=mk.getMarkerId(); + showInfo(info); + } +} +function updateInfo(id){ + closeiWin(); + var iMarker = mrkWithId(id); + iMarker.info = replaceAll($("infoText").value,"\n","<br/>"); + var loc = iMarker.getLatLng(); + var newScript = document.createElement('script'); + newScript.src = "http://127.0.0.1:" + ajaxPort + "/addInfoMarker.js?lat=" + loc[0] + "&lng=" + loc[1] + "&info=" + iMarker.info + "&icon=" + iMarker.icon + "&isNew=True"; + newScript.type = "text/javascript"; + newScript.onload = lhAjax; + $("head").appendChild(newScript); +} +function editInfoMarker(id){ + iMarker = mrkWithId(id); + mID = id; + isMedia = true; + showInfo("<textarea id='infoText' style='height:200;width:250;'>" + iMarker.get_info() + "</textarea><br/><input type='button' class='centerButton' value='" + addTxt + "' onclick='updateInfo(\"" + iMarker.getMarkerId() + "\")'/>"); +} +function lhHideMedia() +{ var newScript = document.createElement('script'); + var d = new Date(); + newScript.src = "http://127.0.0.1:" + ajaxPort + "/hideMedia.js?t="+d.getTime() + newScript.type = "text/javascript"; + $("head").appendChild(newScript); +} +function lhCometInit() +{ var newScript = document.createElement('script'); + var d = new Date(); + newScript.src = "http://127.0.0.1:" + cometPort + "/comet.js?t="+d.getTime() + newScript.type = "text/javascript"; + newScript.onload = lhCometResponse; + $("head").appendChild(newScript); +} +function lhCometResponse(){ lhCometInit(); } +function lhMediaQuery() +{ var bounds = canvas.get_bounds(); + var southWest = bounds[0]; + var northEast = bounds[1]; + var newScript = document.createElement('script'); + newScript.src = "http://127.0.0.1:" + ajaxPort + "/mediaQuery.js?s=" + southWest[0] + "&w=" + southWest[1] + "&n=" + northEast[0] + "&e=" + northEast[1] + newScript.type = "text/javascript"; + newScript.onload = lhAjax; + $("head").appendChild(newScript); +} +function updateLoc() +{ var ctr = canvas.get_center(); + var zoom = canvas.get_zoom(); + var newScript = document.createElement('script'); + if(mediaWin != null){ + newScript.src = "http://127.0.0.1:" + ajaxPort + "/updateLocation.js?lat=" + ctr[0] + "&lng=" + ctr[1] + "&z=" + zoom + "&x=" + ($("iEnc").offsetLeft*1 + 25) + "&y=" + ($("iEnc").offsetTop*1 + 10); + } + else{ + newScript.src = "http://127.0.0.1:" + ajaxPort + "/updateLocation.js?lat=" + ctr[0] + "&lng=" + ctr[1] + "&z=" + zoom + "&x=-1&y=-1"; + } + newScript.type = "text/javascript"; + newScript.onload = lhAjax; + $("head").appendChild(newScript); + updateLines(); +} +function $(id){return document.getElementById(id);} +function mrkWithId(id){ + for(var i=0;i<canvas.markerList.length;i++){ + if(canvas.markerList[i].getMarkerId() == id){ + return canvas.markerList[i]; + } + } +} +function lhAjax(){} +function setMap(lat,lng,zoom,info){ + if(zoom!=canvas.get_zoom()){canvas.set_zoom(zoom);} + var bounds=canvas.get_bounds(); + var latSpan=Math.abs(bounds[0][0]-bounds[1][0]); + var lngSpan=Math.abs(bounds[0][1]-bounds[1][1]); + var latDiff=(lat-justSetMap[0])/latSpan; + var lngDiff=(lng-justSetMap[1])/lngSpan; + if((Math.abs(latDiff)>0.15)||(Math.abs(lngDiff)>0.15)){ + justSetMap=[lat,lng,zoom]; + canvas.set_center([1*lat,1*lng]); + } + if(info){isMedia=true;showInfo(info);} + else{closeiWin();} +} +function setMap2(lat,lng,zoom,info){ + if(zoom!=canvas.get_zoom()){canvas.set_zoom(zoom);} + if((lat!=canvas.get_center()[0])||(lng!=canvas.get_center()[1])){canvas.set_center([1*lat,1*lng]);} + justSetMap=[lat,lng,zoom]; + if(info){isMedia=true;showInfo(unescape(info));} + else{closeiWin();} +} +function hidePics(){lhHideMedia();if(!mediaWin){closeiWin();}} +function findDirs(){ + var ctr=canvas.get_center(); + var z=canvas.get_zoom(); + var right=1*ctr[1]+0.3295875*Math.pow(2,(10-z)); + var left=1*ctr[1]-0.3295875*Math.pow(2,(10-z)); + var top=1*ctr[0]+0.2085*Math.pow(2,(10-z)); + var bottom=1*ctr[0]-0.2085*Math.pow(2,(10-z)); + if((left>0)&&(right<0)){left-=360;} + return [ctr,right,left,top,bottom]; +} +function dirEast(){var plcs=findDirs();var nuCtr=[plcs[0][0],1.3*plcs[1]-0.3*plcs[2]];canvas.set_center(nuCtr);} +function dirWest(){var plcs=findDirs();var nuCtr=[plcs[0][0],-0.3*plcs[1]+1.3*plcs[2]];canvas.set_center(nuCtr);} +function dirNorth(){var plcs=findDirs();var nuCtr=[1.3*plcs[3]-0.3*plcs[4],plcs[0][1]];canvas.set_center(nuCtr);} +function dirSouth(){var plcs=findDirs();var nuCtr=[-0.3*plcs[3]+1.3*plcs[4],plcs[0][1]];canvas.set_center(nuCtr);} +function zoomIn(){hidePics();canvas.set_zoom(canvas.get_zoom()+1);updateLoc();} +function zoomOut(){hidePics();canvas.set_zoom(Math.max(canvas.get_zoom()-1,2));updateLoc();} +function deleteMedia(){ + for(i=0;i<canvas.markerList.length;i++){if(canvas.markerList[i].getMarkerId()==mID){ + canvas.markerList.splice(i,1); + canvas.updateImg(); + break; + }} +} +function preAddMedia() +{ if(!mediaWin){closeiWin();} + addingMedia = true; + hidePics(); + updateLoc(); + $("mapCover").className="crosshairMap"; + $("map").className="crosshairMap"; +} +function placeAddMedia(event) +{ var pt=toLatLng(event.clientX, event.clientY); + var newScript=document.createElement('script'); + newScript.src="http://127.0.0.1:" + ajaxPort + "/placeAddMedia.js?lat=" + pt[0] + "&lng=" + pt[1]; + newScript.type="text/javascript"; + newScript.onload=lhAjax; + $("head").appendChild(newScript); +} +function postAddMedia( lat, lng, url, basename, tags ) +{ var mk=MediaMarker(); + mk.initialize([lat,lng],url,basename,tags); + canvas.markerList.push(mk); + hidePics(); + addedMedia(); + var cell = mk; + if (cell != null){infoImg(cell.markerId);} + canvas.updateImg(); + updateLoc(); +} +function addedMedia() +{ addingMedia=false; + $("mapCover").className="-moz-grab"; + $("map").className="-moz-grab"; +} +function toLatLng(x,y){ + x+=".000000"; + y+=".000000"; + var factor=canvas.factor; + var yfactor = canvas.yfactor; + var ctr=canvas.get_center(); + var zoom=canvas.get_zoom(); + var mapLng=(x-mapXOFF-0.50000000*mapXSPAN)*0.00141335458*factor*Math.pow(2,(10-zoom))+1*ctr[1]; + var mapLat=1*ctr[0]-(y-0.50000000*mapYSPAN)*yfactor*0.001255065*Math.pow(2,(10-zoom)); + return [mapLat,mapLng]; +} +function toLatLngArray(x,y){ + x+=".000000"; + y+=".000000"; + var factor=canvas.factor; + var yfactor = canvas.yfactor; + var ctr=canvas.get_center(); + var zoom=canvas.get_zoom(); + var mapLng=(x-mapXOFF-0.50000000*mapXSPAN)*0.00141335458*1.25*factor*Math.pow(2,(10-zoom))+1*ctr[1]; + var mapLat=1*ctr[0]-(y-0.50000000*mapYSPAN)*yfactor*0.001255065*1.25*Math.pow(2,(10-zoom)); + return [mapLat,mapLng]; +} +function measure(event){ + isMedia=true; + if(!mesrTime){showInfo('Measure<br/><a href="#" onclick="measureLine(null)">x→x Distance (km)</a><br/><br/><a href="#" onclick="measureBox(null)">[] Area (km²)</a>');} + else if(mesrTime=='line'){measureLine(event);} + else{measureBox(event);} +} +function measureLine(event){ + $('iEnc').style.display="none"; + if(!mMrkrs){ + mMrkrs=[]; + mesrTime="line"; + $("mapCover").className="crosshairMap"; + $("map").className="crosshairMap"; + } + else{ + if(!event){ + mMrkrs = null; + mDist = 0; + $("mapCover").className = "-moz-grab"; + $("map").className = "-moz-grab"; + mesrTime = false; + canvas.setLineLayer(null); + return; + } + var measMark = toLatLng(event.clientX,event.clientY); + mMrkrs.push(measMark); + if(mMrkrs.length > 1){ + mDist = (1*mDist) + 0.903*dist(measMark[0], measMark[1], mMrkrs[mMrkrs.length-2][0], mMrkrs[mMrkrs.length-2][1]); + isMedia=true; + showInfo("Measured "+mDist.toFixed(1)+" km<br/>= "+(0.622*mDist).toFixed(1)+" miles<br/><a href='#' onclick='measureLine()'>Done</a>"); + var pts=[]; + for(var m=0;m<mMrkrs.length;m++){pts.push(mMrkrs[m][0].toFixed(5)+","+mMrkrs[m][1].toFixed(5));} + canvas.setLineLayer(pts.join("|")); + canvas.updateImg(); + } + } +} +function measureBox(event){ + $('iEnc').style.display="none"; + if(!mMrkrs){ + mMrkrs=new Array(); + mesrTime="box"; + $("mapCover").className="crosshairMap"; + $("map").className="crosshairMap"; + } + else{ + mMrkrs.push(toLatLng(event.clientX,event.clientY)); + if(mMrkrs.length>1){ + var mArea=dist(mMrkrs[1][0],mMrkrs[0][1],mMrkrs[0][0],mMrkrs[0][1]); + mArea*=dist(mMrkrs[1][0],mMrkrs[1][1],mMrkrs[1][0],mMrkrs[0][1]); + var mArea2=dist(mMrkrs[1][0],mMrkrs[1][1],mMrkrs[0][0],mMrkrs[1][1]); + mArea2*=dist(mMrkrs[0][0],mMrkrs[1][1],mMrkrs[0][0],mMrkrs[0][1]); + mArea=(mArea+mArea2)*0.45; + isMedia=true; + showInfo("Measured "+mArea.toFixed(1)+" km² (sq.km)<br/>= "+(mArea*0.3869).toFixed(1)+" miles²<br/><a href='#' onclick='closeiWin()'>Done</a>"); + mesrTime=null; + $("mapCover").className = "-moz-grab"; + $("map").className = "-moz-grab"; + var pts = [mMrkrs[1][0].toFixed(5)+","+mMrkrs[1][1].toFixed(5)]; + pts.push(mMrkrs[1][0].toFixed(5)+","+mMrkrs[0][1].toFixed(5)); + pts.push(mMrkrs[0][0].toFixed(5)+","+mMrkrs[0][1].toFixed(5)); + pts.push(mMrkrs[0][0].toFixed(5)+","+mMrkrs[1][1].toFixed(5)); + pts.push(mMrkrs[1][0].toFixed(5)+","+mMrkrs[1][1].toFixed(5)); + canvas.setLineLayer("fillcolor:0x0000ff|"+pts.join("|")); + mMrkrs=null; + canvas.updateImg(); + canvas.setLineLayer(null); + } + } +} +function pixel(latlng,bounds){ + var center=canvas.get_center(); + var latDiff=Math.abs(latlng[0]-center[0]); + var lngDiff=Math.abs(latlng[1]-center[1]); + var latSpan=Math.abs(bounds[0][0]-bounds[1][0]); + var lngSpan=Math.abs(bounds[0][1]-bounds[1][1]); + if((center[1]>0)&&(latlng[1]<0)){lngDiff=latlng[1]-(center[1]-360)} + if((latlng[1]>0)&&(center[1]<0)){lngDiff=center[1]-(latlng[1]-360)} + var yDiff=Math.round(latDiff/latSpan*mapYSPAN/1.1); + if(1*latlng[0]<1*center[0]){yDiff=mapYSPAN*0.500000+yDiff} + else{yDiff=mapYSPAN*0.50000000-yDiff} + var xDiff=Math.round(lngDiff/lngSpan*mapXSPAN/1.25); + if(1*latlng[1]>1*center[1]){xDiff=mapXSPAN*0.500000+xDiff+mapXOFF} + else{xDiff=mapXSPAN*0.50000000-xDiff+mapXOFF} + return [xDiff,yDiff]; +} +function pixelprse(lat,lng){ + var bounds=canvas.get_bounds(); + var center=canvas.get_center(); + var latDiff=Math.abs(lat-center[0]); + var lngDiff=Math.abs(lng-center[1]); + var latSpan=Math.abs(bounds[0][0]-bounds[1][0]); + var lngSpan=Math.abs(bounds[0][1]-bounds[1][1]); + if((center[1]>0)&&(lng<0)){lngDiff=lng-(center[1]-360)} + if((lng>0)&&(center[1]<0)){lngDiff=center[1]-(lng-360)} + var yDiff=Math.round(latDiff/latSpan*mapYSPAN/1.01); + if(1*lat<1*center[0]){yDiff=mapYSPAN*0.500000+yDiff} + else{yDiff=mapYSPAN*0.50000000-yDiff} + var xDiff=Math.round(lngDiff/lngSpan*mapXSPAN/1.01); + if(1*lng>1*center[1]){xDiff=mapXSPAN*0.500000+xDiff} + else{xDiff=mapXSPAN*0.50000000-xDiff} + return [xDiff,yDiff]; +} +function dist(lat1,lon1,lat2,lon2){var R=6371;var dLat=toRad(lat2-lat1);var dLon=toRad(lon2-lon1);var a=Math.sin(dLat/2)*Math.sin(dLat/2)+Math.cos(toRad(lat1))*Math.cos(toRad(lat2))*Math.sin(dLon/2)*Math.sin(dLon/2); var c=2*Math.atan2(Math.sqrt(a),Math.sqrt(1-a)); return R*c;} +function toRad(deg){return deg/180*Math.PI;} +function showInfo(er){ + if(er==''){return;} + if(!isMedia){ + if(er.indexOf("::") != -1){ + if(er.indexOf('wiki::') != -1){ er = '<b>' + er.replace('wiki::','</b><iframe height="300" width="320" src="http://simple.m.wikipedia.org/wiki/') + '"></iframe>'; } + else if(er.indexOf('iframe::') != -1){ er = '<b>' + er.replace('iframe::','</b><iframe height="300" width="320" src="') + '"></iframe>'; } + else if(er.indexOf('img::') != -1){ er = '<b>' + er.replace('img::','</b><br/><img style="max-height:300;max-width:300;" src="') + '"/>'; } + else if(er.indexOf('pic::') != -1){ er = '<b>' + er.replace('pic::','</b><br/><img style="max-height:300;max-width:300;" src="') + '"/>'; } + else if(er.indexOf('google::') != -1){ er = er.replace('google::','<iframe height="300" width="320" src="http://google.com/search?q=') + '"></iframe>'; } + else if(er.indexOf('vid::') != -1){ er = '<b>' + er.replace('vid::','</b><br/><object width="300" height="300" type="application/ogg" data="') + '"></object>'; } + else if((er.indexOf('wiki') != -1)&&(er.indexOf('::') > er.indexOf('wiki'))){ + var erBegin = er.substring(0,er.lastIndexOf('wiki')); + er = er.substring(er.lastIndexOf('wiki')); + var wikiCode = er.substring(4,er.indexOf('::')); + er = er.substring(er.indexOf('::') + 2); + er = '<b>' + erBegin + '</b><iframe height="300" width="320" src="http://' + wikiCode + '.m.wikipedia.org/wiki/' + er + '"></iframe>'; + } + } + er+="<br/><input type='button' class='centerButton' value='" + editTxt + "' onclick='editInfoMarker(" + '"' + mID + '"' + ")'/>"; + } + $("iWin").innerHTML = er; + $("iEnc").style.display = "block"; + $("iWin").style.display = "block"; +} +function showMedia(er){ + mediaWin = $("iWin"); + $("iWin").innerHTML = er; + $("iEnc").style.display = "block"; + $("iWin").style.display = "block"; +} +function closeiWin(){ + if(mediaWin != null){ + lhHideMedia(); + mediaWin = null; + } + $("iWin").style.display = "none"; + $("iEnc").style.display = "none"; +} +function clickToZoom(event){hidePics();this.canvas.center=toLatLng(event.clientX,event.clientY);canvas.set_zoom(canvas.get_zoom()+1);updateLoc();} +var cCtr = false; +function clickingCenter(){ + cCtr=true; + $("mapCover").className="crosshairMap"; + $("map").className="crosshairMap"; +} +function clkCtr(event){ + canvas.set_center(toLatLng(event.clientX,event.clientY)); + $("mapCover").className="-moz-grab"; + $("map").className="-moz-grab"; + cCtr=false; +} +function clkMar(event){ + var bounds=canvas.get_bounds(); + var mIndex=-1; + var minDist=12*mapYSPAN; + for(var m=0;m<canvas.markerList.length;m++){ + var mark=canvas.markerList[m]; + var pix=pixel(mark.getLatLng(),bounds); + var pDiff=Math.pow(Math.abs(pix[0] - event.clientX + 80),2) + Math.pow(Math.abs(pix[1] - event.clientY),2); + if(pDiff<minDist){ + mIndex = mark.getMarkerId(); + minDist = pDiff; + } + } + if(mIndex==-1){return;} + mID=mIndex; + if(mID.indexOf("info-") != 0){ + isMedia=true; + infoImg(mID); + } + else{ + isMedia=false; + showInfo(mrkWithId(mID).get_info()); + } +} +function filterTags(sTerms){ + var sTerms = unescape(sTerms).toLowerCase(); + sTerms = replaceAll(sTerms," ",""); + for(var m=0;m<canvas.markerList.length;m++){ + var formattedInfo = replaceAll(canvas.markerList[m].info.toLowerCase()," ",""); + if(formattedInfo.indexOf(sTerms) != -1){ + closeiWin(); + isMedia=false; + setMap2(canvas.markerList[m].pt[0],canvas.markerList[m].pt[1],canvas.zoom,canvas.markerList[m].info); + return; + } + } +} +function replaceAll(src,old,fix){ + while(src.indexOf(old) != -1){ + src = src.replace(old,fix); + } + return src; +} +function proyecto(){ + showInfo('<h3>Proyecto <img src="Proyecto.png" style="vertical-align:middle;"/></h3><ol><li>Click Menú de Editar</li><li>Click el botón <img src="infoIcon.png" style="vertical-align:middle;width:30px;"/>, y click en el mapa</li><li><b>Escribir y creer con mapas</b></li><li>Si empieza con "NuestrosMapas" puede compartir mapas en el internet <img src="NuestrosMapas.png" style="vertical-align:middle;width:30px;"/></li></ol>'); +} +</script> +<style type="text/css"> +body{font-family:arial} +#map{width:89%;height:98.8%;top:0px;left:11%;position:absolute} +img.crosshairMap{cursor:crosshair} +canvas.crosshairMap{cursor:crosshair} +#go{position:absolute;bottom:30px;left:0px} +#sidebar{position:absolute;top:0px;left:0px;width:11%;height:98%;border-top:1px solid #000;border-bottom:1px solid #000} +div.maptype{-moz-border-radius:5px;background-color:silver;color:#000;border:1px solid #000;padding:3px;cursor:pointer} +div.selectmaptype{-moz-border-radius:5px;background-color:#fff;color:#000;border:1px solid #000;padding:3px;font-weight:bold;cursor:pointer} +#iEnc{position:absolute;left:90px;top:30px;-moz-border-radius:10px;border:2px solid #000;background:#fff;width:330px;padding:3px;padding-left:10px;display:none;z-index:10} +input.cBtn{float:right} +input:hover{color:#000;cursor:pointer} +::-moz-selection{background:none;color:#fff} +textarea{border:1px solid #000} +div.ayuda a{color:#ff00ff;font-size:11pt} +img.zoom{cursor:pointer;margin-left:24px;border:1px solid #fff} +img.zoom:hover{border:1px solid #000} +</style> +</head> +<body id="body" onload="load();"> +<!--<a id="toolbar-soas" href="#" style="float:right">Use Sugar on a Stick</a>--> +<div id="sidebar"> + <div id="roadmap" class="maptype" onclick="canvas.set_type('roadmap')">Map</div> + <div id="satellite" class="maptype" onclick="canvas.set_type('satellite')">Satellite</div> + <div id="hybrid" class="maptype" onclick="canvas.set_type('hybrid')">Hybrid</div> + <div id="terrain" class="maptype" onclick="canvas.set_type('terrain')">Terrain</div> + <div id="osm" class="maptype" onclick="canvas.set_type('osm')">OSM</div> + <span id="center">Center</span><br/><input type="button" onclick="clickingCenter()" value="(+)"/><br/><br/> + <span id="zoom">Zoom</span><br/> + <img src="zPlus.png" class="zoom" onclick="zoomIn()"/><br/><br/> + <img src="zMinus.png" class="zoom" onclick="zoomOut()"/><br/><br/> + <div id="ayuda" class="ayuda"> + <a id="toolbar-en" href="#">Help</a> + <a id="toolbar-es" href="#">Guía</a> + </div> + <div id="special"> + </div> +</div> +<img id="map" class="defaultMap" src="" alt="Connecting to Google Maps..." onclick="if(cCtr){clkCtr(event);}else if(mesrTime){measure(event);}else if(addingMedia){placeAddMedia(event);}else if(addingInfo){placeInfoMarker(event);}if(addingLines){placeVertex(event)}else{clkMar(event);}" ondblclick="clickToZoom(event)"/> +<canvas id="mapCover" style="position:absolute;left:11%;top:0px;" width="640" height="404" onclick="if(cCtr){clkCtr(event);}else if(mesrTime){measure(event);}else if(addingMedia){placeAddMedia(event);}else if(addingInfo){placeInfoMarker(event);}if(addingLines){placeVertex(event)}else{clkMar(event);}" ondblclick="clickToZoom(event)"></canvas> +<div id="iEnc"><input type="button" class="cBtn" onclick="closeiWin()" value="x"/><div id="iWin"></div></div> +</body></html> diff --git a/html/zMinus.png b/html/zMinus.png Binary files differnew file mode 100644 index 0000000..01b4447 --- /dev/null +++ b/html/zMinus.png diff --git a/html/zPlus.png b/html/zPlus.png Binary files differnew file mode 100644 index 0000000..cb00699 --- /dev/null +++ b/html/zPlus.png diff --git a/icons/add-icon.svg b/icons/add-icon.svg new file mode 100644 index 0000000..81e7c87 --- /dev/null +++ b/icons/add-icon.svg @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948) --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg version="1.1" id="Layer_5" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + width="74.5px" height="74px" viewBox="0 0 74.5 74" enable-background="new 0 0 74.5 74" xml:space="preserve"> +<g> + <path d="M75.084,54.702c0,10.692-8.748,19.44-19.439,19.44H19.19c-10.692,0-19.44-8.748-19.44-19.44V18.583 + c0-10.692,8.748-19.44,19.44-19.44h36.454c10.691,0,19.439,8.748,19.439,19.44V54.702z"/> +</g> +<g> + <g> + <g> + <path fill="none" stroke="#FFFFFF" stroke-width="3" stroke-linecap="round" d="M62.587,37.583 + c0-13.909-11.256-25.165-25.167-25.165S12.254,23.674,12.254,37.583c0,13.911,11.256,25.167,25.167,25.167 + S62.587,51.494,62.587,37.583z"/> + <path fill="none" stroke="#FFFFFF" stroke-width="3" stroke-linecap="round" d="M37.42,54.825 + c-9.537,0-17.241-7.705-17.241-17.242c0-9.535,7.704-17.24,17.241-17.24s17.241,7.705,17.241,17.24 + C54.661,47.12,46.957,54.825,37.42,54.825z"/> + </g> + </g> + <g> + <line fill="none" stroke="#FFFFFF" stroke-width="4" stroke-linecap="round" x1="26.448" y1="37.638" x2="48.613" y2="37.638"/> + <line fill="none" stroke="#FFFFFF" stroke-width="4" stroke-linecap="round" x1="37.532" y1="26.555" x2="37.532" y2="48.721"/> + </g> +</g> +</svg> diff --git a/icons/corner-info.svg b/icons/corner-info.svg new file mode 100644 index 0000000..9a22582 --- /dev/null +++ b/icons/corner-info.svg @@ -0,0 +1,15 @@ +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [ + <!ENTITY stroke_color "#010101"> + <!ENTITY fill_color "#CDCCCC"> +]><svg enable-background="new 0 0 75 75" height="75px" version="1.1" viewBox="0 0 75 75" width="75px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="0px"><g display="block" id="corner-info"> + <g display="inline"> + <rect height="75" width="75"/> + <g> + <polygon fill="&fill_color;" points="0,0 75,0 0,75 "/> + </g> + <g> + <path d="M22.34,35.03h2.534l-0.383,2.017h-8.436l3.051-15.704h-2.518l0.384-2.018h8.419L22.34,35.03z M19.923,14.308 c0.177-0.9,0.636-1.659,1.375-2.275c0.739-0.617,1.559-0.925,2.459-0.925c0.877,0,1.567,0.311,2.067,0.934 c0.367,0.456,0.55,0.99,0.55,1.601c0,0.21-0.022,0.433-0.066,0.667c-0.167,0.878-0.62,1.625-1.359,2.243 c-0.74,0.617-1.548,0.925-2.426,0.925c-0.9,0-1.6-0.306-2.101-0.917c-0.377-0.456-0.567-0.99-0.567-1.601 C19.856,14.747,19.879,14.53,19.923,14.308z"/> + </g> + <polyline fill="none" points="1,75 1,1 75,1 " stroke="#808080" stroke-width="2"/> + </g> +</g></svg>
\ No newline at end of file diff --git a/icons/delete-icon.svg b/icons/delete-icon.svg new file mode 100644 index 0000000..3c33ea9 --- /dev/null +++ b/icons/delete-icon.svg @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948) --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg version="1.1" id="Layer_5" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + width="74.5px" height="74px" viewBox="0 0 74.5 74" enable-background="new 0 0 74.5 74" xml:space="preserve"> +<g> + <path d="M75.084,54.702c0,10.692-8.748,19.44-19.439,19.44H19.19c-10.692,0-19.44-8.748-19.44-19.44V18.583 + c0-10.692,8.748-19.44,19.44-19.44h36.454c10.691,0,19.439,8.748,19.439,19.44V54.702z"/> +</g> +<g> + <g> + <g> + <path fill="none" stroke="#FFFFFF" stroke-width="3" stroke-linecap="round" d="M62.587,37.583 + c0-13.909-11.256-25.165-25.167-25.165S12.254,23.674,12.254,37.583c0,13.911,11.256,25.167,25.167,25.167 + S62.587,51.494,62.587,37.583z"/> + <path fill="none" stroke="#FFFFFF" stroke-width="3" stroke-linecap="round" d="M37.42,54.825 + c-9.537,0-17.241-7.705-17.241-17.242c0-9.535,7.704-17.24,17.241-17.24s17.241,7.705,17.241,17.24 + C54.661,47.12,46.957,54.825,37.42,54.825z"/> + </g> + </g> + <g> + <line fill="none" stroke="#FFFFFF" stroke-width="4" stroke-linecap="round" x1="26.448" y1="37.638" x2="48.613" y2="37.638"/> + </g> +</g> +</svg> diff --git a/icons/info-marker.svg b/icons/info-marker.svg new file mode 100644 index 0000000..329063f --- /dev/null +++ b/icons/info-marker.svg @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + enable-background="new 0 0 75 75" + height="75px" + version="1.1" + viewBox="0 0 75 75" + width="75px" + x="0px" + xml:space="preserve" + y="0px" + id="svg2516" + sodipodi:version="0.32" + inkscape:version="0.46" + sodipodi:docname="info-marker.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata + id="metadata2536"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs + id="defs2534"><inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 37.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="75 : 37.5 : 1" + inkscape:persp3d-origin="37.5 : 25 : 1" + id="perspective2538" /> + + + + + + + + + </defs><sodipodi:namedview + inkscape:window-height="669" + inkscape:window-width="644" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + guidetolerance="10.0" + gridtolerance="10.0" + objecttolerance="10.0" + borderopacity="1.0" + bordercolor="#666666" + pagecolor="#ffffff" + id="base" + showgrid="false" + inkscape:zoom="6.16" + inkscape:cx="33.821642" + inkscape:cy="37.5" + inkscape:window-x="46" + inkscape:window-y="46" + inkscape:current-layer="svg2516" /><g + id="g2523"> + <polygon + points="0,0 75,0 0,75 0,0 " + id="polygon2525" + style="fill:#cdcccc" /> + </g><path + id="path2529" + d="M 38.249091,42.172857 L 40.783091,42.172857 L 40.400091,44.189857 L 31.964091,44.189857 L 35.015091,28.485857 L 32.497091,28.485857 L 32.881091,26.467857 L 41.300091,26.467857 L 38.249091,42.172857 z M 35.832091,21.450857 C 36.009091,20.550857 36.468091,19.791857 37.207091,19.175857 C 37.946091,18.558857 38.766091,18.250857 39.666091,18.250857 C 40.543091,18.250857 41.233091,18.561857 41.733091,19.184857 C 42.100091,19.640857 42.283091,20.174857 42.283091,20.785857 C 42.283091,20.995857 42.261091,21.218857 42.217091,21.452857 C 42.050091,22.330857 41.597091,23.077857 40.858091,23.695857 C 40.118091,24.312857 39.310091,24.620857 38.432091,24.620857 C 37.532091,24.620857 36.832091,24.314857 36.331091,23.703857 C 35.954091,23.247857 35.764091,22.713857 35.764091,22.102857 C 35.765091,21.889857 35.788091,21.672857 35.832091,21.450857 z" /><polyline + points="1,75 1,1 75,1 " + id="polyline2531" + style="fill:none;stroke:#808080;stroke-width:2" /><path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 14.61039,27.75974 C 19.388669,6.3149988 28.791112,5.6794885 38.961039,6.4935068 C 63.592708,6.9421238 59.868291,26.878152 59.415585,27.11039 C 59.515344,40.116612 52.346731,43.09609 43.668832,48.701298 L 36.146897,68.043417 L 35.714286,69.155844 L 27.11039,51.623377 C 27.380953,43.290043 15.476191,48.106061 14.61039,27.75974 z" + id="path2556" + sodipodi:nodetypes="cccccccc" /></svg>
\ No newline at end of file diff --git a/icons/localwiki.svg b/icons/localwiki.svg new file mode 100644 index 0000000..245f888 --- /dev/null +++ b/icons/localwiki.svg @@ -0,0 +1,327 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + inkscape:export-ydpi="90" + inkscape:export-xdpi="90" + inkscape:export-filename="/home/mischa/Icone/app or web icons/Wikipedia Tango/wikipedia_48.png" + width="48px" + height="48px" + id="svg11300" + sodipodi:version="0.32" + inkscape:version="0.46" + sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/emblems" + sodipodi:docname="wikipedia_new.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape"> + <defs + id="defs3"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 24 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="48 : 24 : 1" + inkscape:persp3d-origin="24 : 16 : 1" + id="perspective47" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient5060" + id="radialGradient6719" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)" + cx="605.71429" + cy="486.64789" + fx="605.71429" + fy="486.64789" + r="117.14286" /> + <linearGradient + inkscape:collect="always" + id="linearGradient5060"> + <stop + style="stop-color:black;stop-opacity:1;" + offset="0" + id="stop5062" /> + <stop + style="stop-color:black;stop-opacity:0;" + offset="1" + id="stop5064" /> + </linearGradient> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient5060" + id="radialGradient6717" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)" + cx="605.71429" + cy="486.64789" + fx="605.71429" + fy="486.64789" + r="117.14286" /> + <linearGradient + id="linearGradient5048"> + <stop + style="stop-color:black;stop-opacity:0;" + offset="0" + id="stop5050" /> + <stop + id="stop5056" + offset="0.5" + style="stop-color:black;stop-opacity:1;" /> + <stop + style="stop-color:black;stop-opacity:0;" + offset="1" + id="stop5052" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5048" + id="linearGradient6715" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)" + x1="302.85715" + y1="366.64789" + x2="302.85715" + y2="609.50507" /> + <linearGradient + id="linearGradient11327"> + <stop + style="stop-color:#7d6400;stop-opacity:1;" + offset="0" + id="stop11329" /> + <stop + style="stop-color:#be9700;stop-opacity:1.0000000;" + offset="1.0000000" + id="stop11331" /> + </linearGradient> + <linearGradient + id="linearGradient2092"> + <stop + id="stop2094" + offset="0" + style="stop-color:#fff7b0;stop-opacity:1;" /> + <stop + style="stop-color:#ffec41;stop-opacity:1.0000000;" + offset="0.20999999" + id="stop2098" /> + <stop + id="stop2293" + offset="0.83999997" + style="stop-color:#e2cc00;stop-opacity:1;" /> + <stop + id="stop2100" + offset="1" + style="stop-color:#c3af00;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient11335"> + <stop + style="stop-color:#6f716d;stop-opacity:1;" + offset="0" + id="stop11337" /> + <stop + style="stop-color:#9ea09c;stop-opacity:1.0000000;" + offset="1.0000000" + id="stop11339" /> + </linearGradient> + <linearGradient + id="linearGradient10591"> + <stop + style="stop-color:#cad0c6;stop-opacity:1.0000000;" + offset="0.0000000" + id="stop10593" /> + <stop + id="stop10599" + offset="0.50000000" + style="stop-color:#eaece9;stop-opacity:1.0000000;" /> + <stop + style="stop-color:#c5cbc0;stop-opacity:1.0000000;" + offset="1.0000000" + id="stop10595" /> + </linearGradient> + <linearGradient + id="linearGradient11520"> + <stop + id="stop11522" + offset="0.0000000" + style="stop-color:#ffffff;stop-opacity:1.0000000;" /> + <stop + id="stop11524" + offset="1.0000000" + style="stop-color:#dcdcdc;stop-opacity:1.0000000;" /> + </linearGradient> + <linearGradient + id="linearGradient11508" + inkscape:collect="always"> + <stop + id="stop11510" + offset="0" + style="stop-color:#000000;stop-opacity:1;" /> + <stop + id="stop11512" + offset="1" + style="stop-color:#000000;stop-opacity:0;" /> + </linearGradient> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient11508" + id="radialGradient1348" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.000000,0.000000,0.000000,0.338462,-1.435476e-15,29.48178)" + cx="30.203562" + cy="44.565483" + fx="30.203562" + fy="44.565483" + r="6.5659914" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient11520" + id="radialGradient1366" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.995058,-1.651527e-32,0.000000,1.995058,-24.32488,-35.70087)" + cx="24.445690" + cy="35.878170" + fx="24.445690" + fy="35.878170" + r="20.530962" /> + <inkscape:perspective + id="perspective9" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 526.18109 : 1" + sodipodi:type="inkscape:persp3d" /> + </defs> + <sodipodi:namedview + stroke="#ef2929" + fill="#729fcf" + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="0.25490196" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="11.354167" + inkscape:cx="23.559478" + inkscape:cy="23.524464" + inkscape:current-layer="layer1" + showgrid="true" + inkscape:grid-bbox="true" + inkscape:document-units="px" + inkscape:showpageshadow="true" + inkscape:window-width="872" + inkscape:window-height="744" + inkscape:window-x="0" + inkscape:window-y="0" + borderlayer="false"> + <inkscape:grid + type="xygrid" + id="grid8399" + visible="true" + enabled="true" /> + </sodipodi:namedview> + <metadata + id="metadata4"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:creator> + <cc:Agent> + <dc:title>Jakub Steiner</dc:title> + </cc:Agent> + </dc:creator> + <dc:source>http://jimmac.musichall.cz</dc:source> + <cc:license + rdf:resource="http://creativecommons.org/licenses/publicdomain/" /> + <dc:title>Read Only Emblem</dc:title> + <dc:subject> + <rdf:Bag> + <rdf:li>emblem</rdf:li> + <rdf:li>read-only</rdf:li> + <rdf:li>nowrite</rdf:li> + </rdf:Bag> + </dc:subject> + </cc:Work> + <cc:License + rdf:about="http://creativecommons.org/licenses/publicdomain/"> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Reproduction" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Distribution" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> + </cc:License> + </rdf:RDF> + </metadata> + <g + id="layer1" + inkscape:label="Layer 1" + inkscape:groupmode="layer"> + <g + transform="matrix(2.243788e-2,0,0,2.086758e-2,44.06795,40.547)" + id="g6707"> + <rect + style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" + id="rect6709" + width="1339.6335" + height="478.35718" + x="-1559.2523" + y="-150.69685" /> + <path + style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" + d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z " + id="path6711" + sodipodi:nodetypes="cccc" /> + <path + sodipodi:nodetypes="cccc" + id="path6713" + d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z " + style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /> + </g> + <rect + ry="5.4548240" + rx="5.4548240" + y="3.5233452" + x="4.4147282" + height="40.061924" + width="40.061924" + id="rect11518" + style="opacity:1.0000000;color:#000000;fill:url(#radialGradient1366);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#9b9b9b;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" + inkscape:export-xdpi="48.220001" + inkscape:export-ydpi="48.220001" /> + <rect + style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999976;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" + id="rect11528" + width="37.696587" + height="37.696587" + x="5.5973887" + y="4.7060070" + rx="4.2426391" + ry="4.2426391" /> + <g + id="g7537" + transform="matrix(1.0877527,0,0,1.0546916,5.8244947,11.835925)" + style="fill:#2e3436" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90"> + <path + sodipodi:nodetypes="ccsccccssccccsscccsssccc" + id="flowRoot7526" + d="M 24.337778,3 L 24.337778,3.5058593 C 23.59109,3.6243668 23.025904,3.8340022 22.642222,4.1347652 C 22.092573,4.5813972 21.605166,5.2649902 21.18,6.1855472 L 13.101888,21.96289 L 12.526333,21.96289 L 5.3444445,5.9804692 C 4.9399968,5.1601722 4.6548118,4.6588712 4.4888888,4.4765622 C 4.2296271,4.1940282 3.908146,3.9752782 3.5244444,3.8203122 C 3.1511096,3.6562682 2.642962,3.5514502 1.9999999,3.5058593 L 1.9999999,3 L 10.617778,3 L 10.617778,3.5058593 C 9.6429548,3.5879085 9.0103629,3.7337422 8.7199999,3.9433592 C 8.4296229,4.1530122 8.2844379,4.4218922 8.2844445,4.7500002 C 8.2844379,5.2057452 8.5229562,5.9166822 9,6.8828122 L 13.646333,17.751953 L 19.344445,7.0195312 C 19.831833,5.9622552 20.075537,5.2285322 20.075556,4.8183592 C 20.075537,4.5540532 19.925168,4.3034022 19.624445,4.0664062 C 19.323686,3.8203302 18.815538,3.6471532 18.1,3.546875 C 18.048132,3.5377784 17.959984,3.5241065 17.835556,3.5058593 L 17.835556,3 L 24.337778,3" + style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:Times New Roman" /> + <path + style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:Times New Roman" + d="M 32.337778,3 L 32.337778,3.5058593 C 31.59109,3.6243668 31.025904,3.8340022 30.642222,4.1347652 C 30.092573,4.5813972 29.605166,5.2649902 29.18,6.1855472 L 21.822222,21.96289 L 21.246667,21.96289 L 13.344445,5.9804692 C 12.939997,5.1601722 12.654812,4.6588712 12.488889,4.4765622 C 12.229627,4.1940282 11.908146,3.9752782 11.524444,3.8203122 C 11.15111,3.6562682 10.642962,3.5514502 10,3.5058593 L 10,3 L 18.617778,3 L 18.617778,3.5058593 C 17.642955,3.5879085 17.010363,3.7337422 16.72,3.9433592 C 16.429623,4.1530122 16.284438,4.4218922 16.284445,4.7500002 C 16.284438,5.2057452 16.522956,5.9166822 17,6.8828122 L 22.366667,17.751953 L 27.344445,7.0195312 C 27.831833,5.9622552 28.075537,5.2285322 28.075556,4.8183592 C 28.075537,4.5540532 27.925168,4.3034022 27.624445,4.0664062 C 27.323686,3.8203302 26.815538,3.6471532 26.1,3.546875 C 26.048132,3.5377784 25.959984,3.5241065 25.835556,3.5058593 L 25.835556,3 L 32.337778,3" + id="path7535" + sodipodi:nodetypes="ccsccccssccccsscccsssccc" /> + </g> + </g> +</svg> diff --git a/icons/map-icon-croseE.svg b/icons/map-icon-croseE.svg new file mode 100644 index 0000000..907247e --- /dev/null +++ b/icons/map-icon-croseE.svg @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [ + <!ENTITY stroke_color "#231F20"> + <!ENTITY fill_color "#FFFFFF"> +]> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + width="28px" height="84.5px" viewBox="0 0 28 84.5" enable-background="new 0 0 28 84.5" xml:space="preserve"> + +<g> + <polygon fill="&fill_color;" stroke="&stroke_color;" stroke-width="3.5" points="25.8,42.5 1.8,78.9 1.8,42.5 1.8,5.9 "/> + <polygon fill="&stroke_color;" stroke="&stroke_color;" stroke-width="3.5" points="1.8,44.3 1.8,77.9 21.8,44.3 "/> +</g> +</svg> diff --git a/icons/map-icon-croseN.svg b/icons/map-icon-croseN.svg new file mode 100644 index 0000000..3b2bbaf --- /dev/null +++ b/icons/map-icon-croseN.svg @@ -0,0 +1,12 @@ +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [ + <!ENTITY stroke_color "#010101"> + <!ENTITY fill_color "#FFFFFF"> +]> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + width="84.5px" height="28px" viewBox="0 0 84.5 28" enable-background="new 0 0 84.5 28" xml:space="preserve"> + +<g> + <polygon fill="&fill_color;" stroke="&stroke_color;" stroke-width="3.5" points="42.5,2.1 78.9,26.1 42.5,26.1 5.9,26.1 "/> + <polygon fill="&stroke_color;" stroke="&stroke_color;" stroke-width="3.5" points="44.3,26.1 77.9,26.1 44.3,6.1 "/> +</g> +</svg> diff --git a/icons/map-icon-croseS.svg b/icons/map-icon-croseS.svg new file mode 100644 index 0000000..3d9354d --- /dev/null +++ b/icons/map-icon-croseS.svg @@ -0,0 +1,13 @@ +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [ + <!ENTITY stroke_color "#010101"> + <!ENTITY fill_color "#FFFFFF"> +]> + +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + width="84.5px" height="28px" viewBox="0 0 84.5 28" enable-background="new 0 0 84.5 28" xml:space="preserve"> + +<g> + <polygon fill="&fill_color;" stroke="&stroke_color;" stroke-width="3.5" points="42.2,25.8 5.8,1.8 42.2,1.8 78.8,1.8 "/> + <polygon fill="&stroke_color;" stroke="&stroke_color;" stroke-width="3.5" points="40.4,1.8 6.8,1.8 40.4,21.8 "/> +</g> +</svg> diff --git a/icons/map-icon-croseW.svg b/icons/map-icon-croseW.svg new file mode 100644 index 0000000..714497a --- /dev/null +++ b/icons/map-icon-croseW.svg @@ -0,0 +1,12 @@ +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [ + <!ENTITY stroke_color "#010101"> + <!ENTITY fill_color "#FFFFFF"> +]> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + width="28px" height="84.5px" viewBox="0 0 28 84.5" enable-background="new 0 0 28 84.5" xml:space="preserve"> + +<g> + <polygon fill="&fill_color;" stroke="&stroke_color;" stroke-width="3.5" points="2.1,42.2 26.1,5.8 26.1,42.2 26.1,78.8 "/> + <polygon fill="&stroke_color;" stroke="&stroke_color;" stroke-width="3.5" points="26.1,40.4 26.1,6.8 6,40.4 "/> +</g> +</svg> diff --git a/icons/map-icon-zoomIn.svg b/icons/map-icon-zoomIn.svg new file mode 100644 index 0000000..6c139f4 --- /dev/null +++ b/icons/map-icon-zoomIn.svg @@ -0,0 +1,95 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="Layer_5" + x="0px" + y="0px" + width="74.5px" + height="74px" + viewBox="0 0 74.5 74" + enable-background="new 0 0 74.5 74" + xml:space="preserve" + sodipodi:version="0.32" + inkscape:version="0.46" + sodipodi:docname="map-icon-zoomIn.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata + id="metadata16"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs + id="defs14"><inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 37 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="74.5 : 37 : 1" + inkscape:persp3d-origin="37.25 : 24.666667 : 1" + id="perspective18" /> + + + + + + </defs><sodipodi:namedview + inkscape:window-height="718" + inkscape:window-width="1366" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + guidetolerance="10.0" + gridtolerance="10.0" + objecttolerance="10.0" + borderopacity="1.0" + bordercolor="#666666" + pagecolor="#ffffff" + id="base" + showgrid="false" + inkscape:zoom="6.2432432" + inkscape:cx="37.25" + inkscape:cy="24.186147" + inkscape:window-x="-8" + inkscape:window-y="-8" + inkscape:current-layer="Layer_5" /> +<circle + sodipodi:ry="30" + sodipodi:rx="30" + sodipodi:cy="37.18" + sodipodi:cx="37.026001" + id="circle5" + r="30" + cy="37.18" + cx="37.026001" /> +<path + sodipodi:type="arc" + style="fill:none;stroke:#0000ff;stroke-width:6.53190851;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path2399" + sodipodi:cx="42.365803" + sodipodi:cy="28.190475" + sodipodi:rx="15.937229" + sodipodi:ry="17.619047" + d="M 58.303032,28.190475 A 15.937229,17.619047 0 1 1 26.428574,28.190475 A 15.937229,17.619047 0 1 1 58.303032,28.190475 z" + transform="matrix(1.2877593,0,0,1.1648369,-13.31237,-0.2420693)" /><rect + style="fill:#0000ff;fill-opacity:1;stroke:#0000ff;stroke-width:10.37449551;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3175" + width="1.2975725" + height="9.29566" + x="54.576096" + y="29.742977" + transform="matrix(0.8590348,0.5119173,-0.6668522,0.74519,0,0)" /><line + x1="41.510841" + y1="14.695152" + x2="41.510841" + y2="50.695152" + id="line9" + style="fill:none;stroke:#ffffff;stroke-width:4" /><line + x1="58.645912" + y1="33.015495" + x2="24.375782" + y2="33.015495" + id="line11" + style="fill:none;stroke:#ffffff;stroke-width:3.90271306" /></svg>
\ No newline at end of file diff --git a/icons/map-icon-zoomOut.svg b/icons/map-icon-zoomOut.svg new file mode 100644 index 0000000..712f350 --- /dev/null +++ b/icons/map-icon-zoomOut.svg @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948) --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg version="1.1" id="Layer_5" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + width="74.5px" height="74px" viewBox="0 0 74.5 74" enable-background="new 0 0 74.5 74" xml:space="preserve"> +<g> + <circle cx="37.026" cy="37.18" r="30"/> + <g> + <line fill="none" stroke="#FFFFFF" stroke-width="4" x1="55.026" y1="37.18" x2="19.026" y2="37.18"/> + </g> +</g> +</svg> diff --git a/icons/measure-icon.svg b/icons/measure-icon.svg new file mode 100644 index 0000000..cd21013 --- /dev/null +++ b/icons/measure-icon.svg @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [ + <!ENTITY fill_color "#AAAAAA"> + <!ENTITY stroke_color "#000000"> +]> +<svg xmlns="http://www.w3.org/2000/svg" width="45" height="45"> + <rect x="13" y="3" width="20" height="40" style="fill:&fill_color;;stroke:&stroke_color;;stroke-width:3.0"/> + <line y1="13" y2="13" x1="25" x2="33" style="fill:&fill_color;;stroke:&stroke_color;;stroke-width:3.0"/> + <line y1="23" y2="23" x1="25" x2="33" style="fill:&fill_color;;stroke:&stroke_color;;stroke-width:3.0"/> + <line y1="33" y2="33" x1="25" x2="33" style="fill:&fill_color;;stroke:&stroke_color;;stroke-width:3.0"/> +</svg> diff --git a/icons/panoramio.svg b/icons/panoramio.svg new file mode 100644 index 0000000..3d46175 --- /dev/null +++ b/icons/panoramio.svg @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [ + <!ENTITY ns_svg "http://www.w3.org/2000/svg"> + <!ENTITY ns_xlink "http://www.w3.org/1999/xlink"> +]> +<svg version="1.1" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="32" height="27.2" viewBox="0 0 32 27.2" + style="overflow:visible;enable-background:new 0 0 32 27.2;" xml:space="preserve"> +<rect y="1.6" width="32" height="25.6"/> +<rect x="1.6" width="1.6" height="2.6"/> +<rect x="8" width="1.6" height="2.9"/> +<rect x="1.6" y="3.2" style="fill:#FFFFFF;" width="8" height="4.8"/> +<rect x="20.8" y="3.2" style="fill:#FFFFFF;" width="8" height="4.8"/> +<rect x="9.4" y="4.8" style="fill:#FFFFFF;" width="12.1" height="1.6"/> +<path style="fill:none;stroke:#FFFFFF;stroke-width:1.6;" d="M8,15.2c0,4,3.2,7.2,7.2,7.2c4,0,7.2-3.2,7.2-7.2c0-4-3.2-7.2-7.2-7.2 + C11.2,8,8,11.2,8,15.2z"/> +<g> + <path style="fill:#FFFFFF;" d="M10.4,15.2c0,2.6,2.2,4.8,4.8,4.8c2.6,0,4.8-2.2,4.8-4.8s-2.2-4.8-4.8-4.8 + C12.6,10.4,10.4,12.6,10.4,15.2z"/> + <path d="M15.2,9.6c-3.1,0-5.6,2.5-5.6,5.6c0,3.1,2.5,5.6,5.6,5.6c3.1,0,5.6-2.5,5.6-5.6C20.8,12.1,18.3,9.6,15.2,9.6L15.2,9.6z + M11.2,15.2c0-2.2,1.8-4,4-4c2.2,0,4,1.8,4,4l0,0l0,0c0,2.2-1.8,4-4,4C13,19.2,11.2,17.4,11.2,15.2L11.2,15.2L11.2,15.2z"/> + <path d="M15.2,9.6c-3.1,0-5.6,2.5-5.6,5.6c0,3.1,2.5,5.6,5.6,5.6c3.1,0,5.6-2.5,5.6-5.6C20.8,12.1,18.3,9.6,15.2,9.6L15.2,9.6z + M11.2,15.2c0-2.2,1.8-4,4-4c2.2,0,4,1.8,4,4l0,0l0,0c0,2.2-1.8,4-4,4C13,19.2,11.2,17.4,11.2,15.2L11.2,15.2L11.2,15.2z"/> +</g> +</svg> diff --git a/icons/save-search.svg b/icons/save-search.svg new file mode 100644 index 0000000..22b18bf --- /dev/null +++ b/icons/save-search.svg @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="Layer_1" + x="0px" + y="0px" + width="76px" + height="76px" + viewBox="0 0 76 76" + enable-background="new 0 0 76 76" + xml:space="preserve" + sodipodi:version="0.32" + inkscape:version="0.45.1" + sodipodi:docname="save-search.svg" + sodipodi:docbase="/root/Desktop" + inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata + id="metadata2230"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs + id="defs2228" /><sodipodi:namedview + inkscape:window-height="622" + inkscape:window-width="872" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + guidetolerance="10.0" + gridtolerance="10.0" + objecttolerance="10.0" + borderopacity="1.0" + bordercolor="#666666" + pagecolor="#ffffff" + id="base" + inkscape:zoom="5.3552632" + inkscape:cx="38" + inkscape:cy="38" + inkscape:window-x="127" + inkscape:window-y="103" + inkscape:current-layer="Layer_1" /> +<g + id="g2221"> + <path + d="M75.946,56.313c0,10.692-8.748,19.44-19.44,19.44H20.053c-10.692,0-19.44-8.748-19.44-19.44v-36.12 c0-10.692,8.748-19.44,19.44-19.44h36.453c10.692,0,19.44,8.748,19.44,19.44V56.313z" + id="path2223" /> +</g> + +<g + display="block" + id="share-link" + transform="matrix(1.2,0,0,1.2,5.6048,4.5697942)" + style="display:block"> + <polygon + display="inline" + points="27.5,7.266 34.074,20.588 48.774,22.723 38.138,33.092 40.647,47.734 27.5,40.82 14.353,47.734 16.862,33.092 6.226,22.723 20.926,20.588 27.5,7.266 " + id="polygon5" + style="fill:#ffffff;stroke:#010101;stroke-width:3.5;display:inline" /> +</g></svg>
\ No newline at end of file diff --git a/icons/static-icon.svg b/icons/static-icon.svg new file mode 100644 index 0000000..2bf143b --- /dev/null +++ b/icons/static-icon.svg @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"[ + <!ENTITY stroke_color "#FFFFFF"> + <!ENTITY fill_color "#010101"> +]> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + width="74.5px" height="74px" viewBox="0 0 74.5 74" enable-background="new 0 0 74.5 74" xml:space="preserve"> +<g> + <line fill="none" stroke="&stroke_color;" stroke-width="3.5" x1="37.124" y1="13.641" x2="37.124" y2="23.035"/> + <path fill="none" stroke="&stroke_color;" stroke-width="3.5" d="M43.213,29.176c0,3.406-2.762,6.168-6.166,6.168 + c-3.406,0-6.167-2.762-6.167-6.168c0-3.404,2.761-6.141,6.167-6.141C40.451,23.035,43.213,25.771,43.213,29.176z M21.735,59.275 + L34.298,34.5"/> + <line fill="none" stroke="&stroke_color;" stroke-width="3.5" x1="27.88" y1="47.344" x2="54.881" y2="47.344"/> + <line fill="none" stroke="&stroke_color;" stroke-width="3.5" x1="39.949" y1="34.434" x2="52.546" y2="59.275"/> +</g> +</svg> diff --git a/icons/tool-polygon.svg b/icons/tool-polygon.svg new file mode 100644 index 0000000..0c8fee6 --- /dev/null +++ b/icons/tool-polygon.svg @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + x="0px" + y="0px" + width="55px" + height="55px" + viewBox="0 0 55 55" + enable-background="new 0 0 55 55" + xml:space="preserve" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.45" + sodipodi:docname="tool-shape-polygon.svg" + sodipodi:docbase="/home/joy/oficina_sugar/oficina/icons" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + sodipodi:modified="true"><metadata + id="metadata10"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs + id="defs8" /><sodipodi:namedview + inkscape:window-height="941" + inkscape:window-width="1269" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + guidetolerance="10.0" + gridtolerance="10.0" + objecttolerance="10.0" + borderopacity="1.0" + bordercolor="#666666" + pagecolor="#ffffff" + id="base" + inkscape:zoom="6.8909091" + inkscape:cx="27.5" + inkscape:cy="27.5" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:current-layer="svg2" /> + +<g + id="Polygon" + style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"> + <polygon + display="inline" + fill="#FFFFFF" + points="16.834,46.58 5.83,27.522 16.834,8.464 38.841,8.464 49.844,27.522 38.841,46.58 " + id="polygon5" + style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-opacity:1" /> +</g> + +</svg>
\ No newline at end of file diff --git a/icons/tool-shape-line.svg b/icons/tool-shape-line.svg new file mode 100644 index 0000000..0bf4d8e --- /dev/null +++ b/icons/tool-shape-line.svg @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948) --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="55px" + height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve"> + +<g id="Line" > + <line display="inline" fill="none" stroke="#FFFFFF" stroke-width="2.25" x1="8.708" y1="47.167" x2="48.042" y2="7.833"/> +</g> + +</svg> diff --git a/icons/topo-icon.svg b/icons/topo-icon.svg new file mode 100644 index 0000000..18a25d6 --- /dev/null +++ b/icons/topo-icon.svg @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948) --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + width="75.667px" height="75.333px" viewBox="0 0 75.667 75.333" enable-background="new 0 0 75.667 75.333" xml:space="preserve"> +<g> + <path d="M75.828,55.925c0,10.692-8.748,19.44-19.439,19.44H19.935c-10.692,0-19.44-8.748-19.44-19.44V19.806 + c0-10.692,8.748-19.44,19.44-19.44h36.454c10.691,0,19.439,8.748,19.439,19.44V55.925z"/> +</g> +<g> + <path fill="none" stroke="#FFFFFF" stroke-width="3" stroke-linecap="round" d="M44.936,43.372 + c-2.121,4.811-6.641,7.477-10.094,5.953c-3.454-1.522,1.952-3.797,4.073-8.608c2.121-4.811,0.156-10.337,3.609-8.813 + C45.979,33.427,47.058,38.562,44.936,43.372z"/> + <path fill="none" stroke="#FFFFFF" stroke-width="3" stroke-linecap="round" d="M50.594,45.6 + c-3.481,7.896-13.633,11.064-22.676,7.077c-9.041-3.987,3.43-6.133,6.911-14.028c3.481-7.896-3.344-18.551,5.696-14.563 + C49.568,28.072,54.075,37.705,50.594,45.6z"/> + <path fill="none" stroke="#FFFFFF" stroke-width="3" stroke-linecap="round" d="M58.834,49.5 + c-4.625,10.486-21.741,13.091-38.235,5.818c-16.491-7.272,4.856-8.013,9.479-18.498s-9.226-26.746,7.265-19.474 + C53.837,24.619,63.457,39.015,58.834,49.5z"/> +</g> +</svg> diff --git a/icons/web-icon.svg b/icons/web-icon.svg new file mode 100644 index 0000000..d5e7e59 --- /dev/null +++ b/icons/web-icon.svg @@ -0,0 +1,14 @@ +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [ + <!ENTITY stroke_color "#010101"> + <!ENTITY fill_color "#FFFFFF"> +]><svg enable-background="new 0 0 55 55" height="55px" version="1.1" viewBox="0 0 55 55" width="55px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="0px"><g display="block" id="activity-browse"> + <circle cx="27.375" cy="27.5" display="inline" fill="&fill_color;" r="19.903" stroke="&stroke_color;" stroke-width="3.5"/> + <g display="inline"> + <path d="M27.376,7.598c0,0-11.205,8.394-11.205,19.976 c0,11.583,11.205,19.829,11.205,19.829" fill="&fill_color;" stroke="&stroke_color;" stroke-width="3.5"/> + <path d="M27.376,7.598c0,0,11.066,9.141,11.066,19.976 c0,10.839-11.066,19.829-11.066,19.829" fill="&fill_color;" stroke="&stroke_color;" stroke-width="3.5"/> + <line fill="&fill_color;" stroke="&stroke_color;" stroke-width="3.5" x1="27.376" x2="27.376" y1="7.598" y2="47.402"/> + <line fill="&fill_color;" stroke="&stroke_color;" stroke-width="3.5" x1="27.376" x2="27.376" y1="7.598" y2="47.402"/> + <line fill="&fill_color;" stroke="&stroke_color;" stroke-width="3.5" x1="27.376" x2="27.376" y1="7.598" y2="47.402"/> + <line fill="&fill_color;" stroke="&stroke_color;" stroke-width="3.5" x1="7.472" x2="47.278" y1="27.5" y2="27.5"/> + </g> +</g></svg>
\ No newline at end of file diff --git a/icons/wikimapia.svg b/icons/wikimapia.svg new file mode 100644 index 0000000..0101988 --- /dev/null +++ b/icons/wikimapia.svg @@ -0,0 +1,100 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.0" + id="Layer_1" + width="48" + height="48.119" + viewBox="0 0 48 48.119" + overflow="visible" + enable-background="new 0 0 48 48.119" + xml:space="preserve" + sodipodi:version="0.32" + inkscape:version="0.46" + sodipodi:docname="activity-maptech.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata + id="metadata2471"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs + id="defs2469"><inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 24.0595 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="48 : 24.0595 : 1" + inkscape:persp3d-origin="24 : 16.039666 : 1" + id="perspective2473" /></defs><sodipodi:namedview + inkscape:window-height="669" + inkscape:window-width="779" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + guidetolerance="10.0" + gridtolerance="10.0" + objecttolerance="10.0" + borderopacity="1.0" + bordercolor="#666666" + pagecolor="#ffffff" + id="base" + showgrid="false" + inkscape:zoom="11.333333" + inkscape:cx="24" + inkscape:cy="23.70819" + inkscape:window-x="23" + inkscape:window-y="23" + inkscape:current-layer="Layer_1" /> + + + + + +<path + sodipodi:type="arc" + style="fill:#ffffff;fill-rule:evenodd;stroke:#808080;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="path2475" + sodipodi:cx="36.037174" + sodipodi:cy="16.300051" + sodipodi:rx="8.748909" + sodipodi:ry="8.592679" + d="M 44.786083,16.300051 A 8.748909,8.592679 0 1 1 27.288265,16.300051 A 8.748909,8.592679 0 1 1 44.786083,16.300051 z" /><path + sodipodi:type="arc" + style="fill:#666666;fill-rule:evenodd;stroke:#4d4d4d;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="path2483" + sodipodi:cx="23.122116" + sodipodi:cy="37.703632" + sodipodi:rx="12.915056" + sodipodi:ry="2.9163029" + d="M 36.037172,37.703632 A 12.915056,2.9163029 0 1 1 10.20706,37.703632 A 12.915056,2.9163029 0 1 1 36.037172,37.703632 z" + transform="translate(6.6817539,5.8394479)" /><rect + style="fill:#f9f9f9;stroke:#999999;stroke-width:1.05382084999999990" + id="rect2485" + width="9.4241638" + height="34.898167" + x="3.1515205" + y="1.9016767" /><rect + style="fill:#f9f9f9;stroke:#999999;stroke-width:1.07296026000000010" + id="rect2487" + width="7.5302582" + height="26.634966" + x="12.951536" + y="10.243541" /><rect + style="fill:#f9f9f9;stroke:#b3b3b3;stroke-width:1.40962899000000010" + id="rect2489" + width="5.9437451" + height="15.942498" + x="21.139704" + y="20.855909" /><path + style="fill:none;fill-rule:evenodd;stroke:#999999;stroke-width:1.19097257000000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 30.800071,23.217604 L 29.338108,42.372851 L 36.310546,25.817245 L 30.800071,23.217604 z" + id="path2495" /><rect + style="fill:#ffffff;stroke:#ffffff" + id="rect2533" + width="3.2647059" + height="4.2352943" + x="31.941177" + y="21.295471" /></svg>
\ No newline at end of file diff --git a/idlethread.py b/idlethread.py new file mode 100644 index 0000000..7dc424e --- /dev/null +++ b/idlethread.py @@ -0,0 +1,175 @@ +from __future__ import generators + +import gobject +import time +import traceback + +class GIdleThread(object): + """This is a pseudo-"thread" for use with the GTK+ main loop. + + This class does act a bit like a thread, all code is executed in + the callers thread though. The provided function should be a generator + (or iterator). + + It can be started with start(). While the "thread" is running is_alive() + can be called to see if it's alive. wait([timeout]) will wait till the + generator is finished, or timeout seconds. + + If an exception is raised from within the generator, it is stored in + the error property. Execution of the generator is finished. + + Note that this routine runs in the current thread, so there is no need + for nasty locking schemes. + + Example (runs a counter through the GLib main loop routine): + >>> def counter(max): for x in xrange(max): yield x + >>> t = GIdleThread(counter(123)) + >>> t.start() + >>> while gen.is_alive(): + ... main.iteration(False) + """ + + def __init__(self, generator, queue=None): + assert hasattr(generator, 'next'), 'The generator should be an iterator' + self._generator = generator + self._queue = queue + self._idle_id = 0 + self._error = None + + def start(self, priority=gobject.PRIORITY_LOW): + """Start the generator. Default priority is low, so screen updates + will be allowed to happen. + """ + idle_id = gobject.idle_add(self.__generator_executer, + priority=priority) + self._idle_id = idle_id + return idle_id + + def wait(self, timeout=0): + """Wait until the corouine is finished or return after timeout seconds. + This is achieved by running the GTK+ main loop. + """ + clock = time.clock + start_time = clock() + main = gobject.main_context_default() + while self.is_alive(): + main.iteration(False) + if timeout and (clock() - start_time >= timeout): + return + + def interrupt(self): + """Force the generator to stop running. + """ + if self.is_alive(): + gobject.source_remove(self._idle_id) + self._idle_id = 0 + + def is_alive(self): + """Returns True if the generator is still running. + """ + return self._idle_id != 0 + + error = property(lambda self: self._error, + doc="Return a possible exception that had occured "\ + "during execution of the generator") + + def __generator_executer(self): + try: + result = self._generator.next() + if self._queue: + try: + self._queue.put(result) + except QueueFull: + self.wait(0.5) + # If this doesn't work... + self._queue.put(result) + return True + except StopIteration: + self._idle_id = 0 + return False + except Exception, e: + self._error = e + traceback.print_exc() + self._idle_id = 0 + return False + + +class QueueEmpty(Exception): + """Exception raised whenever the queue is empty and someone tries to fetch + a value. + """ + pass + + +class QueueFull(Exception): + """Exception raised when the queue is full and the oldest item may not be + disposed. + """ + pass + + +class Queue(object): + """A FIFO queue. If the queue has a max size, the oldest item on the + queue is dropped if that size id exceeded. + """ + + def __init__(self, size=0, dispose_oldest=True): + self._queue = [] + self._size = size + self._dispose_oldest = dispose_oldest + + def put(self, item): + """Put item on the queue. If the queue size is limited ... + """ + if self._size > 0 and len(self._queue) >= self._size: + if self._dispose_oldest: + self.get() + else: + raise QueueFull + + self._queue.insert(0, item) + + def get(self): + """Get the oldest item off the queue. + QueueEmpty is raised if no items are left on the queue. + """ + try: + return self._queue.pop() + except IndexError: + raise QueueEmpty + + +if __name__ == '__main__': + def counter(max): + for i in range(max): + yield i + + def shower(queue): + # Never stop reading the queue: + while True: + try: + cnt = queue.get() + print 'cnt =', cnt + except QueueEmpty: + pass + yield None + + print 'Test 1: (should print range 0..22)' + queue = Queue() + c = GIdleThread(counter(23), queue) + s = GIdleThread(shower(queue)) + + main = gobject.main_context_default() + c.start() + s.start() + s.wait(2) + + print 'Test 2: (should only print 22)' + queue = Queue(size=1) + c = GIdleThread(counter(23), queue) + s = GIdleThread(shower(queue)) + + main = gobject.main_context_default() + c.start(priority=gobject.PRIORITY_DEFAULT) + s.start() + s.wait(3) diff --git a/instance.py b/instance.py new file mode 100644 index 0000000..95fb932 --- /dev/null +++ b/instance.py @@ -0,0 +1,45 @@ +import os + +from sugar import profile +from sugar import util +from sugar.activity import activity +import shutil + +from color import Color + +class Instance: + key = profile.get_pubkey() + #joyride ... + #keyHash = util.sha_data(key) + #8.2... + #keyHash = util._sha_data(key) + #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() ) + + instanceId = None + instancePath = None + dataPath = None + + def __init__(self, ca): + self.__class__.instanceId = ca._activity_id + + self.__class__.instancePath = os.path.join(ca.get_activity_root(), "instance") + recreateTmp() + + 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) + + +def recreateData(): + if (not os.path.exists(Instance.dataPath)): + os.makedirs(Instance.dataPath)
\ No newline at end of file diff --git a/locale/es/LC_MESSAGES/org.laptop.map.mo b/locale/es/LC_MESSAGES/org.laptop.map.mo Binary files differnew file mode 100644 index 0000000..ea90e33 --- /dev/null +++ b/locale/es/LC_MESSAGES/org.laptop.map.mo diff --git a/locale/es/activity.linfo b/locale/es/activity.linfo new file mode 100644 index 0000000..b8f1dd2 --- /dev/null +++ b/locale/es/activity.linfo @@ -0,0 +1,2 @@ +[Activity] +name = Mapa diff --git a/locale/mn/LC_MESSAGES/org.laptop.map.mo b/locale/mn/LC_MESSAGES/org.laptop.map.mo Binary files differnew file mode 100644 index 0000000..2ef674c --- /dev/null +++ b/locale/mn/LC_MESSAGES/org.laptop.map.mo diff --git a/locale/mn/activity.linfo b/locale/mn/activity.linfo new file mode 100644 index 0000000..eadffb2 --- /dev/null +++ b/locale/mn/activity.linfo @@ -0,0 +1,2 @@ +[Activity] +name = Map diff --git a/logic.py b/logic.py new file mode 100644 index 0000000..820e306 --- /dev/null +++ b/logic.py @@ -0,0 +1,359 @@ +# 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. + + +from result import ServerResult +from constants import Constants +from instance import Instance + +from threading import Thread +import threading +import os +import gobject +import time +import gtk +import urllib + +class ServerLogic: + def __init__(self, ca): + self.ca = ca + self.proceedTxt = "" + self.proceedHeaders = [] + self.cond = ca.cond + self.addKMLSet=0 + + def doServerLogic(self, url, path, params): + self.ca.remoteServerActive( True ) + r = ServerResult() + fileName = path[len(path)-1] + + if (fileName == "comet.js"): + + #clear... + self.proceedHeaders = [] + self.proceedTxt = "" + + #wait... + self.cond.acquire() + self.cond.wait() + self.cond.release() + + #prep response... + for h in range( len(self.proceedHeaders) ): + r.headers.append( self.proceedHeaders[h] ) + #r.txt = ""+self.proceedTxt + #self.ca.browser.load_uri("javascript:"+r.txt+"void(0);") + + else: + kickThroughComet = True + + if (fileName =="mediaQuery.js"): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + self.proceedTxt = self.ca.m.getMediaResponse( params[0][1], params[1][1], params[2][1], params[3][1] ) + + elif (fileName == "showMedia.js"): + id = params[0][1] + locX = params[1][1] + locY = params[2][1] + up = params[3][1] + rt = params[4][1] + gobject.idle_add(self.ca.showMedia, id, locX, locY, up=='true', rt=='true') + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + + elif (fileName == "placeAddMedia.js"): + lat = params[0][1] + lng = params[1][1] + gobject.idle_add(self.ca.placeAddMedia, lat, lng) + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + kickThroughComet = False + + elif (fileName == "hideMedia.js"): + gobject.idle_add(self.ca.hideMedia) + + elif (fileName == "getImage.js"): + localfile = open(os.path.join(Instance.instancePath, params[0][1]), 'r') + localdata = localfile.read() + localfile.close() + + #one day we might need to kick you through comet as a base64'd image. + r.txt = localdata + r.headers.append( ("Content-type", "image/jpeg") ) + kickThroughComet = False + + elif (fileName == "updateLocation.js"): + lat = params[0][1] + lng = params[1][1] + zoom = params[2][1] + x = params[3][1] + y = params[4][1] + gobject.idle_add(self.ca.updateMapMetaData,lat,lng,zoom,x,y) + + elif (fileName == "addSavedMap.js"): + # allow internet to send an array of SavedMaps back to map.py + latitudes = params[0][1] + longitudes = params[1][1] + zooms = params[2][1] + notes = params[3][1] + gobject.idle_add(self.ca.addSavedMap,latitudes,longitudes,zooms,urllib.unquote(notes),True) + + elif (fileName == "addInfoMarker.js"): + lat = params[0][1] + lng = params[1][1] + info = params[2][1] + icon = params[3][1] + if(params[4][1] == "True"): + isNew = True + gobject.idle_add(self.ca.cometLogic.forceupdate) + else: + isNew = False + gobject.idle_add(self.ca.addInfoMarker,lat,lng,info,icon,isNew) + + elif (fileName == "addLine.js"): + id = params[0][1] + color = params[1][1] + thickness = params[2][1] + pts = params[3][1] # send pts separated with | instead of , + gobject.idle_add(self.ca.addLine,id,color,thickness,pts,1) + + elif (fileName == "promptSearch.js"): + address = params[0][1] + time.sleep(0.5) + self.ca.preComet() + self.handleAddressUpdate(address+"+") + self.ca.postComet() + + #elif (fileName == "gotoMapV3.js"): + # button on static maps links to mapv3 + #self.ca.loadMapV3() + + if (kickThroughComet): + #not sure how & why this goes out, but it does. + self.cond.acquire() + self.cond.notifyAll() + self.cond.release() + time.sleep(.1) + + return r + + def handleAddressUpdate( self, address ): + findsrc="http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=" + urllib.quote(address) + findAddress = urllib.urlopen(findsrc).read() + + longname=findAddress[findAddress.find('long_name')+13:len(findAddress)] + longname=longname[0:longname.find('"')] + + findSW=findAddress[findAddress.find('southwest'):findAddress.find('northeast')].replace(" ","").replace('\n','') + swlat=findSW[findSW.find('lat')+5:findSW.find(',')] + swlng=findSW[findSW.find('lng')+5:findSW.find('}')] + + findNE=findAddress[findAddress.find('northeast'):len(findAddress)].replace(" ","").replace('\n','') + nelat=findNE[findNE.find('lat')+5:findNE.find(',')] + nelng=findNE[findNE.find('lng')+5:findNE.find('}')] + + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + #self.proceedTxt = "showInfo('" + swlat + "," + swlng + "," + nelat + "," + nelng + "');" + self.proceedTxt = "moveToAddress(" + swlat + "," + swlng + "," + nelat + "," + nelng + ",'" + longname + "');" + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + def forceupdate(self): + #self.ca.preComet() + + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + self.proceedTxt = "canvas.updateImg();" + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + #self.ca.postComet() + + def handleCompassUpdate( self, dir ): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + + if (dir == "e"): + self.proceedTxt = "dirEast();" + elif (dir == "w"): + self.proceedTxt = "dirWest();" + elif (dir == "n"): + self.proceedTxt = "dirNorth();" + elif (dir == "s"): + self.proceedTxt = "dirSouth();" + else: + # use this as a print warning window + self.proceedTxt = 'showInfo("' + dir + '");' + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + def handlePanoramio(self): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + self.proceedTxt = 'panoramio();' + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + def handleLocalWiki(self): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + self.proceedTxt = 'wikiloc();' + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + def handleWikiMapia(self): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + self.proceedTxt = 'wikimapia();' + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + def handleOlpcMAP(self): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + llc=[float(self.ca.NOW_MAP_CENTER_LAT),float(self.ca.NOW_MAP_CENTER_LNG)] + llz=float(self.ca.NOW_MAP_ZOOM) + lln=llc[0]+0.55618*0.75*(2**(9-llz)) + lle=llc[1]+0.98877*0.75*(2**(9-llz)) + lls=llc[0]-0.55618*0.75*(2**(9-llz)) + llw=llc[1]-0.98877*0.75*(2**(9-llz)) + findsrc="http://mapmeld.appspot.com/olpcMAP/kml?llregion="+str(lln)+","+str(lle)+","+str(lls)+","+str(llw) + self.ca.readKML(urllib.urlopen(findsrc)) + + def handleZoomUpdate( self, dir ): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + if (dir == "+"): + self.proceedTxt = "zoomIn();" + elif (dir == "-"): + self.proceedTxt = "zoomOut();" + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + def handleClear( self ): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + self.proceedTxt = "clear();" + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + def handlePreAdd( self ): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + self.proceedTxt = "preAddMedia();" + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + def handlePreAddInfo( self ): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + self.proceedTxt = "preAddInfo();" + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + def handlePostAdd( self, rec ): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + self.proceedTxt = "postAddMedia(" + rec.latitude + ", " + rec.longitude + ", '" + rec.getThumbUrl() + "', '" + rec.getThumbBasename() + "', '" + rec.tags + "');" + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + def handleDelete( self ): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + self.proceedTxt = "deleteMedia();" + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + # handle a map that was sent to us + def handleReceivedMap( self, lat, lng, zoom): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + self.proceedTxt = "setMap(" + lat + "," + lng + "," + zoom + ");" + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + def handleSavedMap( self, lat, lng, zoom, info ): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + if(info.find("Describe the map") != 0): + self.proceedTxt = "setMap2(" + lat + "," + lng + "," + zoom + ",'" + urllib.quote(info) + "');" + else: + self.proceedTxt = "setMap2(" + lat + "," + lng + "," + zoom + ",'');" + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + # handle a marker that was sent to us + def handleAddMarker( self, lat, lng, pixString, icon ): + if(self.addKMLSet < 1): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + self.proceedTxt = "" + if(self.addKMLSet == -1): + self.addKMLSet = 1 + self.proceedTxt = self.proceedTxt + "addInfoMarker(" + lat + ", " + lng + ", '" + pixString.replace("'",'"') + "', '" + icon + "',false);" + #self.proceedTxt = self.proceedTxt + "addInfoMarker(" + lat + ", " + lng + ", '"+pixString.replace("'",'"')+"', 'http://mapmeld.appspot.com/xo-red.png',false);" + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + def startKML( self, tellOthers ): + self.addKMLSet = -1 + if((self.ca.maptube is not None) and (tellOthers == 1)): + self.ca.sendStartKML() + + def handleEndKML( self, tellOthers ): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + self.proceedTxt = self.proceedTxt + "canvas.updateImg();" + self.addKMLSet = 0 + if((self.ca.maptube is not None) and (tellOthers == 1)): + self.ca.sendEndKML() + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + def lineMode(self, type): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + self.proceedTxt = "lineMode('" + type + "');" + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + def handleLine(self,id,color,thickness,pts): + if(self.addKMLSet < 1): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + self.proceedTxt = "" + if(self.addKMLSet == -1): + self.addKMLSet = 1 + self.proceedTxt = self.proceedTxt + "addLine('" + id + "','" + color + "','" + thickness + "','" + pts + "');" + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + # handle start of measure tool + def handleMeasure(self): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + self.proceedTxt = "measure();" + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") + + def handleTagSearch( self, tags ): + self.proceedHeaders.append( ("Content-type", "text/javascript") ) + self.proceedTxt = "filterTags('" + tags + "');" + self.ca.ajaxServer.stop() + self.ca.cometServer.stop() + self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);") diff --git a/manifest b/manifest new file mode 100644 index 0000000..82cff9f --- /dev/null +++ b/manifest @@ -0,0 +1,43 @@ +_camera.c +logic.py +server.py +setup.py +idlethread.py +webviewer.py +NEWS +instance.py +constants.py +tray.py +_camera.so +recorded.py +model.py +gplay.py +savedmap.py +button.py +utils.py +p5.py +filepicker.py +result.py +color.py +serialize.py +map.py +_camera.o +photocanvas.py +activity/activity.info +activity/activity-map.svg +icons/map-icon-zoomIn.svg +icons/map-icon-croseS.svg +icons/map-icon-croseE.svg +icons/map-icon-croseW.svg +icons/add-icon.svg +icons/delete-icon.svg +icons/corner-info.svg +icons/map-icon-croseN.svg +icons/topo-icon.svg +icons/map-icon-zoomOut.svg +icons/save-search.svg +icons/web-icon.svg +icons/measure-icon.svg +icons/static-icon.svg +po/map.pot +Makefile diff --git a/map-activity.iml b/map-activity.iml new file mode 100644 index 0000000..4e07241 --- /dev/null +++ b/map-activity.iml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module version="4" relativePaths="true" type="JAVA_MODULE"> + <component name="ModuleRootManager" /> + <component name="NewModuleRootManager" inherit-compiler-output="true"> + <exclude-output /> + <content url="file://$MODULE_DIR$" /> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntryProperties /> + </component> +</module> + diff --git a/map-activity.ipr b/map-activity.ipr new file mode 100644 index 0000000..3e24b75 --- /dev/null +++ b/map-activity.ipr @@ -0,0 +1,286 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4" relativePaths="false"> + <component name="AntConfiguration"> + <defaultAnt bundledAnt="true" /> + </component> + <component name="BuildJarProjectSettings"> + <option name="BUILD_JARS_ON_MAKE" value="false" /> + </component> + <component name="CodeStyleProjectProfileManger"> + <option name="PROJECT_PROFILE" /> + <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" /> + </component> + <component name="CodeStyleSettingsManager"> + <option name="PER_PROJECT_SETTINGS" /> + <option name="USE_PER_PROJECT_SETTINGS" value="false" /> + </component> + <component name="CompilerConfiguration"> + <option name="DEFAULT_COMPILER" value="Javac" /> + <option name="DEPLOY_AFTER_MAKE" value="0" /> + <resourceExtensions> + <entry name=".+\.(properties|xml|html|dtd|tld)" /> + <entry name=".+\.(gif|png|jpeg|jpg)" /> + </resourceExtensions> + <wildcardResourcePatterns> + <entry name="?*.properties" /> + <entry name="?*.xml" /> + <entry name="?*.gif" /> + <entry name="?*.png" /> + <entry name="?*.jpeg" /> + <entry name="?*.jpg" /> + <entry name="?*.html" /> + <entry name="?*.dtd" /> + <entry name="?*.tld" /> + </wildcardResourcePatterns> + </component> + <component name="DataSourceManagerImpl" /> + <component name="DependenciesAnalyzeManager"> + <option name="myForwardDirection" value="false" /> + </component> + <component name="DependencyValidationManager" /> + <component name="EclipseCompilerSettings"> + <option name="DEBUGGING_INFO" value="true" /> + <option name="GENERATE_NO_WARNINGS" value="true" /> + <option name="DEPRECATION" value="false" /> + <option name="ADDITIONAL_OPTIONS_STRING" value="" /> + <option name="MAXIMUM_HEAP_SIZE" value="128" /> + </component> + <component name="EclipseEmbeddedCompilerSettings"> + <option name="DEBUGGING_INFO" value="true" /> + <option name="GENERATE_NO_WARNINGS" value="true" /> + <option name="DEPRECATION" value="false" /> + <option name="ADDITIONAL_OPTIONS_STRING" value="" /> + <option name="MAXIMUM_HEAP_SIZE" value="128" /> + </component> + <component name="EntryPointsManager"> + <entry_points /> + </component> + <component name="ExportToHTMLSettings"> + <option name="PRINT_LINE_NUMBERS" value="false" /> + <option name="OPEN_IN_BROWSER" value="false" /> + <option name="OUTPUT_DIRECTORY" /> + </component> + <component name="GUI Designer component loader factory" /> + <component name="IdProvider" IDEtalkID="473E4E27819B3CDE0F546064F2F319B7" /> + <component name="InspectionProjectProfileManager"> + <option name="PROJECT_PROFILE" value="Project Default" /> + <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" /> + <scopes /> + <profiles> + <profile version="1.0" is_locked="false"> + <option name="myName" value="Project Default" /> + <option name="myLocal" value="false" /> + <used_levels> + <error> + <option name="myName" value="ERROR" /> + <option name="myVal" value="400" /> + </error> + <warning> + <option name="myName" value="WARNING" /> + <option name="myVal" value="300" /> + </warning> + <information> + <option name="myName" value="INFO" /> + <option name="myVal" value="200" /> + </information> + <server> + <option name="myName" value="SERVER PROBLEM" /> + <option name="myVal" value="100" /> + </server> + </used_levels> + </profile> + </profiles> + </component> + <component name="JavacSettings"> + <option name="DEBUGGING_INFO" value="true" /> + <option name="GENERATE_NO_WARNINGS" value="false" /> + <option name="DEPRECATION" value="true" /> + <option name="ADDITIONAL_OPTIONS_STRING" value="" /> + <option name="MAXIMUM_HEAP_SIZE" value="128" /> + </component> + <component name="JavadocGenerationManager"> + <option name="OUTPUT_DIRECTORY" /> + <option name="OPTION_SCOPE" value="protected" /> + <option name="OPTION_HIERARCHY" value="true" /> + <option name="OPTION_NAVIGATOR" value="true" /> + <option name="OPTION_INDEX" value="true" /> + <option name="OPTION_SEPARATE_INDEX" value="true" /> + <option name="OPTION_DOCUMENT_TAG_USE" value="false" /> + <option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" /> + <option name="OPTION_DOCUMENT_TAG_VERSION" value="false" /> + <option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" /> + <option name="OPTION_DEPRECATED_LIST" value="true" /> + <option name="OTHER_OPTIONS" value="" /> + <option name="HEAP_SIZE" /> + <option name="LOCALE" /> + <option name="OPEN_IN_BROWSER" value="true" /> + </component> + <component name="JikesSettings"> + <option name="JIKES_PATH" value="" /> + <option name="DEBUGGING_INFO" value="true" /> + <option name="DEPRECATION" value="true" /> + <option name="GENERATE_NO_WARNINGS" value="false" /> + <option name="IS_EMACS_ERRORS_MODE" value="true" /> + <option name="ADDITIONAL_OPTIONS_STRING" value="" /> + </component> + <component name="LogConsolePreferences"> + <option name="FILTER_ERRORS" value="false" /> + <option name="FILTER_WARNINGS" value="false" /> + <option name="FILTER_INFO" value="true" /> + <option name="CUSTOM_FILTER" /> + </component> + <component name="Palette2"> + <group name="Swing"> + <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" /> + </item> + <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" /> + </item> + <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" /> + </item> + <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true"> + <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" /> + </item> + <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" /> + <initial-values> + <property name="text" value="Button" /> + </initial-values> + </item> + <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> + <initial-values> + <property name="text" value="RadioButton" /> + </initial-values> + </item> + <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> + <initial-values> + <property name="text" value="CheckBox" /> + </initial-values> + </item> + <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" /> + <initial-values> + <property name="text" value="Label" /> + </initial-values> + </item> + <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> + <preferred-size width="150" height="-1" /> + </default-constraints> + </item> + <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> + <preferred-size width="150" height="-1" /> + </default-constraints> + </item> + <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> + <preferred-size width="150" height="-1" /> + </default-constraints> + </item> + <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" /> + </item> + <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> + <preferred-size width="200" height="200" /> + </default-constraints> + </item> + <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> + <preferred-size width="200" height="200" /> + </default-constraints> + </item> + <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> + </item> + <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> + </item> + <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" /> + </item> + <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" /> + </item> + <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1"> + <preferred-size width="-1" height="20" /> + </default-constraints> + </item> + <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" /> + </item> + <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" /> + </item> + </group> + </component> + <component name="ProjectModuleManager"> + <modules> + <module fileurl="file://$PROJECT_DIR$/map-activity.iml" filepath="$PROJECT_DIR$/map-activity.iml" /> + </modules> + </component> + <component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" project-jdk-type="JavaSDK"> + <output url="file://$PROJECT_DIR$/classes" /> + </component> + <component name="ProjectRunConfigurationManager" /> + <component name="RmicSettings"> + <option name="IS_EANABLED" value="false" /> + <option name="DEBUGGING_INFO" value="true" /> + <option name="GENERATE_NO_WARNINGS" value="false" /> + <option name="GENERATE_IIOP_STUBS" value="false" /> + <option name="ADDITIONAL_OPTIONS_STRING" value="" /> + </component> + <component name="StarteamVcsAdapter" /> + <component name="VssVcs" /> + <component name="com.intellij.jsf.UserDefinedFacesConfigs"> + <option name="USER_DEFINED_CONFIGS"> + <value> + <list size="0" /> + </value> + </option> + </component> + <component name="libraryTable" /> + <component name="uidesigner-configuration"> + <option name="INSTRUMENT_CLASSES" value="true" /> + <option name="COPY_FORMS_RUNTIME_TO_OUTPUT" value="true" /> + <option name="DEFAULT_LAYOUT_MANAGER" value="GridLayoutManager" /> + </component> + <UsedPathMacros /> +</project> + diff --git a/map-activity.iws b/map-activity.iws new file mode 100644 index 0000000..76651af --- /dev/null +++ b/map-activity.iws @@ -0,0 +1,694 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4" relativePaths="false"> + <component name="BookmarkManager" /> + <component name="ChangeBrowserSettings"> + <option name="MAIN_SPLITTER_PROPORTION" value="0.3" /> + <option name="MESSAGES_SPLITTER_PROPORTION" value="0.8" /> + <option name="USE_DATE_BEFORE_FILTER" value="false" /> + <option name="USE_DATE_AFTER_FILTER" value="false" /> + <option name="USE_CHANGE_BEFORE_FILTER" value="false" /> + <option name="USE_CHANGE_AFTER_FILTER" value="false" /> + <option name="DATE_BEFORE" value="" /> + <option name="DATE_AFTER" value="" /> + <option name="CHANGE_BEFORE" value="" /> + <option name="CHANGE_AFTER" value="" /> + <option name="USE_USER_FILTER" value="false" /> + <option name="USER" value="" /> + </component> + <component name="ChangeListManager"> + <list default="true" name="Default" comment="" /> + </component> + <component name="ChangeListSynchronizer" /> + <component name="ChangesViewManager" flattened_view="true" /> + <component name="CheckinPanelState" /> + <component name="Commander"> + <leftPanel /> + <rightPanel /> + <splitter proportion="0.5" /> + </component> + <component name="CompilerWorkspaceConfiguration"> + <option name="COMPILE_IN_BACKGROUND" value="false" /> + <option name="AUTO_SHOW_ERRORS_IN_EDITOR" value="true" /> + <option name="CLOSE_MESSAGE_VIEW_IF_SUCCESS" value="true" /> + <option name="COMPILE_DEPENDENT_FILES" value="false" /> + <option name="CLEAR_OUTPUT_DIRECTORY" value="false" /> + <option name="ASSERT_NOT_NULL" value="true" /> + </component> + <component name="CoverageDataManager" /> + <component name="Cvs2Configuration"> + <option name="PRUNE_EMPTY_DIRECTORIES" value="true" /> + <option name="MERGING_MODE" value="0" /> + <option name="MERGE_WITH_BRANCH1_NAME" value="HEAD" /> + <option name="MERGE_WITH_BRANCH2_NAME" value="HEAD" /> + <option name="RESET_STICKY" value="false" /> + <option name="CREATE_NEW_DIRECTORIES" value="true" /> + <option name="DEFAULT_TEXT_FILE_SUBSTITUTION" value="kv" /> + <option name="PROCESS_UNKNOWN_FILES" value="false" /> + <option name="PROCESS_DELETED_FILES" value="false" /> + <option name="PROCESS_IGNORED_FILES" value="false" /> + <option name="RESERVED_EDIT" value="false" /> + <option name="CHECKOUT_DATE_OR_REVISION_SETTINGS"> + <value> + <option name="BRANCH" value="" /> + <option name="DATE" value="" /> + <option name="USE_BRANCH" value="false" /> + <option name="USE_DATE" value="false" /> + </value> + </option> + <option name="UPDATE_DATE_OR_REVISION_SETTINGS"> + <value> + <option name="BRANCH" value="" /> + <option name="DATE" value="" /> + <option name="USE_BRANCH" value="false" /> + <option name="USE_DATE" value="false" /> + </value> + </option> + <option name="SHOW_CHANGES_REVISION_SETTINGS"> + <value> + <option name="BRANCH" value="" /> + <option name="DATE" value="" /> + <option name="USE_BRANCH" value="false" /> + <option name="USE_DATE" value="false" /> + </value> + </option> + <option name="SHOW_OUTPUT" value="false" /> + <option name="ADD_WATCH_INDEX" value="0" /> + <option name="REMOVE_WATCH_INDEX" value="0" /> + <option name="UPDATE_KEYWORD_SUBSTITUTION" /> + <option name="MAKE_NEW_FILES_READONLY" value="false" /> + <option name="SHOW_CORRUPTED_PROJECT_FILES" value="0" /> + <option name="TAG_AFTER_PROJECT_COMMIT" value="false" /> + <option name="OVERRIDE_EXISTING_TAG_FOR_PROJECT" value="true" /> + <option name="TAG_AFTER_PROJECT_COMMIT_NAME" value="" /> + <option name="CLEAN_COPY" value="false" /> + </component> + <component name="DaemonCodeAnalyzer"> + <disable_hints /> + </component> + <component name="DebuggerManager"> + <breakpoint_any> + <breakpoint> + <option name="NOTIFY_CAUGHT" value="true" /> + <option name="NOTIFY_UNCAUGHT" value="true" /> + <option name="ENABLED" value="false" /> + <option name="SUSPEND_POLICY" value="SuspendAll" /> + <option name="LOG_ENABLED" value="false" /> + <option name="LOG_EXPRESSION_ENABLED" value="false" /> + <option name="COUNT_FILTER_ENABLED" value="false" /> + <option name="COUNT_FILTER" value="0" /> + <option name="CONDITION_ENABLED" value="false" /> + <option name="CLASS_FILTERS_ENABLED" value="false" /> + <option name="INSTANCE_FILTERS_ENABLED" value="false" /> + <option name="CONDITION" value="" /> + <option name="LOG_MESSAGE" value="" /> + </breakpoint> + <breakpoint> + <option name="NOTIFY_CAUGHT" value="true" /> + <option name="NOTIFY_UNCAUGHT" value="true" /> + <option name="ENABLED" value="false" /> + <option name="SUSPEND_POLICY" value="SuspendAll" /> + <option name="LOG_ENABLED" value="false" /> + <option name="LOG_EXPRESSION_ENABLED" value="false" /> + <option name="COUNT_FILTER_ENABLED" value="false" /> + <option name="COUNT_FILTER" value="0" /> + <option name="CONDITION_ENABLED" value="false" /> + <option name="CLASS_FILTERS_ENABLED" value="false" /> + <option name="INSTANCE_FILTERS_ENABLED" value="false" /> + <option name="CONDITION" value="" /> + <option name="LOG_MESSAGE" value="" /> + </breakpoint> + </breakpoint_any> + <breakpoint_rules /> + <ui_properties /> + </component> + <component name="ErrorTreeViewConfiguration"> + <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" /> + <option name="HIDE_WARNINGS" value="false" /> + </component> + <component name="FavoritesManager"> + <favorites_list name="map-activity" /> + </component> + <component name="FavoritesProjectViewPane"> + <subPane subId="map-activity"> + <PATH> + <PATH_ELEMENT> + <option name="myItemId" /> + <option name="myItemType" value="com.intellij.ide.favoritesTreeView.FavoritesTreeNodeDescriptor" /> + </PATH_ELEMENT> + </PATH> + </subPane> + </component> + <component name="FileEditorManager"> + <leaf> + <file leaf-file-name="1.jpg" pinned="false" current="false" current-in-tab="false"> + <entry file="file://$PROJECT_DIR$/html/1.jpg"> + <provider selected="true" editor-type-id="images"> + <state /> + </provider> + </entry> + </file> + <file leaf-file-name="model.py" pinned="false" current="false" current-in-tab="false"> + <entry file="file://$PROJECT_DIR$/model.py"> + <provider selected="true" editor-type-id="text-editor"> + <state line="107" column="57" selection-start="3153" selection-end="3153" vertical-scroll-proportion="0.6363636"> + <folding /> + </state> + </provider> + </entry> + </file> + <file leaf-file-name="activity.info" pinned="false" current="false" current-in-tab="false"> + <entry file="file://$PROJECT_DIR$/activity/activity.info"> + <provider selected="true" editor-type-id="text-editor"> + <state line="7" column="0" selection-start="126" selection-end="126" vertical-scroll-proportion="0.125"> + <folding /> + </state> + </provider> + </entry> + </file> + <file leaf-file-name="NEWS" pinned="false" current="false" current-in-tab="false"> + <entry file="file://$PROJECT_DIR$/NEWS"> + <provider selected="true" editor-type-id="text-editor"> + <state line="1" column="18" selection-start="20" selection-end="20" vertical-scroll-proportion="0.017857144"> + <folding /> + </state> + </provider> + </entry> + </file> + <file leaf-file-name="setup.py" pinned="false" current="true" current-in-tab="true"> + <entry file="file://$PROJECT_DIR$/setup.py"> + <provider selected="true" editor-type-id="text-editor"> + <state line="23" column="0" selection-start="830" selection-end="830" vertical-scroll-proportion="0.4107143"> + <folding /> + </state> + </provider> + </entry> + </file> + </leaf> + </component> + <component name="FindManager"> + <FindUsagesManager> + <setting name="OPEN_NEW_TAB" value="false" /> + </FindUsagesManager> + </component> + <component name="HierarchyBrowserManager"> + <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" /> + <option name="SORT_ALPHABETICALLY" value="false" /> + <option name="HIDE_CLASSES_WHERE_METHOD_NOT_IMPLEMENTED" value="false" /> + </component> + <component name="InspectionManager"> + <option name="AUTOSCROLL_TO_SOURCE" value="false" /> + <option name="SPLITTER_PROPORTION" value="0.5" /> + <option name="GROUP_BY_SEVERITY" value="false" /> + <option name="FILTER_RESOLVED_ITEMS" value="true" /> + <option name="ANALYZE_TEST_SOURCES" value="true" /> + <option name="SHOW_DIFF_WITH_PREVIOUS_RUN" value="false" /> + <option name="SCOPE_TYPE" value="1" /> + <option name="CUSTOM_SCOPE_NAME" value="" /> + <option name="SHOW_ONLY_DIFF" value="false" /> + <option name="myCurrentProfileName" value="Default" /> + </component> + <component name="J2EEProjectPane" /> + <component name="JspContextManager" /> + <component name="ModuleEditorState"> + <option name="LAST_EDITED_MODULE_NAME" /> + <option name="LAST_EDITED_TAB_NAME" /> + </component> + <component name="NamedScopeManager" /> + <component name="PackagesPane"> + <subPane /> + </component> + <component name="PerforceChangeBrowserSettings"> + <option name="USE_CLIENT_FILTER" value="true" /> + <option name="CLIENT" value="" /> + </component> + <component name="PerforceDirect.Settings"> + <option name="useP4CONFIG" value="true" /> + <option name="port" value="<perforce_server>:1666" /> + <option name="client" value="" /> + <option name="user" value="" /> + <option name="passwd" value="" /> + <option name="showCmds" value="false" /> + <option name="useNativeApi" value="false" /> + <option name="pathToExec" value="p4" /> + <option name="useCustomPathToExec" value="false" /> + <option name="SYNC_FORCE" value="false" /> + <option name="SYNC_RUN_RESOLVE" value="true" /> + <option name="REVERT_UNCHANGED_FILES" value="true" /> + <option name="CHARSET" value="none" /> + <option name="SHOW_BRANCHES_HISTORY" value="true" /> + <option name="ENABLED" value="true" /> + <option name="USE_LOGIN" value="false" /> + <option name="LOGIN_SILENTLY" value="false" /> + <option name="INTEGRATE_RUN_RESOLVE" value="true" /> + <option name="INTEGRATE_REVERT_UNCHANGED" value="true" /> + <option name="SERVER_TIMEOUT" value="20000" /> + </component> + <component name="ProjectLevelVcsManager"> + <OptionsSetting value="true" id="Add" /> + <OptionsSetting value="true" id="Remove" /> + <OptionsSetting value="true" id="Checkin" /> + <OptionsSetting value="true" id="Checkout" /> + <OptionsSetting value="true" id="Update" /> + <OptionsSetting value="true" id="Status" /> + <OptionsSetting value="true" id="Edit" /> + <OptionsSetting value="true" id="Undo Check Out" /> + <OptionsSetting value="true" id="Compare with SourceSafe Version" /> + <OptionsSetting value="true" id="Get Latest Version" /> + <ConfirmationsSetting value="0" id="Add" /> + <ConfirmationsSetting value="0" id="Remove" /> + </component> + <component name="ProjectPane"> + <subPane> + <PATH> + <PATH_ELEMENT> + <option name="myItemId" value="map-activity.ipr" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="map-activity" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" /> + </PATH_ELEMENT> + </PATH> + <PATH> + <PATH_ELEMENT> + <option name="myItemId" value="map-activity.ipr" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="map-activity" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> + </PATH_ELEMENT> + </PATH> + <PATH> + <PATH_ELEMENT> + <option name="myItemId" value="map-activity.ipr" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="map-activity" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/po" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> + </PATH_ELEMENT> + </PATH> + <PATH> + <PATH_ELEMENT> + <option name="myItemId" value="map-activity.ipr" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="map-activity" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/icons" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> + </PATH_ELEMENT> + </PATH> + <PATH> + <PATH_ELEMENT> + <option name="myItemId" value="map-activity.ipr" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="map-activity" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/html" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> + </PATH_ELEMENT> + </PATH> + <PATH> + <PATH_ELEMENT> + <option name="myItemId" value="map-activity.ipr" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="map-activity" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/gfx" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> + </PATH_ELEMENT> + </PATH> + <PATH> + <PATH_ELEMENT> + <option name="myItemId" value="map-activity.ipr" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="map-activity" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/activity" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> + </PATH_ELEMENT> + </PATH> + </subPane> + </component> + <component name="ProjectReloadState"> + <option name="STATE" value="0" /> + </component> + <component name="ProjectView"> + <navigator currentView="ProjectPane" proportions="0.11111111" version="1" splitterProportion="0.5"> + <flattenPackages /> + <showMembers /> + <showModules /> + <showLibraryContents /> + <hideEmptyPackages /> + <abbreviatePackageNames /> + <showStructure Favorites="false" PackagesPane="false" Scope="false" ProjectPane="false" /> + <autoscrollToSource /> + <autoscrollFromSource /> + <sortByType /> + </navigator> + </component> + <component name="PropertiesComponent"> + <property name="GoToFile.includeJavaFiles" value="false" /> + <property name="GoToClass.toSaveIncludeLibraries" value="false" /> + <property name="MemberChooser.sorted" value="false" /> + <property name="MemberChooser.showClasses" value="true" /> + <property name="GoToClass.includeLibraries" value="false" /> + <property name="MemberChooser.copyJavadoc" value="false" /> + </component> + <component name="ReadonlyStatusHandler"> + <option name="SHOW_DIALOG" value="true" /> + </component> + <component name="RecentsManager" /> + <component name="RestoreUpdateTree" /> + <component name="RunManager"> + <configuration default="true" type="JUnit" factoryName="JUnit" enabled="false" merge="false"> + <module name="" /> + <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" /> + <option name="ALTERNATIVE_JRE_PATH" /> + <option name="PACKAGE_NAME" /> + <option name="MAIN_CLASS_NAME" /> + <option name="METHOD_NAME" /> + <option name="TEST_OBJECT" value="class" /> + <option name="VM_PARAMETERS" /> + <option name="PARAMETERS" /> + <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" /> + <option name="ADDITIONAL_CLASS_PATH" /> + <option name="TEST_SEARCH_SCOPE"> + <value defaultName="wholeProject" /> + </option> + </configuration> + <configuration default="true" type="Application" factoryName="Application" enabled="false" merge="false"> + <option name="MAIN_CLASS_NAME" /> + <option name="VM_PARAMETERS" /> + <option name="PROGRAM_PARAMETERS" /> + <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" /> + <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" /> + <option name="ALTERNATIVE_JRE_PATH" /> + <option name="ENABLE_SWING_INSPECTOR" value="false" /> + <module name="" /> + </configuration> + <configuration default="true" type="Remote" factoryName="Remote"> + <option name="USE_SOCKET_TRANSPORT" value="true" /> + <option name="SERVER_MODE" value="false" /> + <option name="SHMEM_ADDRESS" value="javadebug" /> + <option name="HOST" value="localhost" /> + <option name="PORT" value="5005" /> + </configuration> + <configuration default="true" type="Applet" factoryName="Applet"> + <module name="" /> + <option name="MAIN_CLASS_NAME" /> + <option name="HTML_FILE_NAME" /> + <option name="HTML_USED" value="false" /> + <option name="WIDTH" value="400" /> + <option name="HEIGHT" value="300" /> + <option name="POLICY_FILE" value="/Applications/IntelliJ IDEA 6.0.4.app/bin/appletviewer.policy" /> + <option name="VM_PARAMETERS" /> + <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" /> + <option name="ALTERNATIVE_JRE_PATH" /> + </configuration> + <configuration name="<template>" type="WebApp" default="true" selected="false"> + <Host>localhost</Host> + <Port>5050</Port> + </configuration> + </component> + <component name="ScopeViewComponent"> + <subPane subId="Project"> + <PATH> + <PATH_ELEMENT USER_OBJECT="Root"> + <option name="myItemId" value="" /> + <option name="myItemType" value="" /> + </PATH_ELEMENT> + </PATH> + </subPane> + </component> + <component name="SelectInManager" /> + <component name="StarteamConfiguration"> + <option name="SERVER" value="" /> + <option name="PORT" value="49201" /> + <option name="USER" value="" /> + <option name="PASSWORD" value="" /> + <option name="PROJECT" value="" /> + <option name="VIEW" value="" /> + <option name="ALTERNATIVE_WORKING_PATH" value="" /> + <option name="LOCK_ON_CHECKOUT" value="false" /> + <option name="UNLOCK_ON_CHECKIN" value="false" /> + </component> + <component name="StructuralSearchPlugin" /> + <component name="StructureViewFactory"> + <option name="AUTOSCROLL_MODE" value="true" /> + <option name="AUTOSCROLL_FROM_SOURCE" value="false" /> + <option name="ACTIVE_ACTIONS" value="" /> + </component> + <component name="Struts Assistant"> + <option name="showInputs" value="true" /> + <option name="resources"> + <value> + <option name="strutsPath" /> + <option name="strutsHelp" /> + </value> + </option> + <option name="selectedTaglibs" /> + <option name="selectedTaglibs" /> + <option name="myStrutsValidationEnabled" value="true" /> + <option name="myTilesValidationEnabled" value="true" /> + <option name="myValidatorValidationEnabled" value="true" /> + <option name="myReportErrorsAsWarnings" value="true" /> + </component> + <component name="SvnChangesBrowserSettings"> + <option name="USE_AUTHOR_FIELD" value="true" /> + <option name="AUTHOR" value="" /> + <option name="LOCATION" value="" /> + <option name="USE_PROJECT_SETTINGS" value="true" /> + <option name="USE_ALTERNATE_LOCATION" value="false" /> + </component> + <component name="SvnConfiguration"> + <option name="USER" value="" /> + <option name="PASSWORD" value="" /> + <option name="PROCESS_UNRESOLVED" value="false" /> + <option name="LAST_MERGED_REVISION" /> + <option name="UPDATE_RUN_STATUS" value="false" /> + <option name="UPDATE_RECURSIVELY" value="true" /> + <option name="MERGE_DRY_RUN" value="false" /> + <configuration useDefault="false">/Users/erikb/.subversion</configuration> + <checkoutURL>http://mediamods.com/public-svn</checkoutURL> + <checkoutURL>http://mediamods.com/private-svn/</checkoutURL> + <checkoutURL>https://svn.gforge.i-a-i.com/svn/storytiles-sim</checkoutURL> + <upgradeMode>auto</upgradeMode> + </component> + <component name="TodoView" selected-index="0"> + <todo-panel id="selected-file"> + <are-packages-shown value="false" /> + <are-modules-shown value="false" /> + <flatten-packages value="false" /> + <is-autoscroll-to-source value="true" /> + </todo-panel> + <todo-panel id="all"> + <are-packages-shown value="true" /> + <are-modules-shown value="false" /> + <flatten-packages value="false" /> + <is-autoscroll-to-source value="true" /> + </todo-panel> + </component> + <component name="ToolWindowManager"> + <frame x="0" y="25" width="1400" height="1000" extended-state="0" /> + <editor active="false" /> + <layout> + <window_info id="UI Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="3" /> + <window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="8" /> + <window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="3" /> + <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.24981357" order="1" /> + <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32760596" order="1" /> + <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" order="4" /> + <window_info id="IDEtalk Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="8" /> + <window_info id="IDEtalk" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="3" /> + <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="8" /> + <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32875144" order="8" /> + <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="7" /> + <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.24981357" order="1" /> + <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" order="0" /> + <window_info id="CVS" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="8" /> + <window_info id="Module Dependencies" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="3" /> + <window_info id="Dependency Viewer" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="8" /> + <window_info id="File View" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="3" /> + <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.17971663" order="0" /> + <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="2" /> + <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" order="6" /> + <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="2" /> + <window_info id="SVN Repositories" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.3298969" order="8" /> + <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="5" /> + <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="0" /> + <window_info id="Web" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="2" /> + <window_info id="EJB" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="3" /> + </layout> + </component> + <component name="VCS.FileViewConfiguration"> + <option name="SELECTED_STATUSES" value="DEFAULT" /> + <option name="SELECTED_COLUMNS" value="DEFAULT" /> + <option name="SHOW_FILTERS" value="true" /> + <option name="CUSTOMIZE_VIEW" value="true" /> + <option name="SHOW_FILE_HISTORY_AS_TREE" value="true" /> + </component> + <component name="VcsManagerConfiguration"> + <option name="OFFER_MOVE_TO_ANOTHER_CHANGELIST_ON_PARTIAL_COMMIT" value="true" /> + <option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="true" /> + <option name="PERFORM_UPDATE_IN_BACKGROUND" value="false" /> + <option name="PERFORM_COMMIT_IN_BACKGROUND" value="false" /> + <option name="PUT_FOCUS_INTO_COMMENT" value="false" /> + <option name="FORCE_NON_EMPTY_COMMENT" value="false" /> + <option name="LAST_COMMIT_MESSAGE" value="po" /> + <option name="SAVE_LAST_COMMIT_MESSAGE" value="true" /> + <option name="CHECKIN_DIALOG_SPLITTER_PROPORTION" value="0.8" /> + <option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="false" /> + <option name="REFORMAT_BEFORE_PROJECT_COMMIT" value="false" /> + <option name="REFORMAT_BEFORE_FILE_COMMIT" value="false" /> + <option name="FILE_HISTORY_DIALOG_COMMENTS_SPLITTER_PROPORTION" value="0.8" /> + <option name="FILE_HISTORY_DIALOG_SPLITTER_PROPORTION" value="0.5" /> + <option name="ERROR_OCCURED" value="false" /> + <option name="ACTIVE_VCS_NAME" value="svn" /> + <option name="UPDATE_GROUP_BY_PACKAGES" value="false" /> + <option name="SHOW_FILE_HISTORY_AS_TREE" value="false" /> + <option name="FILE_HISTORY_SPLITTER_PROPORTION" value="0.6" /> + <MESSAGE value="after a movie... not sure where the code is at." /> + <MESSAGE value="adding tags to map locations works like a charm now" /> + <MESSAGE value="load in image files that do not have thumbnails in their ds metadata works" /> + <MESSAGE value="serialize search results with popup and density tags" /> + <MESSAGE value="added tags when we add media" /> + <MESSAGE value="make file changes" /> + <MESSAGE value="prep for launch" /> + <MESSAGE value="more prep for launch" /> + <MESSAGE value="NEWS" /> + <MESSAGE value="po" /> + </component> + <component name="VssConfiguration"> + <option name="CLIENT_PATH" value="" /> + <option name="SRCSAFEINI_PATH" value="" /> + <option name="USER_NAME" value="" /> + <option name="PWD" value="" /> + <option name="VSS_IS_INITIALIZED" value="true" /> + <CheckoutOptions> + <option name="COMMENT" value="" /> + <option name="DO_NOT_GET_LATEST_VERSION" value="false" /> + <option name="REPLACE_WRITABLE" value="false" /> + <option name="RECURSIVE" value="false" /> + </CheckoutOptions> + <CheckinOptions> + <option name="COMMENT" value="" /> + <option name="KEEP_CHECKED_OUT" value="false" /> + <option name="RECURSIVE" value="false" /> + </CheckinOptions> + <AddOptions> + <option name="STORE_ONLY_LATEST_VERSION" value="false" /> + <option name="CHECK_OUT_IMMEDIATELY" value="false" /> + <option name="FILE_TYPE" value="0" /> + </AddOptions> + <UndocheckoutOptions> + <option name="MAKE_WRITABLE" value="false" /> + <option name="REPLACE_LOCAL_COPY" value="0" /> + <option name="RECURSIVE" value="false" /> + </UndocheckoutOptions> + <GetOptions> + <option name="REPLACE_WRITABLE" value="0" /> + <option name="MAKE_WRITABLE" value="false" /> + <option name="ANSWER_NEGATIVELY" value="false" /> + <option name="ANSWER_POSITIVELY" value="false" /> + <option name="RECURSIVE" value="false" /> + <option name="VERSION" /> + </GetOptions> + <VssConfigurableExcludedFilesTag /> + </component> + <component name="antWorkspaceConfiguration"> + <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" /> + <option name="FILTER_TARGETS" value="false" /> + </component> + <component name="com.intellij.ide.util.scopeChooser.ScopeChooserConfigurable" proportions="" version="1"> + <option name="myLastEditedConfigurable" /> + </component> + <component name="com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectRootMasterDetailsConfigurable" proportions="" version="1"> + <option name="myPlainMode" value="false" /> + <option name="myLastEditedConfigurable" /> + </component> + <component name="com.intellij.profile.ui.ErrorOptionsConfigurable" proportions="0.16666667" version="1"> + <option name="myLastEditedConfigurable" value="IDE Profiles" /> + </component> + <component name="editorHistoryManager"> + <entry file="file://$PROJECT_DIR$/html/1.jpg"> + <provider selected="true" editor-type-id="images"> + <state /> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/model.py"> + <provider selected="true" editor-type-id="text-editor"> + <state line="107" column="57" selection-start="3153" selection-end="3153" vertical-scroll-proportion="0.6363636"> + <folding /> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/activity/activity.info"> + <provider selected="true" editor-type-id="text-editor"> + <state line="7" column="0" selection-start="126" selection-end="126" vertical-scroll-proportion="0.125"> + <folding /> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/NEWS"> + <provider selected="true" editor-type-id="text-editor"> + <state line="1" column="18" selection-start="20" selection-end="20" vertical-scroll-proportion="0.017857144"> + <folding /> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/setup.py"> + <provider selected="true" editor-type-id="text-editor"> + <state line="23" column="0" selection-start="830" selection-end="830" vertical-scroll-proportion="0.4107143"> + <folding /> + </state> + </provider> + </entry> + </component> +</project> + @@ -0,0 +1,1799 @@ +#!/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( "<b><span foreground='white' size='xx-large'>" + Constants.istrConnecting + "</span></b>") + 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("<b>" + Constants.istrLatitude + "</b> ") + 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("<b>" + Constants.istrLongitude + "</b> ") + 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("<b>" + Constants.istrTags + "</b>") + 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('<?xml version="1.0" ?><map')==0): + # Offline Map or regular Map file without meta-data + self.preComet() + self.cometLogic.startKML(1) + xmlarray = firstLine.split('>') + for node in xmlarray: + #if(node.find('<mapItem') == 0): + # picture marker + if(node.find('<infoMarker') == 0): + # info marker + lat = node[node.find('lat="')+5:len(node)] + lat = lat[0:lat.find('"')] + lng = node[node.find('lng="')+5:len(node)] + lng = lng[0:lng.find('"')] + description = node[node.find('info="')+6:len(node)] + description = description[0:description.find('"')] + icon = node[node.find('icon="')+6:len(node)] + icon = icon[0:icon.find('"')] + self.cometLogic.handleAddMarker(lat,lng,description,icon) + self.addInfoMarker(lat,lng,description,icon,True) + elif(node.find('<line') == 0): + # line + lineColor = node[node.find('lcolor="')+8:len(node)] + lineColor = lineColor[0:lineColor.find('"')] + lineID = node[node.find('lid="')+5:len(node)] + lineID = lineID[0:lineID.find('"')] + ptStr = node[node.find('lpts="')+6:len(node)] + ptStr = ptStr[0:ptStr.find('"')] + lineThick = node[node.find('lthickness="')+12:len(node)] + lineThick = lineThick[0:lineThick.find('"')] + self.cometLogic.handleLine(lineID,lineColor,lineThick,ptStr) + self.addLine(lineID,lineColor,lineThick,ptStr,1) + elif(node.find('<savedMap') == 0): + # saved map + lat = node[node.find('lat="')+5:len(node)] + lat = lat[0:lat.find('"')] + lng = node[node.find('lng="')+5:len(node)] + lng = lng[0:lng.find('"')] + notes = node[node.find('notes="')+7:len(node)] + notes = notes[0:notes.find('"')] + zoom = node[node.find('zoom="')+6:len(node)] + zoom = zoom[0:zoom.find('"')] + self.addSavedMap(lat,lng,zoom,notes,True) + self.cometLogic.handleEndKML(1) + self.postComet() + return + placename = None + description = None + kmlIcon = None + lat = None + lng = None + coordList = None + placemarkType = None + lineType = None + stillDescribing = False + morePts = False + dataTable = None + isOSM = False + isGeoRSS = False + self.preComet() + self.cometLogic.startKML(1) + for kmlline in kml: + if((kmlline.find('<osm') != -1) and (lat == None) and (lng == None) and (coordList == None)): + # jump to osm + isOSM = True + break + elif((kmlline.find('georss') != -1) and (lat == None) and (lng == None) and (coordList == None)): + # jump to GeoRSS + isGeoRSS = True + break + if(kmlline.find('<Point') != -1): + placemarkType = 'info' + elif(kmlline.find('<LineString') != -1): + placemarkType = 'line' + lineType = 'line' + elif(kmlline.find('<Polygon') != -1): + placemarkType = 'poly' + lineType = 'poly' + #elif(kmlline.find('<GroundOverlay') != -1): + # placemarkType = 'overlay' + if(kmlline.find('<ExtendedData') != -1): + dataTable = '<table>' + elif(kmlline.find('</ExtendedData>') != -1): + dataTable = dataTable + '</table>' + if(dataTable is not None): + if(kmlline.find('<Data') != -1): + dataTable = dataTable + '<tr>' + if(kmlline.find('<Data name="') != -1): + dataTable = dataTable + "<td><b>" + kmlline[kmlline.find('<Data name="')+12:kmlline.rfind('"')] + "</b></td>" + if(kmlline.find('<value>') != -1): + dataTable = dataTable + "<td>" + kmlline[kmlline.find('<value>')+7:kmlline.find('</value>')] + "</td>" + elif(kmlline.find('</Data>') != -1): + dataTable = dataTable + '</tr>' + + if(kmlline.find('<coordinates>') != -1): + if(placemarkType == 'info'): + lng = kmlline[kmlline.find('<coordinates>')+13:kmlline.find(',')] + lat = kmlline[kmlline.find(',')+1:kmlline.rfind(',')] + else: + if(kmlline.find('</coordinates>') == -1): + morePts = True + kmlline = kmlline.replace('<coordinates>','').replace('</coordinates>','') + coordList = kmlline.split(' ') + elif(morePts == True): + if(kmlline.find('</coordinates>') != -1): + morePts = False + kmlline = kmlline.replace('</coordinates>','') + coordList.extend(kmlline.split(' ')) + + if(kmlline.find('<name>') != -1): + placename = kmlline[kmlline.find('<name>')+6:kmlline.find('</name>')] + if(kmlline.find('<description>') != -1): + description = kmlline[kmlline.find('<description>')+13:len(kmlline)] + if(kmlline.find('</description>') == -1): + # need to read in more lines + stillDescribing = True + else: + description = description[0:description.find('</description')] + if(description.find('<![CDATA[') != -1): + description = description.replace('<![CDATA[','').replace(']]>','') + elif(stillDescribing == True): + description = description + kmlline + if(kmlline.find('</description>') != -1): + stillDescribing = False + description = description[0:description.find('</description')] + if(description.find('<![CDATA[') != -1): + description = description.replace('<![CDATA[','').replace(']]>','') + if(kmlline.find('<Icon><href>')!=-1): + icon = kmlline[kmlline.find('<Icon><href>')+12:kmlline.find('</href>')] + if((kmlline.find('</Placemark>') != -1) or (kmlline.find('<Placemark>') != -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 = '<h3>' + placename + '</h3>' + 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('<node') != -1): + # point, which may be part of a line + nodeID = osm[osm.find('id=')+4:len(osm)] + nodeID = nodeID[0:nodeID.find('"')] + nodeID = nodeID[0:nodeID.find("'")] + lat = osm[osm.find('lat=')+5:len(osm)] + lat = lat[0:lat.find("'")] + lat = lat[0:lat.find('"')] + lng = osm[osm.find('lon=')+5:len(osm)] + lng = lng[0:lng.find("'")] + lng = lng[0:lng.find('"')] + osmNodes[nodeID] = {"latitude":lat,"longitude":lng,"inWay":False,"isWay":False} + if(osm.find('/>') == -1): + readingInNodeID = nodeID + elif(readingInNodeID is not None): + # reading in tag-values for the point + if(osm.find('</node>') != -1): + readingInNodeID = None + else: + if(osm.find('<tag') != -1): + tName = osm[osm.find('k=')+3:len(osm)] + tName = tName[0:tName.find('"')] + tName = tName[0:tName.find("'")] + vName = osm[osm.find('v=')+3:len(osm)] + vName = vName[0:vName.find('"')] + vName = vName[0:vName.find("'")] + osmNodes[readingInNodeID][tName] = vName + elif(osm.find('<way') != -1): + # line, composed of multiple points + readingInWayID = osm[osm.find('id=')+4:len(osm)] + readingInWayID = readingInWayID[0:readingInWayID.find('"')] + readingInWayID = readingInWayID[0:readingInWayID.find("'")] + osmNodes[readingInWayID] = {"isWay":True,"pts":[]} + elif(readingInWayID is not None): + # reading in node ids composing the line + if(osm.find('</way>') != -1): + readingInWayID = None + else: + if(osm.find('<nd') != -1): + nodeRef = osm[osm.find('ref=')+5:len(osm)] + if(nodeRef.find('"') != -1): + nodeRef = nodeRef[0:nodeRef.find('"')] + else: + nodeRef = nodeRef[0:nodeRef.find("'")] + osmNodes[readingInWayID]["pts"].append(nodeRef) + osmNodes[nodeRef]["inWay"] = True + # decide how to publish nodes + for node in osmNodes: + if(osmNodes[node]["isWay"] == True): + # line composed of points + ptList=[] + for pID in osmNodes[node]["pts"]: + ptList.append(osmNodes[pID]["latitude"]+"|"+osmNodes[pID]["longitude"]) + lineID = str(random.getrandbits(128)) + self.cometLogic.handleLine(lineID,"B22222","5",'|'.join(ptList)) + self.addLine(lineID,"B22222","5",'|'.join(ptList),1) + elif(osmNodes[node]["inWay"] == False): + # independent point + description="<table>" + for tag in osmNodes[node]: + if(tag=="latitude"): + continue + elif(tag=="longitude"): + continue + elif(tag=="inWay"): + continue + elif(tag=="isWay"): + continue + else: + value = osmNodes[node][tag] + description=description+"<tr><td>"+tag+"</td><td>"+str(value)+"</td></tr>" + description=description+"</table>" + 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('<title') != -1): + placename = rss[rss.find('>')+1:rss.find('</title>')] + if(rss.find('<link') != -1): + placeLink = rss[rss.find('>')+1:rss.find('</link>')] + if(rss.find('<georss:point') != -1): + latlng = rss[rss.find('>')+1:rss.find('</georss:point>')].split(' ') + lat = latlng[0] + lng = latlng[1] + if(rss.find('<description>') != -1): + description = rss[rss.find('<description>')+13:len(rss)] + if(rss.find('</description>') == -1): + # need to read in more lines + stillDescribing = True + else: + description = description[0:description.find('</description')] + elif(stillDescribing == True): + description = description + rss + if(rss.find('</description>') != -1): + stillDescribing = False + description = description[0:description.find('</description')] + if(rss.find('</item>') != -1): + # publish the point + if(lat is not None): + if(description == None): + description = "" + if(placeLink is not None): + description = placeLink + "<br/>" + description + if(placename is not None): + description = '<h3>' + placename + '</h3>' + description + description=description.replace("'","\\'").replace('"','\\"') + description=description.replace("\n","<br/>").replace("\r","<br/>") + description=description.replace("<![CDATA[","").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 diff --git a/model.py b/model.py new file mode 100644 index 0000000..c97f3fe --- /dev/null +++ b/model.py @@ -0,0 +1,147 @@ +# 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. + +from constants import Constants +from recorded import Recorded +from color import Color +from instance import Instance +import utils +from recorded import Recorded + +import gtk +import os +import shutil +import StringIO + +class Model: + def __init__(self, ca): + self.ca = ca + + self.recs = [] + self.savedMaps = [] + self.infoMarkers = {} + self.lineData = {} + + def getMediaByThumbFilename(self, id): + for i in range(len(self.recs)): + if (self.recs[i].thumbFilename == id): + return self.recs[i] + + return None + + + def getMediaByDatastoreId(self, id): + for i in range(len(self.recs)): + if (self.recs[i].datastoreId == id): + return self.recs[i] + + return None + + + def addMedia(self, lat, lon, datastoreOb): + rec = Recorded() + + #default photo + rec.type = Constants.TYPE_PHOTO + if((datastoreOb.metadata['mime_type'] == "video/ogg") or (datastoreOb.metadata['mime_type'] == "audio/ogg")): + rec.type = Constants.TYPE_VIDEO + + rec.source = Recorded.SOURCE_DATASTORE + rec.datastoreOb = datastoreOb + rec.datastoreId = datastoreOb.object_id + + rec.tags = "" + if (datastoreOb.metadata.has_key("tags")): + rec.tags = datastoreOb.metadata['tags'] + + rec.latitude = lat + rec.longitude = lon + + + colors = datastoreOb.metadata['icon-color'] + colorStroke, colorFill = colors.split(",") + rec.colorStroke = Color() + rec.colorStroke.init_hex(colorStroke) + rec.colorFill = Color() + rec.colorFill.init_hex(colorFill) + + thumbPixbuf = None + if (datastoreOb.metadata.has_key("preview")): + try: + thumb = datastoreOb.metadata['preview'] + if thumb[1:4] == 'PNG': + pbl = gtk.gdk.PixbufLoader() + pbl.write(thumb) + pbl.close() + thumbPixbuf = pbl.get_pixbuf() + else: + thumbPixbuf = utils.getPixbufFromString(thumb) + except: + pass + + if (thumbPixbuf == None): + #try to create the thumbnail yourself... + if (rec.type == Constants.TYPE_PHOTO): + try: + #load in the image, make a thumbnail + thumbPixbuf = gtk.gdk.pixbuf_new_from_file_at_size(rec.getFilepath(), 320, 240) + except: + pass + + if (thumbPixbuf == None): + #i give up. load in a blank image from the activity itself. + thumbPath = os.path.join(self.ca.htmlPath, "1.jpg") + thumbPixbuf = gtk.gdk.pixbuf_new_from_file(thumbPath) + + + thumbFilepath = os.path.join(Instance.instancePath, "thumb.png") + thumbFilepath = utils.getUniqueFilepath(thumbFilepath, 0) + thumbPixbuf.save( thumbFilepath, "png", {} ) + rec.thumbFilename = os.path.basename(thumbFilepath) + + self.recs.append(rec) + + return rec + + def setInfo( self, lat, lng, info, icon ): + self.infoMarkers[lat+','+lng] = lat + ";~" + lng + ";~" + info + ";~" + icon + + def setLine( self, id, color, thickness, pts ): + self.lineData[id] = id + ";~" + color + ";~" + thickness + ";~" + pts + + def addSavedMap( self, smap ): + self.savedMaps.append(smap) + + def getMediaResponse(self, s, w, n, e): + r = "" + + for i in range( len(self.recs) ): + rec = self.recs[i] + r = r + "var m" + str(i) + " = new MediaMarker( new google.maps.LatLng(" + str(rec.latitude) + "," + str(rec.longitude) + "), '" + rec.getThumbUrl() + "', '" + rec.getThumbBasename() + "', null, null, 'null');" + r = r + "canvas.markerList.addMarker(m" + str(i) + ");" + + for k, i in self.infoMarkers.iteritems(): + iMarker = i.split(";~") + r = r + "addInfoMarker(" + iMarker[0] + "," + iMarker[1] + ",'" + iMarker[2] + "','" + iMarker[3] + "');" + + for k, i in self.lineData.iteritems(): + iLine = i.split(";~") + r = r + "addLine('" + iLine[0] + "','" + iLine[1] + "','" + iLine[2] + "','" + iLine[3] + "');" + return r @@ -0,0 +1,5 @@ +1 +* init (jedierikb) + +2 +* 8.2 re-release( jedierikb)
\ No newline at end of file @@ -0,0 +1,86 @@ +# 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 +from gtk import gdk +import gobject +import cairo +import math + + +class P5(gtk.DrawingArea): + def __init__(self, button=False): + super(P5, self).__init__() + self.connect("expose_event", self.expose) + if (button): + self.add_events(gdk.BUTTON_PRESS_MASK | gdk.BUTTON_RELEASE_MASK | gdk.POINTER_MOTION_MASK) + self.connect("button_press_event", self._buttonPress) + + + 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() + + rect = widget.allocation + self.draw( ctx, rect.width, rect.height ) + + + def redraw_canvas(self): + #called from update + if self.window: + alloc = self.get_allocation() + 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() + + + def fillRect( 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.fill() + + + 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 _buttonPress(self, widget, event): + self.fireButton() + + + def fireButton( self ): + #for extending + pass
\ No newline at end of file diff --git a/photocanvas.py b/photocanvas.py new file mode 100644 index 0000000..9346066 --- /dev/null +++ b/photocanvas.py @@ -0,0 +1,65 @@ +import cairo +import gtk +import gobject +from gtk import gdk + +from p5 import P5 +from constants import Constants + +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 draw(self, ctx, w, h): + self.fillRect( ctx, Constants.colorBlack, w, h ) + + if (self.img != None): + + 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 ) + + 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 + + + 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 + + #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() diff --git a/po/es.po b/po/es.po new file mode 100644 index 0000000..f01d56c --- /dev/null +++ b/po/es.po @@ -0,0 +1,99 @@ +#: activity/activity.info:2 +msgid "Map" +msgstr "Mapa" + +#: constants.py:26 +msgid "Edit" +msgstr "Editar" + +#: constants.py:27 +msgid "Search" +msgstr "Buscar" + +#: constants.py:28 +msgid "Find:" +msgstr "Busca:" + +#: constants.py:29 +msgid "Tags:" +msgstr "Palabras:" + +#: constants.py:30 +msgid "Save Search" +msgstr "Recordar Mapa" + +#: constants.py:31 +msgid "Connecting to Map Server" +msgstr "Está Connectando" + +#: constants.py:32 +msgid "Zoom In" +msgstr "Magnificar" + +#: constants.py:33 +msgid "Zoom Out" +msgstr "Magnificar Menos" + +#: constants.py:34 +msgid "Save" +msgstr "Recordar" + +#: constants.py:35 +msgid "Density" +msgstr "Density" + +#: constants.py:36 +msgid "Saved Map" +msgstr "Mapa recordado" + +#: constants.py:37 +msgid "Describe Map" +msgstr "Escribe sobre esto" + +#: constants.py:38 +msgid "Remove Map" +msgstr "Cancelación" + +#: constants.py:39 +msgid "Copy to Clipboard" +msgstr "Copiar" + +#: constants.py:40 +msgid "Add Media" +msgstr "Foto nuevo" + +#: constants.py:41 +msgid "Add Info" +msgstr "Escribir" + +#: constants.py:42 +msgid "Delete" +msgstr "Cancelar" + +#: constants.py:43 +msgid "Library" +msgstr "Biblioteca" + +#: constants.py:44 +msgid "Measure" +msgstr "Medición" + +#: constants.py:45 +msgid "OurMaps" +msgstr "NuestrosMapas" + +#: constants.py:46 +msgid "Latitude:" +msgstr "Latitud:" + +#: constants.py:47 +msgid "Longitude:" +msgstr "Longitud:" + +#: constants.py:48 +msgid "Description:" +msgstr "Descripción:" + +#: constants.py:49 +msgid "lang=en" +msgstr "lang=es" diff --git a/po/map.pot b/po/map.pot new file mode 100644 index 0000000..8b191ef --- /dev/null +++ b/po/map.pot @@ -0,0 +1,113 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-03-10 11:08-0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: activity/activity.info:2 +msgid "Map" +msgstr "" + +#: constants.py:26 +msgid "Edit" +msgstr "" + +#: constants.py:27 +msgid "Search" +msgstr "" + +#: constants.py:28 +msgid "Find:" +msgstr "" + +#: constants.py:29 +msgid "Tags:" +msgstr "" + +#: constants.py:30 +msgid "Save Search" +msgstr "" + +#: constants.py:31 +msgid "Connecting to Map Server" +msgstr "" + +#: constants.py:32 +msgid "Zoom In" +msgstr "" + +#: constants.py:33 +msgid "Zoom Out" +msgstr "" + +#: constants.py:34 +msgid "Save" +msgstr "" + +#: constants.py:35 +msgid "Density" +msgstr "" + +#: constants.py:36 +msgid "Saved Map" +msgstr "" + +#: constants.py:37 +msgid "Describe Map" +msgstr "" + +#: constants.py:38 +msgid "Remove Map" +msgstr "" + +#: constants.py:39 +msgid "Copy to Clipboard" +msgstr "" + +#: constants.py:40 +msgid "Add Media" +msgstr "" + +#: constants.py:41 +msgid "Add Info" +msgstr "" + +#: constants.py:42 +msgid "Delete" +msgstr "" + +#: constants.py:43 +msgid "Library" +msgstr "" + +#: constants.py:44 +msgid "Measure" +msgstr "" + +#: constants.py:45 +msgid "OurMaps" +msgstr "" + +#: constants.py:46 +msgid "Latitude:" +msgstr "" + +#: constants.py:47 +msgid "Longitude:" +msgstr "" + +#: constants.py:48 +msgid "Description:" +msgstr ""
\ No newline at end of file diff --git a/po/mn.po b/po/mn.po new file mode 100644 index 0000000..433bdce --- /dev/null +++ b/po/mn.po @@ -0,0 +1,99 @@ +#: activity/activity.info:2 +msgid "Map" +msgstr "Газрын зураг" + +#: constants.py:26 +msgid "Edit" +msgstr "хийх" + +#: constants.py:27 +msgid "Search" +msgstr "хайлт" + +#: constants.py:28 +msgid "Find:" +msgstr "олох:" + +#: constants.py:29 +msgid "Tags:" +msgstr "--" + +#: constants.py:30 +msgid "Save Search" +msgstr "хадгалах" + +#: constants.py:31 +msgid "Connecting to Map Server" +msgstr "Connecting" + +#: constants.py:32 +msgid "Zoom In" +msgstr "ойрхон" + +#: constants.py:33 +msgid "Zoom Out" +msgstr "алс" + +#: constants.py:34 +msgid "Save" +msgstr "хадгалах" + +#: constants.py:35 +msgid "Density" +msgstr "Density" + +#: constants.py:36 +msgid "Saved Map" +msgstr "газрын зураг" + +#: constants.py:37 +msgid "Describe Map" +msgstr "тодорхойлох" + +#: constants.py:38 +msgid "Remove Map" +msgstr "арилгах" + +#: constants.py:39 +msgid "Copy to Clipboard" +msgstr "хувъ" + +#: constants.py:40 +msgid "Add Media" +msgstr "фото нэмэх" + +#: constants.py:41 +msgid "Add Info" +msgstr "бичих" + +#: constants.py:42 +msgid "Delete" +msgstr "хадгалах" + +#: constants.py:43 +msgid "Library" +msgstr "номын сан" + +#: constants.py:44 +msgid "Measure" +msgstr "зай | орон зай" + +#: constants.py:45 +msgid "OurMaps" +msgstr "хат газрын зураг" + +#: constants.py:46 +msgid "Latitude:" +msgstr "широта:" + +#: constants.py:47 +msgid "Longitude:" +msgstr "долгота:" + +#: constants.py:48 +msgid "Description:" +msgstr "тодорхойлох:" + +#: constants.py:49 +msgid "lang=en" +msgstr "lang=mn" diff --git a/recorded.py b/recorded.py new file mode 100644 index 0000000..2378f1d --- /dev/null +++ b/recorded.py @@ -0,0 +1,82 @@ +# 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 os +import map +import gtk + +from constants import Constants +from instance import Instance + +class Recorded: + SOURCE_DATASTORE = 0 + SOURCE_LOCAL = 1 + SOURCE_BUNDLE = 2 + + def __init__(self): + self.name = None + self.recorded = None + self.colorStroke = None + self.colorFill = None + self.type = None + + self.latitude = None + self.longitude = None + + self.thumbFilename = None + self.fileName = None + self.datastoreOb = None + self.datastoreId = None + self.tags = "" + + self.source = 0 + + + def getFilepath(self): + if (self.source == self.__class__.SOURCE_BUNDLE): + path = os.path.join( Constants.htmlPath, self.fileName ) + return path + elif (self.source == self.__class__.SOURCE_DATASTORE): + return self.datastoreOb.file_path + else: + return None + + + def getPixBuf(self): + pb = None + + fp = self.getFilepath() + if (fp != None): + pb = gtk.gdk.pixbuf_new_from_file(fp) + + return pb + + + def getThumbUrl(self): + return "http://127.0.0.1:" + str(map.Map.ajaxPort) + "/getImage.js?id=" + + + def getThumbBasename(self): + return str(self.thumbFilename) + + + def getThumbPath(self): + thumbPath = os.path.join( Instance.instancePath, self.getThumbBasename() ) + return thumbPath
\ No newline at end of file diff --git a/result.py b/result.py new file mode 100644 index 0000000..a43b67a --- /dev/null +++ b/result.py @@ -0,0 +1,25 @@ +# 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. + + +class ServerResult: + def __init__(self): + self.txt = "" + self.headers = []
\ No newline at end of file diff --git a/savedmap.py b/savedmap.py new file mode 100644 index 0000000..ca890c0 --- /dev/null +++ b/savedmap.py @@ -0,0 +1,41 @@ +# 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. + +class SavedMap: + + def __init__(self, lat, lng, zoom, imgFile, thumbFile, notes, tags): + self.lat = lat + self.lng = lng + self.zoom = zoom + self.imgPath = imgFile + self.thumbPath = thumbFile + self.notes = notes + self.tags = tags + self.density = " " + + self.recdDatastoreId = None + self.recdLat = None + self.recdLng = None + + + def addViewedRecd(self, id, lat, lng): + self.recdDatastoreId = id + self.recdLat = lat + self.recdLng = lng diff --git a/serialize.py b/serialize.py new file mode 100644 index 0000000..4415f3a --- /dev/null +++ b/serialize.py @@ -0,0 +1,203 @@ +import xml.dom.minidom +from xml.dom.minidom import getDOMImplementation +from xml.dom.minidom import parse +import cStringIO +import os +import gtk + +from sugar.datastore import datastore + +from constants import Constants +from instance import Instance +import utils +from recorded import Recorded +import recorded +from savedmap import SavedMap + +def fillMediaHash( index, m ): + doc = None + if (os.path.exists(index)): + try: + doc = parse( os.path.abspath(index) ) + except: + doc = None + if (doc == None): + return + + try: + lastLat = doc.documentElement.getAttributeNode(Constants.mapLat).nodeValue + lastLng = doc.documentElement.getAttributeNode(Constants.mapLng).nodeValue + lastZoom = doc.documentElement.getAttributeNode(Constants.mapZoom).nodeValue + m.ca.preComet() + m.ca.cometLogic.handleReceivedMap(lastLat,lastLng,lastZoom) + m.ca.postComet() + except: + # likely an old saved map + lastLat = 0 + + recdElements = doc.documentElement.getElementsByTagName(Constants.recdMapItem) + for el in recdElements: + _loadMediaIntoHash( el, m ) + + saveElements = doc.documentElement.getElementsByTagName(Constants.recdSavedMapItem) + for el in saveElements: + _loadSavedMap( el, m ) + + saveElements = doc.documentElement.getElementsByTagName(Constants.recdInfoMarker) + for el in saveElements: + _loadInfoMarker( el, m ) + + saveElements = doc.documentElement.getElementsByTagName(Constants.recdLine) + for el in saveElements: + _loadLine( el, m ) + +def _loadSavedMap( el, m ): + latNode = el.getAttributeNode(Constants.recdLat) + lat = latNode.nodeValue + lngNode = el.getAttributeNode(Constants.recdLng) + lng = lngNode.nodeValue + + zoomNode = el.getAttributeNode(Constants.recdZoom) + zoom = zoomNode.nodeValue + notesNode = el.getAttributeNode(Constants.recdNotes) + notes = notesNode.nodeValue + tagsNode = el.getAttributeNode(Constants.recdTags) + tags = tagsNode.nodeValue + + m.ca.addSavedMap(lat,lng,zoom,notes,False) + +def _loadInfoMarker( el, m ): + latNode = el.getAttributeNode(Constants.recdLat) + lat = latNode.nodeValue + lngNode = el.getAttributeNode(Constants.recdLng) + lng = lngNode.nodeValue + infoNode = el.getAttributeNode(Constants.recdInfo) + info = infoNode.nodeValue + iconNode = el.getAttributeNode(Constants.recdIcon) + icon = iconNode.nodeValue + m.setInfo(lat,lng,info,icon) + +def _loadLine( el, m ): + idNode = el.getAttributeNode(Constants.lineID) + id = idNode.nodeValue + colorNode = el.getAttributeNode(Constants.lineColor) + color = colorNode.nodeValue + thickNode = el.getAttributeNode(Constants.lineThick) + thick = thickNode.nodeValue + ptsNode = el.getAttributeNode(Constants.linePts) + pts = ptsNode.nodeValue + m.setLine(id,color,thick,pts) + +def _loadMediaIntoHash( el, m ): + if (el.getAttributeNode(Constants.recdDatastoreId) == None): + return + + datastoreNode = el.getAttributeNode(Constants.recdDatastoreId) + if (datastoreNode != None): + datastoreId = datastoreNode.nodeValue + if (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 + datastoreOb = getMediaFromDatastore(datastoreId) + if (datastoreOb != None): + + lat = 0 + lng = 0 + + if (el.getAttributeNode(Constants.recdLat) != None): + latNode = el.getAttributeNode(Constants.recdLat) + lat = latNode.nodeValue + else: + return + + if (el.getAttributeNode(Constants.recdLng) != None): + lngNode = el.getAttributeNode(Constants.recdLng) + lng = lngNode.nodeValue + else: + return + + m.addMedia( lat, lng, datastoreOb ) + + +def getMediaFromDatastore( id ): + mediaObject = None + try: + mediaObject = datastore.get( id ) + finally: + if (mediaObject == None): + return None + + return mediaObject + + +def fillRecdFromNode( recd, el ): + latNode = el.getAttributeNode(Constants.recdLat) + if (latNode != None): + recd.latitude = latNode.nodeValue + lngNode = el.getAttributeNode(Constants.recdLng) + if (lngNode != None): + recd.longitude = lngNode.nodeValue + + return recd + + +def _addRecdXmlAttrs( el, recd ): + el.setAttribute(Constants.recdDatastoreId, str(recd.datastoreId)) + el.setAttribute(Constants.recdLat, str(recd.latitude)) + el.setAttribute(Constants.recdLng, str(recd.longitude)) + +def _addInfoXmlAttrs( el, recd ): + el.setAttribute(Constants.recdInfo, recd[2]) + el.setAttribute(Constants.recdIcon, recd[3]) + el.setAttribute(Constants.recdLat, str(recd[0])) + el.setAttribute(Constants.recdLng, str(recd[1])) + +def _addLineXmlAttrs( el, recd ): + el.setAttribute(Constants.lineID, recd[0]) + el.setAttribute(Constants.lineColor, recd[1]) + el.setAttribute(Constants.lineThick, recd[2]) + el.setAttribute(Constants.linePts, recd[3]) + +def _addSaveXmlAttrs( el, smap ): + el.setAttribute(Constants.recdLat, str(smap.lat)) + el.setAttribute(Constants.recdLng, str(smap.lng)) + el.setAttribute(Constants.recdZoom, str(smap.zoom)) + el.setAttribute(Constants.recdNotes, str(smap.notes)) + el.setAttribute(Constants.recdTags, smap.tags) + #el.setAttribute(Constants.recdDensity, str(smap.density)) + + if (smap.recdDatastoreId != None): + el.setAttribute(Constants.recdRecdId, smap.recdDatastoreId) + el.setAttribute(Constants.recdRecdLat, smap.recdLat) + el.setAttribute(Constants.recdRecdLng, smap.recdLng) + + +def saveMediaHash( m ): + impl = getDOMImplementation() + album = impl.createDocument(None, Constants.recdAlbum, None) + root = album.documentElement + + for i in range (0, len(m.recs)): + recd = m.recs[i] + mediaEl = album.createElement(Constants.recdMapItem) + root.appendChild( mediaEl ) + _addRecdXmlAttrs( mediaEl, recd ) + + for k, iMarker in m.infoMarkers.iteritems(): + mediaEl = album.createElement(Constants.recdInfoMarker) + root.appendChild( mediaEl ) + _addInfoXmlAttrs( mediaEl, iMarker.split(";~") ) + + for k, iMarker in m.lineData.iteritems(): + mediaEl = album.createElement(Constants.recdLine) + root.appendChild( mediaEl ) + _addLineXmlAttrs( mediaEl, iMarker.split(";~") ) + + for i in range (0, len(m.savedMaps)): + smap = m.savedMaps[i] + saveEl = album.createElement(Constants.recdSavedMapItem) + root.appendChild( saveEl ) + _addSaveXmlAttrs( saveEl, smap ) + + return album diff --git a/server.py b/server.py new file mode 100644 index 0000000..9a91ad4 --- /dev/null +++ b/server.py @@ -0,0 +1,69 @@ +# 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 urlparse +import urllib +import posixpath +import SimpleHTTPServer +import BaseHTTPServer + + +class Server(BaseHTTPServer.HTTPServer): + def __init__(self, server_address, logic): + BaseHTTPServer.HTTPServer.__init__(self, server_address, RegHandler) + self.logic = logic + + +#RegHandler extends SimpleHTTPServer.py (in python 2.4) +class RegHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): + def do_POST( self ): + self.translate_path() + + + def do_GET( self ): + self.translate_path() + + + def do_HEAD( self ): + self.translate_path() + + + def translate_path(self): + #todo: compare with send_head in parent + urlp = urlparse.urlparse(self.path) + + urls = urlp[2] + urls = posixpath.normpath(urllib.unquote(urls)) + urlPath = urls.split('/') + urlPath = filter(None, urlPath) + + params = urlp[4] + parama = [] + allParams = params.split('&') + for i in range (0, len(allParams)): + parama.append(allParams[i].split('=')) + + result = self.server.logic.doServerLogic(self.path, urlPath, parama) + self.send_response(200) + for i in range (0, len(result.headers)): + self.send_header( result.headers[i][0], result.headers[i][1] ) + self.end_headers() + self.wfile.write( result.txt )
\ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..235a560 --- /dev/null +++ b/setup.py @@ -0,0 +1,25 @@ +#!/bin/env python + +# Copyright (C) 2006, Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +from sugar.activity import bundlebuilder + +import os + +os.system("make") + +bundlebuilder.start("map")
\ No newline at end of file @@ -0,0 +1,207 @@ +# Copyright (C) 2007, One Laptop Per Child +# Copyright (c) 2008, Media Modifications Ltd. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +import gobject +import gtk +import hippo + +import sugar +from sugar.graphics import style +from sugar.graphics.palette import Palette, ToolInvoker +from sugar.graphics.toolbutton import ToolButton +from sugar.graphics.icon import Icon + +from constants import Constants + +_PREVIOUS_PAGE = 0 +_NEXT_PAGE = 1 + +class _TrayViewport(gtk.Viewport): + __gproperties__ = { + 'can-scroll' : (bool, None, None, False, + gobject.PARAM_READABLE), + } + + def __init__(self, orientation): + self.orientation = orientation + self._can_scroll = False + + gobject.GObject.__init__(self) + + self.set_shadow_type(gtk.SHADOW_NONE) + + self.traybar = gtk.Toolbar() + self.traybar.set_orientation(orientation) + self.traybar.set_show_arrow(False) + self.add(self.traybar) + self.traybar.show() + + self.connect('size_allocate', self._size_allocate_cb) + + def scroll(self, direction): + if direction == _PREVIOUS_PAGE: + self._scroll_previous() + elif direction == _NEXT_PAGE: + self._scroll_next() + + def _scroll_next(self): + if self.orientation == gtk.ORIENTATION_HORIZONTAL: + adj = self.get_hadjustment() + new_value = adj.value + self.allocation.width + adj.value = min(new_value, adj.upper - self.allocation.width) + else: + adj = self.get_vadjustment() + new_value = adj.value + self.allocation.height + adj.value = min(new_value, adj.upper - self.allocation.height) + + def _scroll_to_end(self): + if self.orientation == gtk.ORIENTATION_HORIZONTAL: + adj = self.get_hadjustment() + adj.value = adj.upper# - self.allocation.width + else: + adj = self.get_vadjustment() + adj.value = adj.upper - self.allocation.height + + def _scroll_previous(self): + if self.orientation == gtk.ORIENTATION_HORIZONTAL: + adj = self.get_hadjustment() + new_value = adj.value - self.allocation.width + adj.value = max(adj.lower, new_value) + else: + adj = self.get_vadjustment() + new_value = adj.value - self.allocation.height + adj.value = max(adj.lower, new_value) + + def do_size_request(self, requisition): + child_requisition = self.child.size_request() + if self.orientation == gtk.ORIENTATION_HORIZONTAL: + requisition[0] = 0 + requisition[1] = child_requisition[1] + else: + requisition[0] = child_requisition[0] + requisition[1] = 0 + + def do_get_property(self, pspec): + if pspec.name == 'can-scroll': + return self._can_scroll + + def _size_allocate_cb(self, viewport, allocation): + bar_requisition = self.traybar.get_child_requisition() + if self.orientation == gtk.ORIENTATION_HORIZONTAL: + can_scroll = bar_requisition[0] > allocation.width + else: + can_scroll = bar_requisition[1] > allocation.height + + if can_scroll != self._can_scroll: + self._can_scroll = can_scroll + self.notify('can-scroll') + +class _TrayScrollButton(gtk.Button): + def __init__(self, icon_name, scroll_direction): + gobject.GObject.__init__(self) + + self._viewport = None + + self._scroll_direction = scroll_direction + + self.set_relief(gtk.RELIEF_NONE) + self.set_size_request(style.GRID_CELL_SIZE, style.GRID_CELL_SIZE) + + icon = Icon(icon_name = icon_name, + icon_size=gtk.ICON_SIZE_SMALL_TOOLBAR) + self.set_image(icon) + icon.show() + + self.connect('clicked', self._clicked_cb) + + def set_viewport(self, viewport): + self._viewport = viewport + self._viewport.connect('notify::can-scroll', + self._viewport_can_scroll_changed_cb) + + def _viewport_can_scroll_changed_cb(self, viewport, pspec): + #self.props.visible = self._viewport.props.can_scroll + self.set_sensitive(self._viewport.props.can_scroll) + + def _clicked_cb(self, button): + self._viewport.scroll(self._scroll_direction) + + viewport = property(fset=set_viewport) + +class HTray(gtk.VBox): + def __init__(self, **kwargs): + gobject.GObject.__init__(self, **kwargs) + + separator = hippo.Canvas() + box = hippo.CanvasBox( + border_color=Constants.colorWhite.get_int(), + background_color=Constants.colorWhite.get_int(), + box_height=1, + border_bottom=1) + separator.set_root(box) + self.pack_start(separator, False) + + hbox = gtk.HBox() + self.pack_start(hbox) + + self.scroll_left = _TrayScrollButton('go-left', _PREVIOUS_PAGE) + self.scroll_left_event = gtk.EventBox() + self.scroll_left_event.add(self.scroll_left) + self.scroll_left_event.set_size_request(55, -1) + hbox.pack_start(self.scroll_left_event, False) + + self.viewport = _TrayViewport(gtk.ORIENTATION_HORIZONTAL) + hbox.pack_start(self.viewport) + self.viewport.show() + + self.scroll_right = _TrayScrollButton('go-right', _NEXT_PAGE) + self.scroll_right_event = gtk.EventBox() + self.scroll_right_event.add(self.scroll_right) + self.scroll_right_event.set_size_request(55, -1) + hbox.pack_start(self.scroll_right_event, False) + + self.scroll_left.set_focus_on_click(False) + self.scroll_left_event.modify_bg(gtk.STATE_NORMAL, sugar.graphics.style.COLOR_TOOLBAR_GREY.get_gdk_color()) + self.scroll_left.modify_bg(gtk.STATE_ACTIVE, sugar.graphics.style.COLOR_BUTTON_GREY.get_gdk_color()) + + self.scroll_right.set_focus_on_click(False) + self.scroll_right_event.modify_bg(gtk.STATE_NORMAL, sugar.graphics.style.COLOR_TOOLBAR_GREY.get_gdk_color()) + self.scroll_right.modify_bg(gtk.STATE_ACTIVE, sugar.graphics.style.COLOR_BUTTON_GREY.get_gdk_color()) + + self.scroll_left.viewport = self.viewport + self.scroll_right.viewport = self.viewport + + self.connect_after("size-allocate", self._sizeAllocateCb) + + def _sizeAllocateCb(self, widget, event ): + self.viewport.notify('can-scroll') + + def get_children(self): + return self.viewport.traybar.get_children() + + def add_item(self, item, index=-1): + self.viewport.traybar.insert(item, index) + + def remove_item(self, item): + self.viewport.traybar.remove(item) + + def get_item_index(self, item): + return self.viewport.traybar.get_item_index(item) + + def scroll_to_end(self): + self.viewport._scroll_to_end()
\ No newline at end of file diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..5085d66 --- /dev/null +++ b/utils.py @@ -0,0 +1,110 @@ +import base64 +import rsvg +import re +import os +import cairo +import gc +import gtk +from hashlib import md5 +import time +from time import strftime + +from sugar import util +import _camera + +def getStringFromPixbuf(pixbuf): + data = [""] + pixbuf.save_to_callback(_saveDataToBufferCb, "png", {}, data) + return base64.b64encode(str(data[0])) + + +def _saveDataToBufferCb(buf, data): + 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() + + +def loadSvg( data, stroke, fill ): + if ((stroke == None) or (fill == None)): + return rsvg.Handle( data=data ) + + entity = '<!ENTITY fill_color "%s">' % fill + data = re.sub('<!ENTITY fill_color .*>', entity, data) + + entity = '<!ENTITY stroke_color "%s">' % stroke + data = re.sub('<!ENTITY stroke_color .*>', entity, 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 ) + + +def md5File( filepath ): + 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 = _camera.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 + + svgDim = handle.get_dimension_data() + if (svgDim[0] > dim[0]): + pass + + return scale + + +def getDateString( when ): + #todo: internationalize the date + 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()) + + +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
\ No newline at end of file diff --git a/webviewer.py b/webviewer.py new file mode 100644 index 0000000..8ce8201 --- /dev/null +++ b/webviewer.py @@ -0,0 +1,148 @@ +# Copyright (C) 2006, Red Hat, Inc. +# Copyright (C) 2007, One Laptop Per Child +# Copyright (c) 2008, Media Modifications Ltd. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +from sugar import env + +import logging +import gobject +import gtk +import os +import hulahop +hulahop.startup(os.path.join(env.get_profile_path(), 'gecko')) +import xpcom +from xpcom.nsError import * +from xpcom import components +from xpcom.components import interfaces +from hulahop.webview import WebView + +#import sessionstore +#from dnd import DragDropHooks + +class WebViewer(WebView): + def __init__(self): + WebView.__init__(self) + + window_creator = WindowCreator(self) + cls = components.classes['@mozilla.org/embedcomp/window-watcher;1'] + window_watcher = cls.getService(interfaces.nsIWindowWatcher) + window_watcher.setWindowCreator(window_creator) + + self.connect('realize', self._realize_cb) + + def _realize_cb(self, widget): + #drag_drop_hooks = DragDropHooks(self) + + cls = components.classes['@mozilla.org/embedcomp/command-params;1'] + cmd_params = cls.createInstance('nsICommandParams') + #cmd_params.setISupportsValue('addhook', drag_drop_hooks) + + requestor = self.browser.queryInterface(interfaces.nsIInterfaceRequestor) + command_manager = requestor.getInterface(interfaces.nsICommandManager) + command_manager.doCommand('cmd_clipboardDragDropHook', cmd_params, self.dom_window) + + def get_session(self): + return sessionstore.get_session(self) + + def set_session(self, session_data): + return sessionstore.set_session(self, session_data) + +class WindowCreator: + _com_interfaces_ = interfaces.nsIWindowCreator + + def __init__(self, browser): + self._popup_creators = [] + self._browser = browser + + def createChromeWindow(self, parent, chrome_flags): + logging.debug('createChromeWindow: %r %r' % (parent, chrome_flags)) + + popup_creator = _PopupCreator(self._browser.get_toplevel()) + popup_creator.connect('popup-created', self._popup_created_cb) + + self._popup_creators.append(popup_creator) + + browser = popup_creator.get_embed() + + if chrome_flags & interfaces.nsIWebBrowserChrome.CHROME_OPENAS_CHROME: + logging.debug('Creating chrome window.') + browser.is_chrome = True + item = browser.browser.queryInterface(interfaces.nsIDocShellTreeItem) + item.itemType = interfaces.nsIDocShellTreeItem.typeChromeWrapper + else: + logging.debug('Creating browser window.') + item = browser.browser.queryInterface(interfaces.nsIDocShellTreeItem) + item.itemType = interfaces.nsIDocShellTreeItem.typeContentWrapper + + browser.realize() + + return browser.browser.containerWindow + + def _popup_created_cb(self, creator): + self._popup_creators.remove(creator) + +class _PopupCreator(gobject.GObject): + __gsignals__ = { + 'popup-created': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([])), + } + + def __init__(self, parent_window): + gobject.GObject.__init__(self) + + logging.debug('Creating the popup widget') + + self._parent_window = parent_window + + self._dialog = gtk.Window() + self._dialog.set_resizable(True) + + self._dialog.realize() + self._dialog.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG) + + self._embed = Browser() + self._vis_sid = self._embed.connect('notify::visible', self._notify_visible_cb) + self._dialog.add(self._embed) + + def _notify_visible_cb(self, embed, param): + self._embed.disconnect(self._vis_sid) + + if self._embed.type == Browser.TYPE_POPUP or self._embed.is_chrome: + logging.debug('Show the popup') + self._embed.show() + self._dialog.set_transient_for(self._parent_window) + self._dialog.show() + else: + logging.debug('Open a new activity for the popup') + self._dialog.remove(self._embed) + self._dialog.destroy() + self._dialog = None + + # FIXME We need a better way to handle this. + # It seem like a pretty special case though, I doubt + # other activities will need something similar. + from webactivity import WebActivity + from sugar.activity import activityfactory + from sugar.activity.activityhandle import ActivityHandle + handle = ActivityHandle(activityfactory.create_activity_id()) + activity = WebActivity(handle, self._embed) + activity.show() + + self.emit('popup-created') + + def get_embed(self): + return self._embed
\ No newline at end of file |