Logo Search packages:      
Sourcecode: agtl version File versions  Download package

biggui.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

#     Copyright (C) 2009 Daniel Fett
#     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 3 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, see <http://www.gnu.org/licenses/>.
#
#     Author: Daniel Fett simplecaching@fragcom.de
#

 
### For the gui :-)
import math
import thread

import extListview
import geo
import geocaching
import gobject
import gtk
from htmlentitydefs import name2codepoint as n2cp
import openstreetmap
import pango
import provider
import re


class BigGui(GtkGui):
    MAP_FACTOR = 0
    CACHE_SIZE = 20
    CLICK_RADIUS = 10
    TOO_MUCH_POINTS = 400
      
      
    SETTINGS_CHECKBOXES = [
      'download_visible',
      'download_notfound',
      'download_new',
      'download_nothing',
      'download_create_index',
      'download_run_after',
      'download_resize',
      'options_show_name'
    ]
    SETTINGS_INPUTS = [
      'download_run_after_string',
      'download_output_dir',
      'download_resize_pixel',
      'options_username',
      'options_password'
    ]
      
    def __init__(self, core, pointprovider, userpointprovider):
      self.ts = ts = openstreetmap.TileServer()
            
      self.core = core
      self.pointprovider = pointprovider
      self.userpointprovider = userpointprovider
            
      self.current_cache = None
      self.dragging = False
      self.block_changes = False
            
      self.drawing_area_configured = False
      self.drag_offset_x = 0
      self.drag_offset_y = 0
      self.map_center_x, self.map_center_y = 100, 100
      self.inhibit_zoom = False
      self.draw_lock = thread.allocate_lock()
            
      global builder
            
      builder = gtk.Builder()
      builder.add_from_file("../../glade/main.glade")
      self.window = builder.get_object("window")
            
      builder.connect_signals({"on_window_destroy": self.destroy,
                        "on_zoomin_clicked": self.on_zoomin_clicked,
                        "on_zoomout_clicked": self.on_zoomout_clicked,
                        "on_download_clicked": self.on_download_clicked,
                        'save_config': self.on_save_config,
                        'on_button_download_now_clicked': self.on_download_descriptions_clicked,
                        'on_spinbutton_zoom_change_value': self.on_zoom_changed,
                        'start_search': self.on_start_search_simple,
                        'on_entry_search_key_release_event': self.on_search_simple_key_release,
                        #     'on_vscale_search_terrain_change_value' : self.search_value_terrain_change,
                        #     'on_vscale_search_diff_change_value' : self.search_value_diff_change
                        'on_button_advanced_search_clicked': self.on_search_advanced_clicked,
                        'on_check_search_find_no_details_toggled': self.on_search_details_toggled
                        })

            
      self.drawing_area = builder.get_object('drawingarea')
      self.drawing_area.connect("expose_event", self.expose_event)
      self.drawing_area.connect("configure_event", self.configure_event)
      self.drawing_area.connect("button_press_event", self.drag_start)
      self.drawing_area.connect("scroll_event", self.scroll)
      self.drawing_area.connect("button_release_event", self.drag_end)
      self.drawing_area.connect("motion_notify_event", self.drag)
      self.drawing_area.set_events(gtk.gdk.EXPOSURE_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.SCROLL)
      #self.drawing_area.show()
            
            
      self.zoom_adjustment = builder.get_object('spinbutton_zoom').get_adjustment()
            
      self.hpaned = builder.get_object("hpaned1")
      self.hpaned.set_position(0)
      self.cache_elements = {
          'name_downloaded':  builder.get_object('link_cache_name'),
          'name_not_downloaded': builder.get_object('button_cache_name'),
          'title': builder.get_object('label_cache_title'),
          'type': builder.get_object('label_cache_type'),
          'size': builder.get_object('label_cache_size'),
          'terrain': builder.get_object('label_cache_terrain'),
          'difficulty': builder.get_object('label_cache_difficulty'),
          'desc': builder.get_object('label_cache_desc'),
          'shortdesc': builder.get_object('label_cache_shortdesc'),
          'hints': builder.get_object('label_cache_hints'),
          'coords': builder.get_object('label_cache_coords'),
          'found': builder.get_object('check_cache_found'),
          'homepage': builder.get_object('link_cache_homepage'),
          'log': builder.get_object('link_cache_log'),
          'notebook': builder.get_object('notebook_cache')
      }
            
      self.search_elements = {
          'name': builder.get_object('entry_search_name'),
          'owner': builder.get_object('entry_search_owner'),
          'found': {
            'true': builder.get_object('radio_search_found_true'),
            'false': builder.get_object('radio_search_found_false')
            },
          'type': {
            'regular': builder.get_object('check_search_type_traditional'),
            'multi': builder.get_object('check_search_type_multi'),
            'unknown': builder.get_object('check_search_type_unknown'),
            'virtual': builder.get_object('check_search_type_virtual'),
            'other': builder.get_object('check_search_type_other')
            },
          'size': {
            '1': builder.get_object('check_search_size_1'),
            '2': builder.get_object('check_search_size_2'),
            '3': builder.get_object('check_search_size_3'),
            '4': builder.get_object('check_search_size_4'),
            '5': builder.get_object('check_search_size_other')
            },
          'terrain': {
            'lower': builder.get_object('vscale_search_terrain_lower'),
            'upper': builder.get_object('vscale_search_terrain_upper')
            },
          'diff': {
            'lower': builder.get_object('vscale_search_diff_lower'),
            'upper': builder.get_object('vscale_search_diff_upper')
            },
          'frames': {
            'type': builder.get_object('frame_search_type'),
            'size': builder.get_object('frame_search_size'),
            'terrain': builder.get_object('frame_search_terrain'),
            'diff': builder.get_object('frame_search_diff'),
          },
          'no_details': builder.get_object('check_search_no_details')
      }
      self.search_elements['terrain']['lower'].get_adjustment().set_value(1)
      self.search_elements['terrain']['upper'].get_adjustment().set_value(5)
      self.search_elements['diff']['lower'].get_adjustment().set_value(1)
      self.search_elements['diff']['upper'].get_adjustment().set_value(5)
            
      #
      # setting up TABLES
      #
            
      strings = self.pointprovider.get_titles_and_names()
      liststore = gtk.ListStore(gobject.TYPE_STRING)
      for string in strings:
          liststore.append([string])
      comp = builder.get_object('entrycompletion_search')
      entry = builder.get_object('entry_search')
      entry.set_completion(comp)
      comp.set_model(liststore)
      comp.set_text_column(0)
      self.entry_search = entry
            
            
      # Create the renderer used in the listview
      txtRdr    = gtk.CellRendererText()
      pixbufRdr = gtk.CellRendererPixbuf()
      (
       ROW_FOUND,
       ROW_TYPE,
       ROW_SIZE,
       ROW_TERRAIN,
       ROW_DIFF,
       ROW_ID,
       ROW_TITLE,
       ) = range(7)
      columns = (
               ('gefunden?', [(txtRdr, gobject.TYPE_STRING)], (ROW_FOUND, ROW_ID), False, True),
               ('Typ', [(txtRdr, gobject.TYPE_STRING)], (ROW_TYPE, ), False, True),
               ('Größe', [(txtRdr, gobject.TYPE_STRING)], (ROW_SIZE, ROW_ID), False, True),
               ('Terrain', [(txtRdr, gobject.TYPE_STRING)], (ROW_TERRAIN, ROW_ID), False, True),
               ('Difficulty', [(txtRdr, gobject.TYPE_STRING)], (ROW_DIFF, ROW_ID), False, True),
               ('ID', [(txtRdr, gobject.TYPE_STRING)], (ROW_ID, ), False, True),
               ('Titel', [(txtRdr, gobject.TYPE_STRING)], (ROW_TITLE, ), False, True),
               )
      self.cachelist = listview = extListview.ExtListView(columns, sortable=True, useMarkup=False, canShowHideColumns=False)
      builder.get_object('scrolledwindow_search').add(listview)
      listview.connect('extlistview-button-pressed', self.on_search_cache_clicked)
            
      # Create the renderer used in the listview for user defined points
            
      txtRdr    = gtk.CellRendererText()
      pixbufRdr = gtk.CellRendererPixbuf()
      (
       ROW_COORD,
       ROW_COMMENT,
       ) = range(2)
      columns = (
               ('Position', [(txtRdr, gobject.TYPE_STRING)], (ROW_COORD), False, True),
               ('Kommentar', [(txtRdr, gobject.TYPE_STRING)], (ROW_COMMENT, ), False, True),
               )
      self.userpointlist = extListview.ExtListView(columns, sortable=True, useMarkup=False, canShowHideColumns=False)
      builder.get_object('scrolledwindow_userpoints').add(self.userpointlist)
            
      '''
      def center(coord):
            point = self.ts.deg2num(coord)
            size = self.ts.tile_size()
            p_x = (point[0] * size - self.map_center_x * size)
            p_y = (point[1] * size - self.map_center_y * size)
            '''
      
            
    def __configure_event(self, widget, event):
      
      x, y, width, height = widget.get_allocation()
      self.map_width = int(width  + 2 * width * self.MAP_FACTOR)
      self.map_height = int(height + 2 * height * self.MAP_FACTOR)
      try:
          openstreetmap.TileLoader.drawlock.acquire()
          self.pixmap = gtk.gdk.Pixmap(widget.window, self.map_width, self.map_height)
      finally:
          openstreetmap.TileLoader.drawlock.release()
                  
      self.xgc = widget.get_style().fg_gc[gtk.STATE_NORMAL]
      #xgc.line_width = 3
      self.drawing_area_configured = True
      self.draw_at_x = 0
      self.draw_at_y = 0
      self.draw_root_x = int(-width * self.MAP_FACTOR)
      self.draw_root_y = int(-height * self.MAP_FACTOR)
      self.__draw_map()
            
    def __coord2point(self, coord):
      point = self.ts.deg2num(coord)
      size = self.ts.tile_size()
            
      p_x = int(point[0] * size - self.map_center_x * size + self.map_width / 2)
      p_y = int(point[1] * size - self.map_center_y * size + self.map_height / 2)
      return [p_x, p_y]
            
      
            
    def __decode_htmlentities(self, string):
      def substitute_entity(match):
          ent = match.group(3)
          if match.group(1) == "#":
            # decoding by number
            if match.group(2) == '':
                # number is in decimal
                return unichr(int(ent))
            elif match.group(2) == 'x':
                # number is in hex
                return unichr(int('0x' + ent, 16))
          else:
            # they were using a name
            cp = n2cp.get(ent)
            if cp:
                return unichr(cp)
            else:
                return match.group()

      entity_re = re.compile(r'&(#?)(x?)(\w+);')
      return entity_re.subn(substitute_entity, string)[0]
      
    def destroy(self, target):
      gtk.main_quit()
    # called by core
    def display_results_advanced(self, caches):
      rows = []
      for r in caches:
          if r.found:
            f = 'ja'
          else:
            f = '  '
          if r.size == -1:
            s = "?"
          else:
            s = "%d" % r.size
                        
          if r.difficulty == -1:
            d = "?"
          else:
            d = "%.1f" % r.difficulty
                        
          if r.terrain == -1:
            t = "?"
          else:
            t = "%.1f" % r.terrain
                  
          rows.append((f, r.type, s, t, d, r.name, r.title))
      self.cachelist.replaceContent(rows)
            
    def __draw_map(self):
      if not self.drawing_area_configured:
          return False
      
      if self.map_width == 0 or self.map_height == 0:
          return
      size = self.ts.tile_size()
      xi = int(self.map_center_x)
      yi = int(self.map_center_y)
      span_x = int(math.ceil(float(self.map_width) / (size * 2.0)))
      span_y = int(math.ceil(float(self.map_height) / (size * 2.0)))
      tiles = []
      for i in range(0, span_x + 1, 1):
          for j in range(0, span_y + 1, 1):
            for dir in range(0, 4, 1):
                dir_ns = dir_ew = 1
                if dir % 2 == 1: # if dir == 1 or dir == 3
                  dir_ns = -1
                if dir > 1:
                  dir_ew = -1
                        
                tile = (xi + (i * dir_ew), yi + (j * dir_ns))
                if not tile in tiles:
                  tiles.append(tile)
                  #print "Requesting ", tile, " zoom ", ts.zoom
                              
                  d = openstreetmap.TileLoader(tile, self.ts.zoom, self)
                  d.start()

            
    def __drag(self, widget, event):
      if not self.dragging:
          return
      self.drag_offset_x = self.drag_start_x - event.x
      self.drag_offset_y = self.drag_start_y - event.y
            
    def __drag_end(self, widget, event):
      if not self.dragging:
          return
      self.dragging = False
      offset_x = (self.drag_start_x - event.x)
      offset_y = (self.drag_start_y - event.y)
      if abs(offset_x) < 3 or abs(offset_y) < 3:
          x, y = event.x, event.y
          c = self.screenpoint2coord([x, y])
          c1 = self.screenpoint2coord([x-self.CLICK_RADIUS, y-self.CLICK_RADIUS])
          c2 = self.screenpoint2coord([x + self.CLICK_RADIUS, y + self.CLICK_RADIUS])
          cache = self.pointprovider.get_nearest_point_filter(c, c1, c2)
          self.core.on_cache_selected(cache)
          return
      self.map_center_x += (offset_x / self.ts.tile_size())
      self.map_center_y += (offset_y / self.ts.tile_size())
      self.__draw_map()
            
                  
    def __drag_draw(self):
      if not self.dragging:
          return False
      #if abs(self.drag_offset_x) < 3 or abs(self.drag_offset_y) < 3:
      #     return
      widget = self.drawing_area
      x, y, width, height = widget.get_allocation()
            
      widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL],
                            self.pixmap, -self.draw_at_x + self.drag_offset_x - self.draw_root_x, -self.draw_at_y + self.drag_offset_y - self.draw_root_y, 0, 0, width, height)
      return True
      
            
    def __drag_start(self, widget, event):
      self.drag_start_x = event.x
      self.drag_start_y = event.y
      self.drag_offset_x = 0
      self.drag_offset_y = 0
      self.last_drag_offset_x = 0
      self.last_drag_offset_y = 0
      self.dragging = True
      gobject.timeout_add(50, self.drag_draw)
            
            
                              
    def __draw_marks(self, thr):
      xgc = self.xgc
      """
            position = Coordinate(49.75400, 6.66135)
            target = Coordinate(49.755900, 6.649933)
            bearing = 12
            
            p = self.coord2point(position)
            if p == False:
                  return
            
            t = self.coord2point(target)
            if t == False:
                  return
            
            xgc.line_width = 5            
            xgc.set_function(gtk.gdk.AND_INVERT)
            xgc.set_rgb_fg_color(gtk.gdk.color_parse("blue"))
            self.pixmap.draw_line(xgc, p[0], p[1], t[0], t[1])
            
            xgc.line_width = 1
            length = 0.001 * (2 ** ts.zoom)
            xgc.set_function(gtk.gdk.COPY)
            xgc.set_rgb_fg_color(gtk.gdk.color_parse("blue"))
            self.pixmap.draw_line(xgc, p[0], p[1], int(p[0] + math.cos(bearing) * length), int(p[1] + math.sin(bearing) * length))
            """
            
      #
      # draw geocaches
      #
            
      coords = self.pointprovider.get_points_filter((self.pixmappoint2coord([0, 0]), self.pixmappoint2coord([self.map_width, self.map_height])))
      draw_short = (len(coords) > self.TOO_MUCH_POINTS)

      xgc.set_function(gtk.gdk.AND)
      radius = 7
      color_default = gtk.gdk.color_parse('blue')
      color_found = gtk.gdk.color_parse('grey')
      color_regular = gtk.gdk.color_parse('green')
      color_multi = gtk.gdk.color_parse('orange')
      font = pango.FontDescription("Sans 8")
      num = 0
      for c in coords: # for each geocache
          color = color_default
          if c.found:
            color = color_found
          elif c.type == "regular":
            color = color_regular
          elif c.type == "multi":
            color = color_multi
                  
          p = self.__coord2point(c)
          xgc.set_rgb_fg_color(color)
                  
          xgc.line_width = 1
          self.pixmap.draw_line(xgc, p[0], p[1] - 2, p[0], p[1] + 3) #  |
          self.pixmap.draw_line(xgc, p[0] - 2, p[1], p[0] + 3, p[1]) # ---
                  
          if draw_short:
            continue
          xgc.line_width = 3
          self.pixmap.draw_rectangle(xgc, False, p[0] - radius, p[1] - radius, radius * 2, radius * 2)
                  
          # print the name?
          if self.settings['options_show_name']:
            layout = self.drawing_area.create_pango_layout(c.name)
            layout.set_font_description(font)
            self.pixmap.draw_layout(xgc, p[0] + 3 + radius, p[1] - 3 - radius, layout)
                  
          # if we have a description for this cache...
          if c.was_downloaded():
            # draw something like:
            # ----
            # ----
            # ----
            # besides the icon
            width = 6
            dist = 2
            pos_x = p[0] + radius + 3 + 1
            pos_y = p[1] + 2
            xgc.line_width = 1
            for i in range(0, 3):
                self.pixmap.draw_line(xgc, pos_x, pos_y + dist * i, pos_x + width, pos_y + dist * i)
                  
          # if this cache is the active cache
          if self.current_cache != None and c.name == self.current_cache.name:
            xgc.line_width = 1
            xgc.set_rgb_fg_color(gtk.gdk.color_parse('black'))
            radius = 8
            self.pixmap.draw_rectangle(xgc, False, p[0] - radius, p[1] - radius, radius * 2, radius * 2)
                  

      # draw additional waypoints
      # --> print description!
      if self.current_cache != None and self.current_cache.waypoints != None:
          xgc.set_function(gtk.gdk.AND)
          xgc.set_rgb_fg_color(gtk.gdk.color_parse('red'))
          num = 0
          for w in self.current_cache.waypoints:
            if w['lat'] != -1 and w['lon'] != -1:
                num = num + 1
                xgc.line_width = 1
                radius = 4
                p = self.__coord2point(geo.Coordinate(w['lat'], w['lon']))
                self.pixmap.draw_line(xgc, p[0], p[1] - 3, p[0], p[1] + 4) #  |
                self.pixmap.draw_line(xgc, p[0] - 3, p[1], p[0] + 4, p[1]) # ---
                self.pixmap.draw_arc(xgc, False, p[0] - radius, p[1] - radius, radius * 2, radius * 2, 0, 360 * 64)
                layout = self.drawing_area.create_pango_layout('')
                layout.set_markup('<i>%s</i>' % (w['id']))
                layout.set_font_description(font)
                self.pixmap.draw_layout(xgc, p[0] + 3 + radius, p[1] - 3 - radius, layout)
            
                  
      #
      # next, draw the user defined points
      #
            
      coords = self.userpointprovider.get_points_filter((self.pixmappoint2coord([0, 0]), self.pixmappoint2coord([self.map_width, self.map_height])))

      xgc.set_function(gtk.gdk.AND)
      radius = 7
      color = gtk.gdk.color_parse('darkorchid')
      for c in coords: # for each geocache
          p = self.__coord2point(c)
          xgc.line_width = 3
          xgc.set_rgb_fg_color(color)
          radius = 8
          self.pixmap.draw_line(xgc, p[0] - radius, p[1], p[0], p[1] + radius)
          self.pixmap.draw_line(xgc, p[0], p[1] + radius, p[0] + radius, p[1])
          self.pixmap.draw_line(xgc, p[0] + radius, p[1], p[0], p[1] - radius)
          self.pixmap.draw_line(xgc, p[0], p[1] - radius, p[0] - radius, p[1])
          xgc.line_width = 1
          self.pixmap.draw_line(xgc, p[0], p[1] - 2, p[0], p[1] + 3) #  |
          self.pixmap.draw_line(xgc, p[0] - 2, p[1], p[0] + 3, p[1]) # ---
          layout = self.drawing_area.create_pango_layout(c.name)
          layout.set_font_description(font)
          self.pixmap.draw_layout(xgc, p[0] + 3 + radius, p[1] - 3 - radius, layout)
            
      """
            xgc.line_width = 2      
            radius_o = 20
            radius_i = 7
            xgc.set_function(gtk.gdk.INVERT)
            xgc.set_rgb_fg_color(gtk.gdk.color_parse("black"))
            self.pixmap.draw_line(xgc, t[0] - radius_o, t[1], t[0] - radius_i, t[1])
            self.pixmap.draw_line(xgc, t[0] + radius_o, t[1], t[0] + radius_i, t[1])
            self.pixmap.draw_line(xgc, t[0], t[1] + radius_o, t[0], t[1] + radius_i)
            self.pixmap.draw_line(xgc, t[0], t[1] - radius_o, t[0], t[1] - radius_i)
            
            xgc.set_function(gtk.gdk.INVERT)
            self.pixmap.draw_point(xgc, t[0], t[1])
            """
            
      xgc.set_rgb_fg_color(gtk.gdk.color_parse("black"))
      xgc.set_function(gtk.gdk.COPY)
      self.refresh()
      return False
      
    def expose_event(self, widget, event):
      x, y, width, height = event.area
      try:
          openstreetmap.TileLoader.drawlock.acquire()
          widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL],
                              self.pixmap, x, y, self.draw_root_x + self.draw_at_x  + x, self.draw_root_y + self.draw_at_y + y, -1, -1)
          # width, height hier?
      finally:
          openstreetmap.TileLoader.drawlock.release()
      return False

    def get_visible_area(self):
      return (self.pixmappoint2coord([0, 0]), self.pixmappoint2coord([self.map_width, self.map_height]))
            
            
    def on_download_descriptions_clicked(self, something):
      self.core.on_download_descriptions(self.get_visible_area())
      self.__draw_map()
            
    def on_download_clicked(self, something):
      self.core.on_download(self.get_visible_area())
      self.__draw_map()
                              
    def on_save_config(self, something):
      if not self.block_changes:
          self.core.on_config_changed(self.read_settings())
            
    def on_search_advanced_clicked(self, something):
      if self.search_elements['found']['true'].get_active():
          found = True
      elif self.search_elements['found']['false'].get_active():
          found = False
      else:
          found = None
            
      owner_search = self.search_elements['owner'].get_text()
      name_search = self.search_elements['name'].get_text()
            
      if not self.search_elements['type']['other'].get_active():
          ctype = []
          for type, el in self.search_elements['type'].items():
            if el.get_active():
                ctype.append(type)
      else:
          ctype = None
                  
      if not self.search_elements['no_details'].get_active():
          size = []
          for s in range(1, 6):
            if self.search_elements['size'][str(s)].get_active():
                size.append(s)
                        
          terrain = [self.search_elements['terrain']['lower'].get_adjustment().get_value(),
            self.search_elements['terrain']['upper'].get_adjustment().get_value()]
          diff = [self.search_elements['diff']['lower'].get_adjustment().get_value(),
            self.search_elements['diff']['upper'].get_adjustment().get_value()]
      else:
          size = terrain = diff = None
      self.core.on_start_search_advanced(found, owner_search, name_search, size, terrain, diff, ctype)

            
    def on_search_details_toggled(self, some=None):
      for k, i in self.search_elements['frames'].items():
          if k != 'type':
            i.set_sensitive(not self.search_elements['no_details'].get_active())

    def on_search_cache_clicked(self, listview, event, element):
      if event.type != gtk.gdk._2BUTTON_PRESS or element == None:
          return
            
      cachename = listview.getItem(element[0], 5)
      cache = self.pointprovider.find_by_string(cachename)
      self.core.on_cache_selected(cache)
            
            
    def on_search_key_release(self, widget, event):
      print event.keyval
      if event.keyval == 65293:  # seems to be keycode of return key
          self.core.on_start_search_simple(self.widget.get_text())
            
    def on_search_simple_key_release(self, something):
      self.core.on_start_search_simple(self.widget.get_text())
            
            
    def on_start_search_simple(self, something):
      self.core.on_start_search_simple(self.entry_search.get_text())
                  
    def on_zoom_changed(self, blub):
      if not self.inhibit_zoom:
          self.zoom()
            
    def on_zoomin_clicked(self, widget):
      self.zoom( + 1)
            
    def on_zoomout_clicked(self, widget):
      self.zoom(-1)
      
    def pixmappoint2coord(self, point):
      size = self.ts.tile_size()
      coord = self.ts.num2deg(
                        (point[0] + self.map_center_x * size - self.map_width / 2) / size,
                        (point[1] + self.map_center_y * size - self.map_height / 2) / size
                        )
      return coord

    def read_settings(self):
      c = self.ts.num2deg(self.map_center_x, self.map_center_y)
      settings = {
          'map_position_lat': c.lat,
          'map_position_lon': c.lon
      }
      for x in self.SETTINGS_CHECKBOXES:
          settings[x] = builder.get_object('check_%s' % x).get_active()
            
      for x in self.SETTINGS_INPUTS:
          settings[x] = builder.get_object('input_%s' % x).get_text()
            
      self.settings = settings
      return settings
                  
            
    def refresh(self):
      self.drawing_area.queue_draw()
                  
    def replace_image_tag(self, m):
      if m.group(1) != None and m.group(1).strip() != '':
          return ' [Bild: %s] ' % m.group(1).strip()
      else:
          return ' [Bild] '
                  
    def screenpoint2coord(self, point):
      size = self.ts.tile_size()
      coord = self.ts.num2deg(
                        ((point[0] - self.draw_root_x - self.draw_at_x) + self.map_center_x * size - self.map_width / 2) / size,
                        ((point[1] - self.draw_root_y - self.draw_at_y) + self.map_center_y * size - self.map_height / 2) / size
                        )
      return coord
      
    def scroll(self, widget, event):
      if event.direction == gtk.gdk.SCROLL_DOWN:
          self.zoom(-1)
      else:
          self.zoom( + 1)
    def show(self):
      self.window.show_all()
      gtk.main()
            
                  
    # called by core
    def show_cache(self, cache):
      if cache == None:
          self.hpaned.set_position(0)
          return
      self.current_cache = cache
      self.hpaned.set_position(-1)
      if cache.was_downloaded():
          uri = 'file://%s/%s.html' % (self.settings['download_output_dir'], cache.name)
          self.cache_elements['name_downloaded'].set_uri(uri)
          self.cache_elements['name_downloaded'].set_label(cache.name)
          self.cache_elements['name_downloaded'].show()
          self.cache_elements['name_not_downloaded'].hide()
      else:
          self.cache_elements['name_not_downloaded'].set_label(cache.name)
          self.cache_elements['name_downloaded'].hide()
          self.cache_elements['name_not_downloaded'].show()
      self.cache_elements['title'].set_text(cache.title)
      self.cache_elements['type'].set_text("%s" % cache.type)
      self.cache_elements['size'].set_text("%d/5" % cache.size)
      self.cache_elements['terrain'].set_text("%.1f/5" % (cache.terrain / 10.0))
      self.cache_elements['difficulty'].set_text("%.1f/5" % (cache.difficulty / 10.0))
            
      set_page = False
            
      text_shortdesc = self.__strip_html(cache.shortdesc).strip()[:600]
      if text_shortdesc == '':
          text_shortdesc = '(Keine Kurzbeschreibung vorhanden)'
      else:
          self.cache_elements['notebook'].set_current_page(0)
          set_page = True
                  
      text_desc = self.__strip_html(cache.desc).strip()[:600]
      if text_desc == '':
          text_desc = '(Keine Beschreibung vorhanden)'
      if not set_page:
          self.cache_elements['notebook'].set_current_page(1)
                  
      text_hints = cache.hints.strip()
      if text_hints == '':
          text_hints = '(Keine Hints vorhanden)'
                  
      text_coords = 'Start: %s\n' % cache
      for w in cache.waypoints:
          if not (w['lat'] == -1 and w['lon'] == -1):
            n = geo.Coordinate(w['lat'], w['lon'])
            latlon = "%s %s" % (re.sub(r' ', '', n.get_lat(geo.Coordinate.FORMAT_DM)), re.sub(r' ', '', n.get_lon(geo.Coordinate.FORMAT_DM)))
          else:
            latlon = "???"
          text_coords += "<b>%s</b> <tt>%s</tt> <i>%s</i>\n<small>%s</small>" % (w['id'], latlon, w['name'], w['comment'])
                  
      self.cache_elements['desc'].set_text(text_desc)
      self.cache_elements['shortdesc'].set_text(text_shortdesc)
      self.cache_elements['hints'].set_text(text_hints)
      self.cache_elements['coords'].set_use_markup(True)
      self.cache_elements['coords'].set_text(text_coords)
      self.cache_elements['found'].set_active(cache.found)
      self.cache_elements['homepage'].set_uri('http://www.geocaching.com/seek/cache_details.aspx?wp=%s' % cache.name)
      self.cache_elements['log'].set_uri('http://www.geocaching.com/seek/log.aspx?wp=%s' % cache.name)
            
            
    def set_center(self, coord):
      builder.get_object("notebook_all").set_current_page(0)
      self.map_center_x, self.map_center_y = self.ts.deg2num(coord)
      self.draw_at_x = 0
      self.draw_at_y = 0
      self.__draw_map()

      
    def __strip_html(self, text):
      text = re.sub(r"""(?i)<img[^>]+alt=["']?([^'"> ]+)[^>]+>""", self.replace_image_tag, text)
      text = re.sub(r'<[^>]*?>', '', text)
      text = self.__decode_htmlentities(text)
      text = re.sub(r'[\n\r]+\s*[\n\r]+', '\n', text)
      return text
            
    def write_settings(self, settings):
      self.settings = settings
      self.block_changes = True
      self.set_center(geo.Coordinate(self.settings['map_position_lat'], self.settings['map_position_lon']))

      for x in self.SETTINGS_CHECKBOXES:
          if x in self.settings.keys():
            builder.get_object('check_%s' % x).set_active(self.settings[x])
          elif x in self.DEFAULT_SETTINGS.keys():
            builder.get_object('check_%s' % x).set_active(self.DEFAULT_SETTINGS[x])
      
      for x in self.SETTINGS_INPUTS:
          if x in self.settings.keys():
            builder.get_object('input_%s' % x).set_text(str(self.settings[x]))
          elif x in self.DEFAULT_SETTINGS.keys():
            builder.get_object('input_%s' % x).set_text(self.DEFAULT_SETTINGS[x])
                              
      self.block_changes = False
            
    def zoom(self, direction=None):
      size = self.ts.tile_size()
      center = self.ts.num2deg(self.map_center_x - float(self.draw_at_x) / size, self.map_center_y - float(self.draw_at_y) / size)
      if direction == None:
          newzoom = self.zoom_adjustment.get_value()
      else:
          newzoom = self.ts.get_zoom() + direction
      self.ts.set_zoom(newzoom)
      self.inhibit_zoom = True
      self.zoom_adjustment.set_value(self.ts.get_zoom())
      self.inhibit_zoom = False
      self.set_center(center)

Generated by  Doxygen 1.6.0   Back to index