Attributes display with correct namespaces.
[dom-editor.git] / Dome / Namespaces.py
blob4aead1d0adde0596c3df2956756308341ebc5f84
1 from xml.dom import XMLNS_NAMESPACE, XML_NAMESPACE
2 from constants import DOME_NS
4 import rox
5 from rox import g
7 fixed_ns = {'xml': XML_NAMESPACE, 'xmlns': XMLNS_NAMESPACE,
8 'dome': DOME_NS}
10 common_ns = {'http://www.w3.org/1999/xhtml': 'xhtml',
11 'http://www.w3.org/1999/02/22-rdf-syntax-ns#': 'rdf',
12 'http://xmlns.4suite.org/ext': 'ft',
13 'http://www.w3.org/1999/XMLSchema': 'xsd',
14 'http://www.w3.org/1999/XMLSchema-instance': 'xsi',
15 'http://schemas.xmlsoap.org/soap/envelope/': 'env'}
17 class Namespaces(g.GenericTreeModel):
18 def __init__(self):
19 g.GenericTreeModel.__init__(self)
20 self.uri = dict(fixed_ns)
21 self.update_list()
23 def update_list(self):
24 self.list = self.uri.keys()
25 self.list.sort()
26 pre = self.prefix = {}
27 for p, u in self.uri.iteritems():
28 pre[u] = p
30 def on_get_n_columns(self):
31 return 2
33 def on_get_iter(self, path):
34 assert len(path) == 1
35 return path[0]
37 def on_get_value(self, iter, column):
38 if column == 0:
39 return self.list[iter]
40 return self.uri[self.list[iter]]
42 def on_iter_nth_child(self, iter, n):
43 if iter == None:
44 return n
45 return None
47 def on_get_column_type(self, col):
48 return str
50 def on_iter_has_child(self, iter):
51 return False
53 def on_iter_next(self, iter):
54 if iter < len(self.list) - 1:
55 return iter + 1
57 def __setitem__(self, prefix, uri):
58 if prefix in self.uri and self.uri[prefix] == uri:
59 return
61 assert prefix
62 if prefix in fixed_ns:
63 raise Exception('That namespace prefix cannot be changed')
65 modifed = prefix in self.uri
67 self.uri[prefix] = uri
68 self.update_list()
69 path = (self.list.index(prefix),)
71 if modifed:
72 self.emit('row-changed', path, self.get_iter(path))
73 else:
74 self.emit('row-inserted', path, self.get_iter(path))
76 def __delitem__(self, iter):
77 prefix = self[iter][0]
78 if prefix in fixed_ns:
79 raise Exception('This is a built-in namespace and cannot be deleted')
80 path = (self.list.index(prefix),)
81 del self.uri[prefix]
82 self.update_list()
83 self.emit('row-deleted', path)
85 def ensure_ns(self, suggested_prefix, uri):
86 """Return the prefix for this URI. If none is set choose one (using suggested_prefix
87 if possible)."""
88 try:
89 return self.prefix[uri]
90 except KeyError:
91 if not suggested_prefix:
92 suggested_prefix = common_ns.get(uri, 'ns')
93 if suggested_prefix in self.uri:
94 x = 1
95 while suggested_prefix + `x` in self.uri: x += 1
96 suggested_prefix += `x`
97 self[suggested_prefix] = uri
98 print "Added", suggested_prefix, uri
99 return suggested_prefix
101 def to_xml(self, doc):
102 node = doc.createElementNS(DOME_NS, 'dome:namespaces')
103 for prefix, uri in self.uri.iteritems():
104 if prefix in fixed_ns: continue
105 ns = doc.createElementNS(DOME_NS, 'dome:ns')
106 ns.setAttributeNS(None, 'prefix', prefix)
107 ns.setAttributeNS(None, 'uri', uri)
108 node.appendChild(ns)
109 return node
111 class GUI(rox.Dialog):
112 def __init__(self, model):
113 rox.Dialog.__init__(self)
114 self.model = model
116 self.add_button(g.STOCK_ADD, 1)
117 self.add_button(g.STOCK_DELETE, 2)
118 self.add_button(g.STOCK_CLOSE, g.RESPONSE_OK)
120 tree = g.TreeView(model.namespaces)
122 def response(dialog, resp):
123 if resp == 1:
124 dialog.add_new(model.namespaces)
125 elif resp == 2:
126 dialog.delete_selected(tree.get_selection())
127 else:
128 dialog.destroy()
129 self.connect('response', response)
130 self.set_position(g.WIN_POS_MOUSE)
131 self.set_title('Namespaces for ' + `model.uri`)
133 frame = g.Frame()
134 frame.add(tree)
135 frame.set_shadow_type(g.SHADOW_IN)
137 cell = g.CellRendererText()
138 column = g.TreeViewColumn('Prefix', cell, text = 0)
139 tree.append_column(column)
141 column = g.TreeViewColumn('URI', cell, text = 1)
142 tree.append_column(column)
144 frame.show_all()
146 self.vbox.pack_start(frame, True, True)
147 self.set_default_size(400, 200)
149 self.set_has_separator(False)
151 def delete_selected(self, sel):
152 model, iter = sel.get_selected()
153 if not iter:
154 rox.alert('Select a namespace binding to delete')
155 return
156 try:
157 del model[iter]
158 except:
159 rox.report_exception()
161 def add_new(self, ns):
162 d = rox.Dialog()
164 hbox = g.HBox(False, 2)
165 d.vbox.pack_start(hbox, False, True)
166 hbox.pack_start(g.Label('Prefix:'), False, True, 0)
167 prefix = g.Entry()
168 hbox.pack_start(prefix, True, True, 0)
170 def check_prefix(entry):
171 if not uri.get_text():
172 pre = prefix.get_text()
173 for u, p in common_ns.iteritems():
174 if p == pre:
175 uri.set_text(u)
176 break
177 uri.grab_focus()
179 prefix.connect('activate', check_prefix)
181 hbox = g.HBox(False, 2)
182 d.vbox.pack_start(hbox, False, True)
183 hbox.pack_start(g.Label('Namespace URI:'), False, True, 0)
184 uri = g.Entry()
185 hbox.pack_start(uri, True, True, 0)
186 uri.set_activates_default(True)
188 d.vbox.show_all()
189 d.set_position(g.WIN_POS_MOUSE)
191 prefix.grab_focus()
193 d.add_button(g.STOCK_CANCEL, g.RESPONSE_CANCEL)
194 d.add_button(g.STOCK_OK, g.RESPONSE_OK)
196 d.set_default_response(g.RESPONSE_OK)
198 if d.run() != g.RESPONSE_OK:
199 d.destroy()
200 return
201 try:
202 ns[prefix.get_text()] = uri.get_text()
203 except:
204 rox.report_exception()
205 d.destroy()