OSDN Git Service

update at 12/23/2018
[sawarabi-fonts/sawarabi-fonts.git] / chartool / pygtk / main.py
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3
4 import gtk
5 import os
6 import pygtk
7
8
9 class Controller:
10     def __init__(self, glade_file_path):
11         builder = gtk.Builder()
12         builder.add_from_file(glade_file_path)
13         builder.connect_signals(self)
14
15         self.entries = dict([(nm, builder.get_object("entry_%s" % nm)) \
16                                  for nm in ['search', 'code', 'name']])
17         self.search_action = SearchAction(self.entries['search'])
18         self.label_char = builder.get_object('label_char')
19         self.menu_label_char = builder.get_object('menu_label_char')
20         self.font_name = None
21         self.font_dialog = builder.get_object('fontselectiondialog')
22         self.window = builder.get_object('window_main')
23         self.window.show()
24
25         gtk.main()
26
27     def end_application(self, widget, data=None):
28         gtk.main_quit()
29         return False
30
31     def on_button_search_clicked(self, widget, data=None):
32         a = self.search_action
33         a.set_next()
34         a.put_code(self.entries['code'])
35         a.put_char(self.label_char, self.font_name)
36
37         return False
38
39     def on_entry_search_activate(self, widget, data=None):
40         self.on_button_search_clicked(widget, data)
41
42         return False
43
44     def on_label_char_button_press_event(self, widget, event=None):
45         if event.button == 3:
46             self.menu_label_char.popup(None, None, None, event.button, event.time)
47             return True
48         return False
49
50     def on_menuitem_font_activate(self, widget, event=None):
51         self.font_dialog.show()
52
53         return False
54
55     def on_fontsel_cancel_button_clicked(self, widget, data=None):
56         self.font_dialog.hide()
57
58         return False
59
60     def on_fontsel_ok_button_clicked(self, widget, data=None):
61         self.font_name = self.font_dialog.get_font_name()
62         self.font_dialog.hide()
63         self.search_action.put_char(self.label_char, self.font_name)
64
65         return False
66
67
68 class SearchAction:
69     def __init__(self, entry_search):
70         self.entry_search = entry_search
71         self.char_util = CharUtil()
72         self.code = None
73         self.char = ''
74
75     def set_next(self):
76         en = self.entry_search
77         buf = en.get_text().decode('utf-8')
78         if len(buf) == 0: return
79
80         pos = en.get_position()
81         if pos == len(buf): pos = 0
82         region = self.char_util.get_target_region(buf, pos)
83         target = buf[region[0]:region[1]]
84         en.select_region(region[0], region[1])
85         ch = self.char_util.get_unichar(target)
86
87         self.code = hex(ord(ch))
88         self.char = ch
89
90     def put_code(self, entry):
91         if not self.code: return
92
93         entry.set_text(self.code)
94
95     def put_char(self, label, font_name):
96         if not self.char: return
97         if not font_name: font_name = '80'
98
99         mu = '<span font="%s">%s</span>' % (font_name, self.char)
100         label.set_markup(mu)
101
102
103 class CharUtil:
104     def is_hex_char(self, char):
105         return (char >= '0' and char <= '9') or \
106             (char >= 'a' and char <= 'f') or \
107             (char >= 'A' and char <= 'F')
108
109     def get_unichar(self, buf):
110         if len(buf) <= 1: return buf
111
112         return unichr(int(buf, 16))
113
114     def get_target_region(self, text, pos):
115         ch = text[pos:pos + 1]
116         rlen = 0
117         llen = 0
118         while rlen <= 4 and self.is_hex_char(ch):
119             rlen += 1
120             if pos + rlen >= len(text): break
121             ch = text[(pos + rlen):(pos + rlen + 1)]
122         if rlen >= 1 and rlen < 5:
123             while rlen + llen <= 4 and pos - llen > 0:
124                 ch = text[(pos - llen - 1):(pos - llen)]
125                 if not self.is_hex_char(ch): break
126                 llen += 1
127         ret = (pos - llen, pos + rlen)
128         if ret == (pos, pos): return (pos, pos + 1)
129         return ret
130
131
132 if __name__ == '__main__':
133     path = os.path.abspath(os.path.dirname(__file__))
134     Controller(os.path.join(path, 'window_main.glade'))