-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgnome_utils_ctypes.py
More file actions
273 lines (165 loc) · 8.93 KB
/
gnome_utils_ctypes.py
File metadata and controls
273 lines (165 loc) · 8.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# ctypes implementation for access to gnome-utils
import os
import sys
from gi.repository import GObject
import pdb
from ctypes.util import find_library
from ctypes import *
from pygobjectcapi import PyGObjectCAPI
import gnucash_log
from date_ctypes import TM as TM
# junkily define this for the moment
# define a function equivalent to N_ for internationalization
def N_(msg):
return msg
#gboolean = c_byte
gboolean = c_int
gpointer = c_void_p
guint = c_uint
gsize = c_uint
GType = gsize
time64 = c_ulonglong
# find core-utils then add gnucash to path to get to gnome-utuils
libgnccorenm = find_library("libgnc-core-utils")
if libgnccorenm is None:
raise RuntimeError("Can't find a libgnc-core-utils library to use.")
libpth = os.path.dirname(libgnccorenm)
libgnc_gnomeutilnm = os.path.join(libpth,"gnucash","libgncmod-gnome-utils.dylib")
if not os.path.exists(libgnc_gnomeutilnm):
pdb.set_trace()
raise RuntimeError("Can't find a libgncmod-gnome-utils library to use.")
libgnc_gnomeutils = CDLL(libgnc_gnomeutilnm)
# Im undecided how to partition these calls as gnome-utils has calls for a lot
# of different objects
# for the moment Im going to move the call definitions into the python
# ctypes module for an object
# only generic calls will be done here
libgnc_gnomeutils.gnc_shutdown.argtypes = [ c_int ]
libgnc_gnomeutils.gnc_shutdown.restype = None
# oh boy - by missing the restype this screws up using the return
# - you get a different integer - ah - because the default return is a c_int
# but a pointer on 64 bit machine is not a c_int - the address gets truncated
# even though the resulting python type is an integer in both cases
libgnc_gnomeutils.gnc_gui_init.argtypes = []
libgnc_gnomeutils.gnc_gui_init.restype = c_void_p
# do not use this - use the function in gnc_main_window
def gnc_gui_init ():
print("WARNING WARNING - should NOT be calling this routine", file=sys.stderr)
# OK - this does work if I use the right restype for gnc_gui_init!!
# note that the gnc_gui_init just returns main window object pointer
# if already called - we assume gnc_gui_init has already been called here
main_window_ptr = libgnc_gnomeutils.gnc_gui_init()
gnucash_log.dbglog_err("gnc_gui_init: main_window_ptr %x"%main_window_ptr)
#pdb.set_trace()
# now understand what the problem is
# although the following converts the GType to a python gobject
# it ONLY covers the GType data - it does NOT appear to apply the functions
# that is a GType class consists of data and functions
# (this is because we need to register a python object type to be associated
# with a GType via pygobject C function pygobject_register_class)
# using pygobject_new (mapped to to_object) wraps the data but not the functions - as they are
# defined as simple C functions
# to add the functions to the python gobject looks like we need to define
# new python functions which call the underlying C functions from the library
# using ctypes
# call like this:
Cgobject = PyGObjectCAPI()
main_window = Cgobject.to_object(main_window_ptr)
pdb.set_trace()
return main_window
libgnc_gnomeutils.gnc_window_set_progressbar_window.argtypes = [ c_void_p ]
libgnc_gnomeutils.gnc_window_set_progressbar_window.restype = None
libgnc_gnomeutils.gnc_window_get_progressbar_window.argtypes = []
libgnc_gnomeutils.gnc_window_get_progressbar_window.restype = c_void_p
libgnc_gnomeutils.gnc_window_show_progress.argtypes = [ c_char_p, c_double ]
libgnc_gnomeutils.gnc_window_show_progress.restype = None
libgnc_gnomeutils.gnc_tree_view_account_get_view_info.argtypes = [ c_void_p, c_void_p ]
libgnc_gnomeutils.gnc_tree_view_account_get_view_info.restype = c_void_p
libgnc_gnomeutils.gnc_tree_view_account_set_view_info.argtypes = [ c_void_p, c_void_p ]
libgnc_gnomeutils.gnc_tree_view_account_set_view_info.restype = None
libgnc_gnomeutils.gnc_tree_view_account_get_cursor_account.argtypes = [ c_void_p ]
libgnc_gnomeutils.gnc_tree_view_account_get_cursor_account.restype = c_void_p
libgnc_gnomeutils.gnc_tree_view_account_select_subaccounts.argtypes = [ c_void_p, c_void_p ]
libgnc_gnomeutils.gnc_tree_view_account_select_subaccounts.restype = None
libgnc_gnomeutils.gnc_tree_view_account_set_selected_accounts.argtypes = [ c_void_p, c_void_p ]
libgnc_gnomeutils.gnc_tree_view_account_set_selected_accounts.restype = None
libgnc_gnomeutils.gnc_tree_view_account_get_selected_accounts.argtypes = [ c_void_p ]
libgnc_gnomeutils.gnc_tree_view_account_get_selected_accounts.restype = c_void_p
libgnc_gnomeutils.gnc_tree_view_account_get_selected_account.argtypes = [ c_void_p ]
libgnc_gnomeutils.gnc_tree_view_account_get_selected_account.restype = c_void_p
libgnc_gnomeutils.gnc_tree_view_account_new_with_root.argtypes = [ c_void_p, c_bool ]
libgnc_gnomeutils.gnc_tree_view_account_new_with_root.restype = c_void_p
libgnc_gnomeutils.gnc_tree_view_account_new.argtypes = [ c_bool ]
libgnc_gnomeutils.gnc_tree_view_account_new.restype = c_void_p
libgnc_gnomeutils.gnc_tree_model_account_types_new.argtypes = [ c_uint ]
libgnc_gnomeutils.gnc_tree_model_account_types_new.restype = c_void_p
libgnc_gnomeutils.gnc_tree_model_account_types_filter_using_mask.argtypes = [ c_uint ]
libgnc_gnomeutils.gnc_tree_model_account_types_filter_using_mask.restype = c_void_p
libgnc_gnomeutils.gnc_tree_model_account_types_set_mask.argtypes = [ c_void_p, c_uint ]
libgnc_gnomeutils.gnc_tree_model_account_types_set_mask.restype = None
libgnc_gnomeutils.gnc_tree_model_account_types_get_mask.argtypes = [ c_void_p ]
libgnc_gnomeutils.gnc_tree_model_account_types_get_mask.restype = c_uint
libgnc_gnomeutils.gnc_tree_model_account_types_get_selection.argtypes = [ c_void_p ]
libgnc_gnomeutils.gnc_tree_model_account_types_get_selection.restype = c_uint
libgnc_gnomeutils.gnc_tree_model_account_types_get_selection_single.argtypes = [ c_void_p ]
libgnc_gnomeutils.gnc_tree_model_account_types_get_selection_single.restype = c_uint
libgnc_gnomeutils.gnc_tree_model_account_types_set_selection.argtypes = [ c_void_p, c_uint ]
libgnc_gnomeutils.gnc_tree_model_account_types_set_selection.restype = None
libgnc_gnomeutils.gnc_date_edit_get_type.argtypes = []
libgnc_gnomeutils.gnc_date_edit_get_type.restype = GType
libgnc_gnomeutils.gnc_date_edit_new.argtypes = [ time64, c_int, c_int ]
libgnc_gnomeutils.gnc_date_edit_new.restype = c_void_p
libgnc_gnomeutils.gnc_handle_date_accelerator.argtypes = [ c_void_p, c_void_p, c_char_p ]
libgnc_gnomeutils.gnc_handle_date_accelerator.restype = c_bool
# renamed essentially in 3.2 to gnc_ui_get_main_window
#libgnc_gnomeutils.gnc_ui_get_toplevel.argtypes = []
#libgnc_gnomeutils.gnc_ui_get_toplevel.restype = c_void_p
libgnc_gnomeutils.gnc_ui_get_main_window.argtypes = [ c_void_p ]
libgnc_gnomeutils.gnc_ui_get_main_window.restype = c_void_p
# this definition needs to be here as otherwise get circular definitions
# if in gnc_main_window.py
#def ui_get_toplevel ():
def ui_get_main_window (widget):
#global Cgobject
ui_top_ptr = libgnc_gnomeutils.gnc_ui_get_main_window(None)
if ui_top_ptr != None:
# need to wrap returned gtk widget
Cgobject = PyGObjectCAPI()
ui_toplevel = Cgobject.to_object(ui_top_ptr)
else:
ui_toplevel = None
return ui_toplevel
# in python 3 we need to do unicode <-> conversion
# so specific implementation here - remove all external access via gnome_utils_ctypes.libgnc_gnomeutils.gnc_window_show_progress
def window_show_progress (progress_str, percnt):
libgnc_gnomeutils.gnc_window_show_progress(progress_str.encode('utf-8'), percnt)
def gnc_handle_date_accelerator (event, dttm, txtstr):
event_ptr = hash(event)
tm_ptr = ctypes.addressof(dttm)
retval = gnome_utils_ctypes.libgnc_gnomeutils.gnc_handle_date_accelerator(event_ptr,tm_ptr,txtstr.encode('utf-8'))
return retval
# unfortunately gnc_error_dialog uses variable argument lists
# for the moment lets reimplement in python - its pretty trivial
# this does mean need to import Gtk here
# also just pass string
from gi.repository import Gtk
def gnc_error_dialog (parent, errmsg):
if parent == None:
parent = gnc_ui_get_main_window(None)
dialog = Gtk.MessageDialog(parent,Gtk.DialogFlags.DIALOG_MODAL|Gtk.DialogFlags.DESTROY_WITH_PARENT,
Gtk.MessageType.ERROR,Gtk.ButtonsType.CLOSE,N_(errmsg))
if parent == None:
dialog.set_skip_taskbar_hint(False)
dialog.show()
dialog.destroy()
def gnc_verify_dialog (parent, yes_is_default, errmsg):
if parent == None:
parent = gnc_ui_get_main_window(None)
dialog = Gtk.MessageDialog(parent,Gtk.DialogFlags.MODAL|Gtk.DialogFlags.DESTROY_WITH_PARENT,
Gtk.MessageType.QUESTION,Gtk.ButtonsType.YES_NO,N_(errmsg))
if parent == None:
dialog.set_skip_taskbar_hint(False)
dialog.set_default_response(Gtk.ResponseType.YES if yes_is_default else Gtk.ResponseType.NO)
result = dialog.run()
dialog.destroy()
return result == Gtk.ResponseType.YES