pyvguicom 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyvguicom might be problematic. Click here for more details.

@@ -0,0 +1,90 @@
1
+ Metadata-Version: 2.1
2
+ Name: pyvguicom
3
+ Version: 1.0.0
4
+ Summary: High power secure server GUI utility helpers.
5
+ Home-page: https://github.com/pglen/pyvserv
6
+ Author: Peter Glen
7
+ Author-email: peterglen99@gmail.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3
12
+ Description-Content-Type: text/markdown
13
+
14
+ # pyvguicom PyV GUI Common utilities
15
+
16
+ ## Common GUI routines and classes
17
+
18
+ These classes are for python PyGobject (Gtk) development. They are used in
19
+ several projects. They act as a simplification front end for the PyGtk / PyGobject
20
+ classes.
21
+
22
+ A sampler of what is in there (pasted from code, in no particular order):
23
+
24
+ class CairoHelper():
25
+ class TextTable(Gtk.Table):
26
+ class TextRow(Gtk.HBox):
27
+ class RadioGroup(Gtk.Frame):
28
+ class Led(Gtk.DrawingArea):
29
+ class SeparatorMenuItem(Gtk.SeparatorMenuItem):
30
+ class Menu():
31
+ class MenuButt(Gtk.DrawingArea):
32
+ class Lights(Gtk.Frame):
33
+ class WideButt(Gtk.Button):
34
+ class ScrollListBox(Gtk.Frame):
35
+ class TextRow(Gtk.HBox):
36
+ class RadioGroup(Gtk.Frame):
37
+ class Led(Gtk.DrawingArea):
38
+ class Lights(Gtk.Frame):
39
+ class FrameTextView(Gtk.TextView):
40
+ class Label(Gtk.Label):
41
+ class Logo(Gtk.VBox):
42
+ class xSpacer(Gtk.HBox):
43
+ class ScrollListBox(Gtk.Frame):
44
+ class ListBox(Gtk.TreeView):
45
+
46
+ ... and a lot more ...
47
+
48
+ ## Also includes python / Gtk primitives:
49
+
50
+ def get_screen_wh():
51
+ def get_screen_xy():
52
+ def print_exception(xstr):
53
+ def message(strx, parent = None, title = None, icon = Gtk.MessageType.INFO):
54
+ def usleep(msec):
55
+ def tmpname(indir, template):
56
+ def mainloop():
57
+ def time_n2s(ttt):
58
+ def time_s2n(sss):
59
+ def yes_no_cancel(title, message, cancel = True, parent = None):
60
+ def yn_key(win, event, cancel):
61
+ def opendialog(parent=None):
62
+ def savedialog(resp):
63
+ def leadspace(strx):
64
+
65
+ ... and a lot more ...
66
+
67
+ ## Example:
68
+
69
+ The Label Button (smallbutt) takes a constructor, and feeds
70
+ the arguments with defaults as one would expect.
71
+
72
+ def __init__(self, textm="", widget=None, tooltip=None, font=None):
73
+
74
+ The simplification effect allows one to create a smallbutt with no arguments,
75
+ and still have a somewhat reasonable outcome. The label example is trivial,
76
+ the simplification takes a new dimension with classes like SimpleTree.
77
+
78
+ The defaults are set to a reasonable value, and the named argument(s) can be
79
+ set on one line. This makes the code look more compact and maintainable.
80
+
81
+ ## Tests:
82
+
83
+ The test utilities can confirm correct operation; however being a visual
84
+ set of classes, the real test is seeing the generated UI.
85
+
86
+ See descendent projects for more examples. (pyedpro; pycal; pggui; ...)
87
+
88
+ Peter Glen
89
+
90
+ // EOF
@@ -0,0 +1,77 @@
1
+ # pyvguicom PyV GUI Common utilities
2
+
3
+ ## Common GUI routines and classes
4
+
5
+ These classes are for python PyGobject (Gtk) development. They are used in
6
+ several projects. They act as a simplification front end for the PyGtk / PyGobject
7
+ classes.
8
+
9
+ A sampler of what is in there (pasted from code, in no particular order):
10
+
11
+ class CairoHelper():
12
+ class TextTable(Gtk.Table):
13
+ class TextRow(Gtk.HBox):
14
+ class RadioGroup(Gtk.Frame):
15
+ class Led(Gtk.DrawingArea):
16
+ class SeparatorMenuItem(Gtk.SeparatorMenuItem):
17
+ class Menu():
18
+ class MenuButt(Gtk.DrawingArea):
19
+ class Lights(Gtk.Frame):
20
+ class WideButt(Gtk.Button):
21
+ class ScrollListBox(Gtk.Frame):
22
+ class TextRow(Gtk.HBox):
23
+ class RadioGroup(Gtk.Frame):
24
+ class Led(Gtk.DrawingArea):
25
+ class Lights(Gtk.Frame):
26
+ class FrameTextView(Gtk.TextView):
27
+ class Label(Gtk.Label):
28
+ class Logo(Gtk.VBox):
29
+ class xSpacer(Gtk.HBox):
30
+ class ScrollListBox(Gtk.Frame):
31
+ class ListBox(Gtk.TreeView):
32
+
33
+ ... and a lot more ...
34
+
35
+ ## Also includes python / Gtk primitives:
36
+
37
+ def get_screen_wh():
38
+ def get_screen_xy():
39
+ def print_exception(xstr):
40
+ def message(strx, parent = None, title = None, icon = Gtk.MessageType.INFO):
41
+ def usleep(msec):
42
+ def tmpname(indir, template):
43
+ def mainloop():
44
+ def time_n2s(ttt):
45
+ def time_s2n(sss):
46
+ def yes_no_cancel(title, message, cancel = True, parent = None):
47
+ def yn_key(win, event, cancel):
48
+ def opendialog(parent=None):
49
+ def savedialog(resp):
50
+ def leadspace(strx):
51
+
52
+ ... and a lot more ...
53
+
54
+ ## Example:
55
+
56
+ The Label Button (smallbutt) takes a constructor, and feeds
57
+ the arguments with defaults as one would expect.
58
+
59
+ def __init__(self, textm="", widget=None, tooltip=None, font=None):
60
+
61
+ The simplification effect allows one to create a smallbutt with no arguments,
62
+ and still have a somewhat reasonable outcome. The label example is trivial,
63
+ the simplification takes a new dimension with classes like SimpleTree.
64
+
65
+ The defaults are set to a reasonable value, and the named argument(s) can be
66
+ set on one line. This makes the code look more compact and maintainable.
67
+
68
+ ## Tests:
69
+
70
+ The test utilities can confirm correct operation; however being a visual
71
+ set of classes, the real test is seeing the generated UI.
72
+
73
+ See descendent projects for more examples. (pyedpro; pycal; pggui; ...)
74
+
75
+ Peter Glen
76
+
77
+ // EOF
File without changes
@@ -0,0 +1,263 @@
1
+ #!/usr/bin/env python
2
+
3
+ ''' This encapsulates the browser window wit the webkia an toolbars '''
4
+
5
+ import os, sys, getopt, signal, random, time, warnings
6
+
7
+ realinc = os.path.realpath(os.path.dirname(__file__) + os.sep + "../pycommon")
8
+ sys.path.append(realinc)
9
+
10
+ from pgutils import *
11
+ from pggui import *
12
+ from pgsimp import *
13
+
14
+ import gi
15
+ gi.require_version("Gtk", "3.0")
16
+ #gi.require_version('WebKit2', '4.0')
17
+
18
+ from gi.repository import Gtk
19
+ from gi.repository import Gdk
20
+ from gi.repository import GLib
21
+ from gi.repository import GObject
22
+ from gi.repository import Pango
23
+
24
+ ret = ""
25
+
26
+ try:
27
+ import pgwkit
28
+ except:
29
+ print("Cannot load WebKit2", sys.exc_info())
30
+ sys.exit(1)
31
+
32
+ class brow_win(Gtk.VBox):
33
+
34
+ ''' Collection of URL bar, toolbar, status bar '''
35
+
36
+ def __init__(self):
37
+
38
+ try:
39
+ Gtk.VBox.__init__(self)
40
+ except:
41
+ pass
42
+
43
+ # TEST Mnemonic Label
44
+ #bbb = Gtk.Button.new_with_mnemonic("_Hello")
45
+ #self.pack_start(bbb, 0, 0, 0)
46
+
47
+ hbox3 = self.urlbar()
48
+ self.pack_start(hbox3, 0, 0, 0)
49
+
50
+ #if not conf.kiosk:
51
+ # vbox.pack_start(hbox3, False, False, 2)
52
+
53
+ self.scroll_win = Gtk.ScrolledWindow()
54
+
55
+ try:
56
+ self.webview = pgwkit.pgwebw(self)
57
+ except:
58
+ print("Please install webkit2")
59
+ #sys.exit(1)
60
+ raise
61
+
62
+ #self.old_html = ""
63
+ self.scroll_win.add(self.webview)
64
+ self.webview.editor = self.webview
65
+
66
+ self.toolbar2 = self.webview.ui.get_widget("/toolbar_format")
67
+ self.pack_start(self.toolbar2, False, False, 0)
68
+
69
+ self.pack_start(self.scroll_win, 1, 1, 2)
70
+
71
+ hbox5 = Gtk.HBox()
72
+ hbox5.pack_start(Gtk.Label(" "), 0, 0, 0)
73
+ self.status = Gtk.Label(" Idle ");
74
+ self.status.set_xalign(0)
75
+
76
+ hbox5.pack_start(self.status, 1, 1, 0)
77
+ hbox5.pack_start(Gtk.Label(" "), 0, 0, 0)
78
+ self.set_status(" Idle State ")
79
+
80
+ self.pack_start(hbox5, 0, 0, 2)
81
+
82
+ #self.add_events(Gdk.EventMask.ALL_EVENTS_MASK)
83
+ #self.set_sensitive(True)
84
+
85
+ # Receive key presses
86
+ self.set_can_focus(True)
87
+ #self.grab_focus()
88
+
89
+ def load_html(self, strx):
90
+ self.webview.load_html(strx)
91
+
92
+ def cut(self):
93
+ #print("cut")
94
+ self.webview.on_action("cut")
95
+
96
+ def copy(self):
97
+ #print("copy")
98
+ self.webview.on_action("copy")
99
+
100
+ def paste(self):
101
+ #print("paste")
102
+ self.webview.on_paste()
103
+ #self.webview.on_action("paste")
104
+
105
+ def open(self):
106
+ dialog = Gtk.FileChooserDialog("Open an HTML file", None,
107
+ Gtk.FileChooserAction.OPEN,
108
+ (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
109
+ Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
110
+
111
+ ret = dialog.run()
112
+ fn = dialog.get_filename()
113
+ dialog.destroy()
114
+
115
+ if ret == Gtk.ResponseType.OK:
116
+ if not fn:
117
+ return
118
+ if os.path.exists(fn):
119
+ self.fname = fn
120
+ with open(fn) as fd:
121
+ self.webview.load_html(fd.read(), "file:///")
122
+
123
+ def save(self):
124
+
125
+ #print("brow_win", "save", self.fname)
126
+ def completion(html, user_data):
127
+ #print("len html", len(html), len(self.webview.old_html) )
128
+ #print("html", html, "old", self.webview.old_html )
129
+ #if self.webview.old_html == html:
130
+
131
+ if not self.webview.modified:
132
+ self.set_status("File NOT modified.") # '%s'" % self.fname)
133
+ else:
134
+ #self.webview.old_html = html
135
+ open_mode = user_data
136
+ with open(self.fname, open_mode) as fd:
137
+ fd.write(html)
138
+ self.set_status("Saved file '%s'" % self.fname)
139
+ self.webview.modified = False
140
+ self.webview.get_html(completion, 'w')
141
+
142
+ def is_modified(self):
143
+ return self.webview.modified
144
+
145
+ def _completion(self, html, user_data):
146
+ self.ret = html
147
+ self.done = True
148
+ self.webview.modified = False
149
+ #print("retx", ret)
150
+
151
+ def get_content(self):
152
+ self.done = 0; self.ret = ""
153
+ self.webview.get_html(self._completion, "w")
154
+ # Wait until done is set
155
+ for aa in range(1000):
156
+ if self.done:
157
+ break
158
+ Gtk.main_iteration_do(False)
159
+ return self.ret
160
+
161
+ def saveas(self):
162
+ def completion(html, user_data):
163
+ open_mode = user_data
164
+ with open(self.fname, open_mode) as fd:
165
+ fd.write(html)
166
+ self.set_status("Saved as '%s'" % self.fname)
167
+
168
+ dialog = Gtk.FileChooserDialog("Select an HTML file", None,
169
+ Gtk.FileChooserAction.SAVE,
170
+ (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
171
+ Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
172
+
173
+ if dialog.run() == Gtk.ResponseType.OK:
174
+ self.fname = dialog.get_filename()
175
+ #print("Saving", self.fname)
176
+ self.webview.get_html(completion, "w+")
177
+ dialog.destroy()
178
+
179
+ def url_callb(self, xtxt):
180
+ self.webview.go(xtxt)
181
+
182
+ def url_callb(self, xtxt):
183
+ self.go(xtxt)
184
+
185
+ def backurl(self, url, parm, buff):
186
+ self.webview.go_back()
187
+
188
+ def baseurl(self, url, parm, buff):
189
+ self.webview.load_uri("file://" + self.fname)
190
+
191
+ def forwurl(self, url, parm, buff):
192
+ self.webview.go_forward()
193
+
194
+ #def gourl(self, url, parm, buff):
195
+ def gourl(self, *url):
196
+ print("gourl", *url)
197
+ self.go(self.edit.get_text())
198
+
199
+ def go(self, xstr):
200
+ print("go", xstr)
201
+
202
+ # Leave known URL scemes alone
203
+ if xstr[:7] == "file://":
204
+ sss = os.path.realpath(xstr[7:])
205
+ xstr = "file://" + sss
206
+ pass
207
+ elif xstr[:7] == "http://":
208
+ pass
209
+ elif xstr[:8] == "https://":
210
+ pass
211
+ elif xstr[:6] == "ftp://":
212
+ pass
213
+ elif str.isdecimal(xstr[0]):
214
+ #print("Possible IP")
215
+ pass
216
+ else:
217
+ # Yeah, padd it
218
+ xstr = "https://" + xstr
219
+
220
+ self.webview.load_uri(xstr)
221
+
222
+ def stattime(self, *arg):
223
+ self.status.set_text("Idle.")
224
+
225
+ def set_status(self, xtxt):
226
+ self.status.set_text(xtxt)
227
+ GLib.timeout_add(3000, self.stattime, self, 0)
228
+
229
+ def urlbar(self):
230
+
231
+ self.edit = SimpleEdit();
232
+ self.edit.setsavecb(self.url_callb)
233
+ self.edit.single_line = True
234
+
235
+ hbox3 = Gtk.HBox()
236
+ uuu = Gtk.Label(" URL: ")
237
+ uuu.set_tooltip_text("Current / New URL; press Enter to go")
238
+ hbox3.pack_start(uuu, 0, 0, 0)
239
+
240
+ hbox3.pack_start(self.edit, True, True, 2)
241
+
242
+ bbb = LabelButt(" _Go ", self.gourl, "Go to speified URL")
243
+ #bbb = Gtk.Button.new_with_mnemonic(" _Go ") #, self.gourl, "Go to speified URL")
244
+ #bbb.connect("clicked", self.gourl)
245
+
246
+ #bbb = LabelButt(" _Go ", self.gourl, "Go to speified URL")
247
+ ccc = LabelButt(" <-_Back ", self.backurl, "Go Back")
248
+ ddd = LabelButt(" For_w-> ", self.forwurl, "Go Forw")
249
+ eee = LabelButt(" B_ase ", self.baseurl, "Go to base URL")
250
+
251
+ hbox3.pack_start(Gtk.Label(" "), 0, 0, 0)
252
+
253
+ hbox3.pack_start(bbb, 0, 0, 0)
254
+ hbox3.pack_start(ccc, 0, 0, 0)
255
+ hbox3.pack_start(ddd, 0, 0, 0)
256
+ hbox3.pack_start(eee, 0, 0, 0)
257
+
258
+ #hbox3.pack_start(Gtk.Label(" ^ "), 0, 0, 0)
259
+ hbox3.pack_start(Gtk.Label(" "), 0, 0, 0)
260
+
261
+ return hbox3
262
+
263
+ # EOF
@@ -0,0 +1,252 @@
1
+ import os
2
+ import gi
3
+
4
+ gi.require_version("Gtk", "3.0")
5
+ gi.require_version('WebKit2', '4.0')
6
+ from gi.repository import Gtk, Gdk, WebKit2
7
+
8
+ class HtmlEditor(Gtk.Widget):
9
+
10
+ def __init__(self):
11
+ super().__init__()
12
+
13
+ #self.set_title("Html Editor")
14
+ #self.connect("destroy", Gtk.main_quit)
15
+ self.resize(500, 500)
16
+ self.filename = None
17
+
18
+ self.editor = WebKit2.WebView()
19
+ self.editor.set_editable(True)
20
+ self.editor.load_html("", "file:///")
21
+
22
+ self.scroll = Gtk.ScrolledWindow()
23
+ self.scroll.add(self.editor)
24
+ self.scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
25
+
26
+ self.ui = self.generate_ui()
27
+ self.add_accel_group(self.ui.get_accel_group())
28
+ self.toolbar1 = self.ui.get_widget("/toolbar_main")
29
+ self.toolbar2 = self.ui.get_widget("/toolbar_format")
30
+ self.menubar = self.ui.get_widget("/menubar_main")
31
+
32
+ self.layout = Gtk.VBox()
33
+ self.layout.pack_start(self.menubar, False, False, 0)
34
+ self.layout.pack_start(self.toolbar1, False, False, 0)
35
+ self.layout.pack_start(self.toolbar2, False, False, 0)
36
+ self.layout.pack_start(self.scroll, True, True, 0)
37
+ self.add(self.layout)
38
+
39
+ #self.layout.pack_start(self.editor.get_inspector(), True, True, 0)
40
+ #self.inspect = WebKit2.WebInspector()
41
+ #self.inspect.attach()
42
+ #self.editor.get_inspector().attach()
43
+
44
+ self.editor.get_settings().set_property("enable_developer_extras", True)
45
+ #self.editor.get_inspector().set_property("height", 200)
46
+ #self.editor.get_inspector().show()
47
+ #print("hhh", self.editor.get_inspector().get_attached_height())
48
+
49
+ def generate_ui(self):
50
+ ui_def = """
51
+ <ui>
52
+ <menubar name="menubar_main">
53
+ <menu action="menuFile">
54
+ <menuitem action="new" />
55
+ <menuitem action="open" />
56
+ <menuitem action="save" />
57
+ </menu>
58
+ <menu action="menuEdit">
59
+ <menuitem action="cut" />
60
+ <menuitem action="copy" />
61
+ <menuitem action="paste" />
62
+ </menu>
63
+ <menu action="menuInsert">
64
+ <menuitem action="insertimage" />
65
+ </menu>
66
+ <menu action="menuFormat">
67
+ <menuitem action="bold" />
68
+ <menuitem action="italic" />
69
+ <menuitem action="underline" />
70
+ <menuitem action="strikethrough" />
71
+ <separator />
72
+ <menuitem action="font" />
73
+ <menuitem action="color" />
74
+ <separator />
75
+ <menuitem action="justifyleft" />
76
+ <menuitem action="justifyright" />
77
+ <menuitem action="justifycenter" />
78
+ <menuitem action="justifyfull" />
79
+ </menu>
80
+ </menubar>
81
+ <toolbar name="toolbar_main">
82
+ <toolitem action="new" />
83
+ <toolitem action="open" />
84
+ <toolitem action="save" />
85
+ <separator />
86
+ <toolitem action="undo" />
87
+ <toolitem action="redo" />
88
+ <separator />
89
+ <toolitem action="cut" />
90
+ <toolitem action="copy" />
91
+ <toolitem action="paste" />
92
+ </toolbar>
93
+ <toolbar name="toolbar_format">
94
+ <toolitem action="bold" />
95
+ <toolitem action="italic" />
96
+ <toolitem action="underline" />
97
+ <toolitem action="strikethrough" />
98
+ <separator />
99
+ <toolitem action="font" />
100
+ <toolitem action="color" />
101
+ <separator />
102
+ <toolitem action="justifyleft" />
103
+ <toolitem action="justifyright" />
104
+ <toolitem action="justifycenter" />
105
+ <toolitem action="justifyfull" />
106
+ <separator />
107
+ <toolitem action="insertimage" />
108
+ <toolitem action="insertlink" />
109
+ </toolbar>
110
+ </ui>
111
+ """
112
+
113
+ actions = Gtk.ActionGroup("Actions")
114
+ actions.add_actions([
115
+ ("menuFile", None, "_File"),
116
+ ("menuEdit", None, "_Edit"),
117
+ ("menuInsert", None, "_Insert"),
118
+ ("menuFormat", None, "_Format"),
119
+
120
+ ("new", Gtk.STOCK_NEW, "_New", None, None, self.on_new),
121
+ ("open", Gtk.STOCK_OPEN, "_Open", None, None, self.on_open),
122
+ ("save", Gtk.STOCK_SAVE, "_Save", None, None, self.on_save),
123
+
124
+ ("undo", Gtk.STOCK_UNDO, "_Undo", None, None, self.on_action),
125
+ ("redo", Gtk.STOCK_REDO, "_Redo", None, None, self.on_action),
126
+
127
+ ("cut", Gtk.STOCK_CUT, "_Cut", None, None, self.on_action),
128
+ ("copy", Gtk.STOCK_COPY, "_Copy", None, None, self.on_action),
129
+ ("paste", Gtk.STOCK_PASTE, "_Paste", None, None, self.on_paste),
130
+
131
+ ("bold", Gtk.STOCK_BOLD, "_Bold", "<ctrl>B", None, self.on_action),
132
+ ("italic", Gtk.STOCK_ITALIC, "_Italic", "<ctrl>I", None, self.on_action),
133
+ ("underline", Gtk.STOCK_UNDERLINE, "_Underline", "<ctrl>U", None, self.on_action),
134
+ ("strikethrough", Gtk.STOCK_STRIKETHROUGH, "_Strike", "<ctrl>T", None, self.on_action),
135
+ ("font", Gtk.STOCK_SELECT_FONT, "Select _Font", "<ctrl>F", None, self.on_select_font),
136
+ ("color", Gtk.STOCK_SELECT_COLOR, "Select _Color", None, None, self.on_select_color),
137
+
138
+ ("justifyleft", Gtk.STOCK_JUSTIFY_LEFT, "Justify _Left", None, None, self.on_action),
139
+ ("justifyright", Gtk.STOCK_JUSTIFY_RIGHT, "Justify _Right", None, None, self.on_action),
140
+ ("justifycenter", Gtk.STOCK_JUSTIFY_CENTER, "Justify _Center", None, None, self.on_action),
141
+ ("justifyfull", Gtk.STOCK_JUSTIFY_FILL, "Justify _Full", None, None, self.on_action),
142
+
143
+ ("insertimage", "insert-image", "Insert _Image", None, None, self.on_insert_image),
144
+ ("insertlink", "insert-link", "Insert _Link", None, None, self.on_insert_link),
145
+ ])
146
+
147
+ actions.get_action("insertimage").set_property("icon-name", "insert-image")
148
+ actions.get_action("insertlink").set_property("icon-name", "insert-link")
149
+
150
+ ui = Gtk.UIManager()
151
+ ui.insert_action_group(actions)
152
+ ui.add_ui_from_string(ui_def)
153
+ return ui
154
+
155
+ def on_action(self, action):
156
+ self.editor.run_javascript("document.execCommand('%s', false, false);" % action.get_name())
157
+
158
+ def on_paste(self, action):
159
+ self.editor.execute_editing_command(WebKit2.EDITING_COMMAND_PASTE)
160
+
161
+ def on_new(self, action):
162
+ self.editor.load_html("", "file:///")
163
+
164
+ def on_select_font(self, action):
165
+ dialog = Gtk.FontChooserDialog("Select a font")
166
+ if dialog.run() == Gtk.ResponseType.OK:
167
+ fname = dialog.get_font_desc().get_family()
168
+ fsize = dialog.get_font_desc().get_size()
169
+ self.editor.run_javascript("document.execCommand('fontname', null, '%s');" % fname)
170
+ self.editor.run_javascript("document.execCommand('fontsize', null, '%s');" % fsize)
171
+ dialog.destroy()
172
+
173
+ def on_select_color(self, action):
174
+ dialog = Gtk.ColorChooserDialog("Select Color")
175
+ if dialog.run() == Gtk.ResponseType.OK:
176
+ (r, g, b, a) = dialog.get_rgba()
177
+ color = "#%0.2x%0.2x%0.2x%0.2x" % (
178
+ int(r * 255),
179
+ int(g * 255),
180
+ int(b * 255),
181
+ int(a * 255))
182
+ self.editor.run_javascript("document.execCommand('forecolor', null, '%s');" % color)
183
+ dialog.destroy()
184
+
185
+ def on_insert_link(self, action):
186
+ dialog = Gtk.Dialog("Enter a URL:", self, 0,
187
+ (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OK, Gtk.ResponseType.OK))
188
+
189
+ entry = Gtk.Entry()
190
+ dialog.vbox.pack_start(entry, False, False, 0)
191
+ dialog.show_all()
192
+
193
+ if dialog.run() == Gtk.ResponseType.OK:
194
+ self.editor.run_javascript(
195
+ "document.execCommand('createLink', true, '%s');" % entry.get_text())
196
+ dialog.destroy()
197
+
198
+ def on_insert_image(self, action):
199
+ dialog = Gtk.FileChooserDialog("Select an image file", self, Gtk.FileChooserAction.OPEN,
200
+ (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
201
+
202
+ if dialog.run() == Gtk.ResponseType.OK:
203
+ fn = dialog.get_filename()
204
+ if os.path.exists(fn):
205
+ self.editor.run_javascript(
206
+ "document.execCommand('insertImage', null, '%s');" % fn)
207
+ dialog.destroy()
208
+
209
+ def on_open(self, action):
210
+ dialog = Gtk.FileChooserDialog("Select an HTML file", self, Gtk.FileChooserAction.OPEN,
211
+ (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
212
+
213
+ if dialog.run() == Gtk.ResponseType.OK:
214
+ fn = dialog.get_filename()
215
+ if os.path.exists(fn):
216
+ self.filename = fn
217
+ with open(fn) as fd:
218
+ self.editor.load_html(fd.read(), "file:///")
219
+ dialog.destroy()
220
+
221
+ def on_save(self, action):
222
+ def completion(html, user_data):
223
+ open_mode = user_data
224
+ with open(self.filename, open_mode) as fd:
225
+ fd.write(html)
226
+
227
+ if self.filename:
228
+ self.get_html(completion, 'w')
229
+ else:
230
+ dialog = Gtk.FileChooserDialog("Select an HTML file", self, Gtk.FileChooserAction.SAVE,
231
+ (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
232
+
233
+ if dialog.run() == Gtk.ResponseType.OK:
234
+ self.filename = dialog.get_filename()
235
+ self.get_html(completion, "w+")
236
+ dialog.destroy()
237
+
238
+ def get_html(self, completion_function, user_data):
239
+ def javascript_completion(obj, result, user_data):
240
+ html = self.editor.get_title()
241
+ completion_function(html, user_data)
242
+ self.editor.run_javascript("document.title=document.documentElement.innerHTML;",
243
+ None,
244
+ javascript_completion,
245
+ user_data)
246
+
247
+ #e = HtmlEditor()
248
+ #e.show_all()
249
+ #e.scroll.grab_focus()
250
+ #Gtk.main()
251
+
252
+ # EOF