1# 2# Gramps - a GTK+/GNOME based genealogy program 3# 4# Copyright (C) 2000-2006 Donald N. Allingham 5# 6# This program is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 2 of the License, or 9# (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; if not, write to the Free Software 18# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19# 20 21__all__ = ["LinkLabel", "EditLabel", "BasicLabel", "GenderLabel", 22 "MarkupLabel", "DualMarkupLabel"] 23 24#------------------------------------------------------------------------- 25# 26# Standard python modules 27# 28#------------------------------------------------------------------------- 29import os 30from html import escape 31from gramps.gen.const import GRAMPS_LOCALE as glocale 32_ = glocale.translation.gettext 33import logging 34_LOG = logging.getLogger(".widgets.labels") 35 36#------------------------------------------------------------------------- 37# 38# GTK/Gnome modules 39# 40#------------------------------------------------------------------------- 41from gi.repository import Gdk 42from gi.repository import Gtk 43from gi.repository import Pango 44 45#------------------------------------------------------------------------- 46# 47# Gramps modules 48# 49#------------------------------------------------------------------------- 50from gramps.gen.constfunc import has_display, win 51from ..utils import get_link_color 52 53#------------------------------------------------------------------------- 54# 55# Constants 56# 57#------------------------------------------------------------------------- 58if has_display(): 59 HAND_CURSOR = Gdk.Cursor.new_for_display(Gdk.Display.get_default(), 60 Gdk.CursorType.HAND2) 61 62#------------------------------------------------------------------------- 63# 64# Module functions 65# 66#------------------------------------------------------------------------- 67def realize_cb(widget): 68 widget.get_window().set_cursor(HAND_CURSOR) 69 70#------------------------------------------------------------------------- 71# 72# LinkLabel class 73# 74#------------------------------------------------------------------------- 75class LinkLabel(Gtk.EventBox): 76 77 def __init__(self, label, func, handle, emph=False, theme="CLASSIC"): 78 self.theme = theme 79 self.emph = emph 80 81 Gtk.EventBox.__init__(self) 82 83 st_cont = self.get_style_context() 84 self.color = get_link_color(st_cont) 85 86 if emph: 87 #emphasize a link 88 if theme == "CLASSIC": 89 format = 'underline="single" weight="heavy" style="italic"' 90 elif theme == "WEBPAGE": 91 format = 'foreground="' + self.color + '" weight="heavy"' 92 else: 93 raise AttributeError("invalid theme: '%s'" % theme) 94 elif emph is None: 95 #emphasize, but not a link 96 if theme == "CLASSIC": 97 format = 'weight="heavy"' 98 elif theme == "WEBPAGE": 99 format = 'weight="heavy"' 100 else: 101 raise AttributeError("invalid theme: '%s'" % theme) 102 else: 103 #no emphasize, a link 104 if theme == "CLASSIC": 105 format = 'underline="single"' 106 elif theme == "WEBPAGE": 107 format = 'foreground="' + self.color + '"' 108 else: 109 raise AttributeError("invalid theme: '%s'" % theme) 110 111 self.orig_text = escape(label[0]) 112 self.gender = label[1] 113 self.decoration = format 114 text = '<span %s>%s</span>' % (self.decoration, self.orig_text) 115 116 if func: 117 msg = _('Click to make this person active\n' 118 'Right click to display the edit menu\n' 119 'Click Edit icon (enable in configuration dialog) to edit') 120 121 self.set_tooltip_text(msg) 122 123 self.label = Gtk.Label(label=text) 124 self.label.set_use_markup(True) 125 self.label.set_halign(Gtk.Align.START) 126 127 hbox = Gtk.Box() 128 hbox.pack_start(self.label, False, False, 0) 129 if label[1]: 130 hbox.pack_start(GenderLabel(label[1]), False, False, 0) 131 hbox.set_spacing(4) 132 self.add(hbox) 133 134 if func: 135 self.connect('button-press-event', func, handle) 136 self.connect('enter-notify-event', self.enter_text, handle) 137 self.connect('leave-notify-event', self.leave_text, handle) 138 self.connect('realize', realize_cb) 139 140 def set_padding(self, x, y): 141 self.label.set_padding(x, y) 142 143 def enter_text(self, obj, event, handle): 144 if self.emph: 145 #emphasize a link 146 if self.theme == "CLASSIC": 147 format = 'foreground="' + self.color + '" underline="single" '\ 148 'weight="heavy" style="italic"' 149 elif self.theme == "WEBPAGE": 150 format = 'underline="single" foreground="' + self.color + '" '\ 151 'weight="heavy"' 152 else: 153 raise AttributeError("invalid theme: '%s'" % self.theme) 154 elif self.emph is None: 155 # no link, no change on enter_text 156 if self.theme == "CLASSIC": 157 format = 'weight="heavy"' 158 elif self.theme == "WEBPAGE": 159 format = 'weight="heavy"' 160 else: 161 raise AttributeError("invalid theme: '%s'" % self.theme) 162 else: 163 #no emphasize, a link 164 if self.theme == "CLASSIC": 165 format = 'foreground="' + self.color + '" underline="single"' 166 elif self.theme == "WEBPAGE": 167 format = 'underline="single" foreground="' + self.color + '"' 168 else: 169 raise AttributeError("invalid theme: '%s'" % self.theme) 170 171 text = '<span %s>%s</span>' % (format, self.orig_text) 172 self.label.set_text(text) 173 self.label.set_use_markup(True) 174 175 def leave_text(self, obj, event, handle): 176 text = '<span %s>%s</span>' % (self.decoration, self.orig_text) 177 self.label.set_text(text) 178 self.label.set_use_markup(True) 179 180#------------------------------------------------------------------------- 181# 182# EditLabel class 183# 184#------------------------------------------------------------------------- 185class EditLabel(Gtk.Box): 186 def __init__(self, text): 187 Gtk.Box.__init__(self) 188 label = BasicLabel(text) 189 self.pack_start(label, False, True, 0) 190 self.pack_start(Gtk.Image.new_from_icon_name('gtk-edit', 191 Gtk.IconSize.MENU), False) 192 self.set_spacing(4) 193 self.show_all() 194 195#------------------------------------------------------------------------- 196# 197# BasicLabel class 198# 199#------------------------------------------------------------------------- 200class BasicLabel(Gtk.Label): 201 202 def __init__(self, text, ellipsize=Pango.EllipsizeMode.NONE): 203 Gtk.Label.__init__(self, label=text) 204 self.set_halign(Gtk.Align.START) 205 self.set_ellipsize(ellipsize) 206 self.show() 207 208#------------------------------------------------------------------------- 209# 210# GenderLabel class 211# 212#------------------------------------------------------------------------- 213class GenderLabel(Gtk.Label): 214 215 def __init__(self, text): 216 Gtk.Label.__init__(self, label=text) 217 self.set_halign(Gtk.Align.START) 218 if win(): 219 pangoFont = Pango.FontDescription('Arial') 220 self.override_font(pangoFont) 221 self.show() 222 223#------------------------------------------------------------------------- 224# 225# MarkupLabel class 226# 227#------------------------------------------------------------------------- 228class MarkupLabel(Gtk.Label): 229 230 def __init__(self, text, halign=Gtk.Align.START): 231 Gtk.Label.__init__(self, label=text) 232 self.set_halign(halign) 233 self.set_use_markup(True) 234 self.show_all() 235 236#------------------------------------------------------------------------- 237# 238# DualMarkupLabel class 239# 240#------------------------------------------------------------------------- 241class DualMarkupLabel(Gtk.Box): 242 243 def __init__(self, text, alt, halign=Gtk.Align.START): 244 Gtk.Box.__init__(self) 245 label = Gtk.Label(label=text) 246 label.set_halign(halign) 247 label.set_use_markup(True) 248 249 self.pack_start(label, False, False, 0) 250 b = GenderLabel(alt) 251 b.set_use_markup(True) 252 self.pack_start(b, False, False, 4) 253 self.show() 254