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