11 import dbus.mainloop.glib
15 ##=================================================================
18 #signal handler #1 for Manager
19 def manager_Added(self, name):
20 print (" Added %s") % name
21 self.manager_getDetails()
23 #signal handler #2 for Manager
24 def manager_Removed(self, name):
25 print (" Removed %s") % name
26 if self.adapters_remove is not None:
27 self.adapter_update(name)
30 #connect to the manager in order to be notified on
32 def manager_Connect(self):
34 manager_obj = self.systemBus.get_object('org.neard', "/")
35 # Add 2 handlers to follow Adapters
36 manager_obj.connect_to_signal('AdapterAdded',
39 manager_obj.connect_to_signal('AdapterRemoved',
42 self.iface_manager = dbus.Interface(manager_obj, 'org.neard.Manager')
45 print ("Can't connect to org.neard.Manager");
46 self.iface_manager = None
47 #Retrieve the manager informations
48 self.manager_getDetails()
50 def manager_getDetails(self):
51 #No iface_manager means adapter removed
52 if self.iface_manager is None:
53 if self.adapters_remove is not None:
54 self.adapters_remove()
56 #Need to update adapter's details
57 self.adapter_updateDetails(self.iface_manager.GetProperties())
59 def adapter_PropertyChanged(self, prop, value, adapt_path = None):
60 print("Prop changed: %s") % prop
62 adapt_properties[prop] = value
64 self.tag_updateDetails(adapt_properties)
66 self.adapter_update(adapt_path, adapt_properties)
68 #Update the records UI
69 def record_updateDetails(self, tag_properties):
70 for record_path in tag_properties["Records"]:
71 print ("REC %s ") % record_path
72 record_obj = self.systemBus.get_object('org.neard',
74 record_iface = dbus.Interface(record_obj,'org.neard.Record')
75 record_properties = record_iface.GetProperties()
77 self.recordregistered[record_path] = True
80 self.records_update(record_path, record_properties)
83 def tag_updateDetails(self, adapt_properties):
84 if adapt_properties["Tags"]:
85 for tag_path in adapt_properties["Tags"]:
86 print ("TAG %s ") % tag_path
87 tag_obj = self.systemBus.get_object('org.neard', tag_path)
89 tag_iface = dbus.Interface(tag_obj,'org.neard.Tag')
90 tag_properties = tag_iface.GetProperties()
92 self.tagregistered[tag_path] = True
94 self.tags_update(tag_path, tag_properties)
96 self.record_updateDetails(tag_properties)
98 print ("remove tags and records")
100 self.records_update()
103 #Something changed, must update the UI
104 def adapter_updateDetails(self, properties):
105 if self.adapter_update is not None and "Adapters" in properties:
106 for adapt_path in properties["Adapters"]:
107 if adapt_path in self.adaptregistered:
108 print (" already registered %s") % adapt_path
110 #Get valuable informations from the object
111 adapter_obj = self.systemBus.get_object('org.neard',
113 adapter_obj.connect_to_signal('PropertyChanged',
114 self.adapter_PropertyChanged,
116 path_keyword='adapt_path')
118 adapt_iface = dbus.Interface(adapter_obj,'org.neard.Adapter')
119 adapt_properties = adapt_iface.GetProperties()
121 self.adaptregistered[adapt_path] = True
124 self.adapter_update(adapt_path, adapt_properties)
127 self.tag_updateDetails(adapt_properties)
130 #Search DBUS to find any neard instance
131 def neardNameOwnerChanged(self, proxy):
133 print("Neard is connected to System bus")
134 self.manager_Connect()
136 print("Neard is disconnected from System bus")
137 self.iface_manager = None
138 self.adaptregistered = {}
139 self.manager_getDetails()
142 def __init__(self, adapter_update = None, adapters_remove = None,
143 tags_update = None, records_update = None):
145 self.adapter_update = adapter_update
146 self.adapters_remove = adapters_remove
147 self.tags_update = tags_update
148 self.records_update = records_update
150 self.adaptregistered = {}
151 self.tagregistered = {}
152 self.recordregistered = {}
154 self.systemBus = dbus.SystemBus()
156 #Prepare the first handler
157 self.systemBus.watch_name_owner('org.neard',
158 self.neardNameOwnerChanged)
160 ##=================================================================
161 class NeardUI(Neard):
163 # return the current selection
164 def adapters_actionToggle(self, i, col):
166 return self.adapters_list.get_value(i, col)
169 # Action: activate or not the polling mode
170 def adapter_pollingToggled(self, poolingRendererToggle, path, user):
172 i = self.adapters_list.get_iter(path)
173 objpath = self.adapters_list.get_value(i, 0)
174 adapter_obj = self.systemBus.get_object('org.neard', objpath)
175 adapt_iface = dbus.Interface(adapter_obj,'org.neard.Adapter')
177 if self.adapters_actionToggle(i, 3):
178 print ("Stop Polling %s") % objpath
179 adapt_iface.StopPollLoop()
181 print ("Start Polling %s") % objpath
182 adapt_iface.StartPollLoop("Initiator")
185 #------------------------------
186 #Set the field values
187 def adapters_setUIList(self, adapt_properties, i, col, name, path = None):
188 if name in adapt_properties:
189 value = adapt_properties[name]
193 for tgts in adapt_properties[name]:
194 #For each tag, add it to the tag lbox:
196 short_tgt = tgts[len(path)+1:]
199 value = "{" + short_tgt
201 value = value + "," + short_tgt
204 if name == "Protocols":
206 for protos in adapt_properties[name]:
210 value = value + " " + protos
212 if value is not None:
213 self.adapters_list.set_value(i, col, value)
214 print (" property %s, value %s") % (name, value)
216 # Clear one or all the adapters present in list
217 def adapter_RemoveUI(self):
218 self.adapters_list.clear()
220 #Add, Update or delete a list entry
221 def adapter_UpdateUI(self, path = None, adapt_properties = None):
222 i = self.adapters_list.get_iter_first()
224 if self.adapters_list.get_value(i, 0) == path:
226 i = self.adapters_list.iter_next(i)
228 if adapt_properties is None:
230 print ("Delete adapter %s") % path
231 self.adapters_list.remove(i)
233 print ("Already deleted adapter %s") % path
237 i = self.adapters_list.append()
238 self.adapters_list.set_value(i, 0, path)
239 print ("Add adapter %s") % (path)
241 print ("Update adapter %s") % (path)
244 self.adapters_setUIList(adapt_properties, i, 2, "Powered")
245 self.adapters_setUIList(adapt_properties, i, 3, "Polling")
246 self.adapters_setUIList(adapt_properties, i, 4, "Protocols")
247 self.adapters_setUIList(adapt_properties, i, 5, "Tags", path)
249 #--------------------------------------------------
250 def tags_setUIList(self, tag_properties, i, col, name):
251 if name in tag_properties:
252 value = tag_properties[name]
254 if name == "Records":
256 for tags in tag_properties[name]:
257 #For each tag, add it to the tag lbox:
261 value = value + "-" + tags
265 for tags in tag_properties[name]:
266 #For each tag, add it to the tag lbox:
270 value = value + "-" + tags
272 if value is not None:
273 self.tags_list.set_value(i, col, value)
274 print (" property %s, value %s") % (name, value)
276 #Add, Update or delete a list entry
277 def tag_UpdateUI(self, path = None, tag_properties = None):
278 print("Tag Update %s") % path
279 i = self.tags_list.get_iter_first()
281 if self.tags_list.get_value(i, 0) == path:
283 i = self.tags_list.iter_next(i)
285 #Delete mode: Remove all
286 if tag_properties is None:
287 i = self.tags_list.get_iter_first()
289 path_name = self.tags_list.get_value(i, 0)
290 print ("Deleted tag %s") % path_name
291 self.tags_list.remove(i)
292 if self.tags_list.iter_is_valid(i):
293 i = self.tags_list.iter_next(i)
299 i = self.tags_list.append()
300 self.tags_list.set_value(i, 0, path)
301 print ("Add tag %s") % (path)
303 print ("Update tag %s") % (path)
304 self.tags_setUIList(tag_properties, i, 2, "ReadOnly")
305 self.tags_setUIList(tag_properties, i, 3, "Type")
306 self.tags_setUIList(tag_properties, i, 4, "Records")
308 #--------------------------------------------------
309 def records_setUIList(self, record_properties, i, col, name):
310 if name in record_properties:
311 value = record_properties[name]
314 for rec_data in record_properties:
315 if rec_data != "Type":
318 value = value + rec_data + " : " +record_properties[rec_data]
320 if value is not None:
321 self.records_list.set_value(i, col, value)
322 print (" property %s, value %s") % (name, value)
324 #Add, Update or delete a list entry
325 def record_UpdateUI(self, path = None, record_properties = None):
326 print("Record Update %s") % path
327 i = self.records_list.get_iter_first()
329 if self.records_list.get_value(i, 0) == path:
331 i = self.records_list.iter_next(i)
333 #Delete mode: Remove all records
334 if record_properties is None:
335 i = self.records_list.get_iter_first()
337 path_name = self.records_list.get_value(i, 0)
338 print ("Delete record %s") % path_name
339 self.records_list.remove(i)
340 if self.records_list.iter_is_valid(i):
341 i = self.records_list.iter_next(i)
347 i = self.records_list.append()
348 self.records_list.set_value(i, 0, path)
349 print ("Add record %s") % (path)
351 print ("Update record %s") % (path)
353 self.records_setUIList(record_properties, i, 2, "Type")
354 self.records_setUIList(record_properties, i, 3, "Data")
357 def tag_RemoveUI(self):
360 #Adapter selected on lbox
361 def on_adapter_sel_changed(self, selection = None):
362 model, iter = selection.get_selected()
364 value = self.adapters_list.get_value(iter, 0)
365 print ("value %s") % value
366 value = self.adapters_list.get_value(iter, 5)
367 print ("tag: %s") % value
370 #-----------------------------------------------------
371 # Prepare TreeView for Adapters
372 def createAdaptersWidgets(self, adaptlist):
375 tv_adapters = gtk.TreeView(adaptlist)
377 column = gtk.TreeViewColumn("Path", gtk.CellRendererText(), text=0)
378 tv_adapters.append_column(column)
380 toggle = gtk.CellRendererToggle()
381 column = gtk.TreeViewColumn("Powered", toggle, active=2)
382 tv_adapters.append_column(column)
384 toggle = gtk.CellRendererToggle()
385 column = gtk.TreeViewColumn("Polling", toggle, active=3)
386 toggle.connect('toggled', self.adapter_pollingToggled, None)
387 tv_adapters.append_column(column)
389 column = gtk.TreeViewColumn("Protocols",gtk.CellRendererText(), text=4)
390 tv_adapters.append_column(column)
392 column = gtk.TreeViewColumn("Tags", gtk.CellRendererText(), text=5)
393 tv_adapters.append_column(column)
395 tv_adapters.get_selection().connect("changed",
396 self.on_adapter_sel_changed)
400 # Prepare TreeView for Tags
401 def createTagsWidgets(self, tags_list):
404 tv_tags = gtk.TreeView(tags_list)
406 column = gtk.TreeViewColumn("Path", gtk.CellRendererText(), text=0)
407 tv_tags.append_column(column)
408 toggle = gtk.CellRendererToggle()
409 column = gtk.TreeViewColumn("ReadOnly", toggle, active=2)
410 tv_tags.append_column(column)
412 column = gtk.TreeViewColumn("Type", gtk.CellRendererText(), text=3)
413 tv_tags.append_column(column)
415 column = gtk.TreeViewColumn("Record", gtk.CellRendererText(), text=4)
416 tv_tags.append_column(column)
420 # Prepare TreeView for Records
421 def createRecordsWidgets(self, records_list):
423 tv_records = gtk.TreeView(records_list)
424 tv_records.connect("row-activated", self.on_record_activated)
426 column = gtk.TreeViewColumn("Path", gtk.CellRendererText(), text=0)
427 tv_records.append_column(column)
429 column = gtk.TreeViewColumn("Type", gtk.CellRendererText(), text=2)
430 tv_records.append_column(column)
432 column = gtk.TreeViewColumn("Data", gtk.CellRendererText(), text=3)
433 tv_records.append_column(column)
436 def on_record_activated(self, widget, row, col):
437 model = widget.get_model()
438 recordUI = RecordUI(self.neardDialog, model[row][0], model[row][2])
441 def dlg_onResponse(self, dialog, response):
442 self.neardDialog.destroy()
443 self.neardDialog = None
444 if self.response_callback is not None:
445 self.response_callback(response)
447 #------------------------------
449 def createDialog(self, title = None):
450 if self.title is not None:
452 dialog = gtk.Dialog(title, None,
454 gtk.DIALOG_DESTROY_WITH_PARENT,
455 (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
456 dialog.set_property("resizable", True)
457 dialog.set_default_size(800, 300)
459 notebook = gtk.Notebook()
460 dialog.child.add(notebook)
462 # Create the first tab...an adapters's list
463 scrolledwindow = gtk.ScrolledWindow()
464 widget = self.createAdaptersWidgets(self.adapters_list)
465 scrolledwindow.add(widget)
466 # notebook.append_page(widget, gtk.Label("Adapters"))
467 notebook.append_page(scrolledwindow, gtk.Label("Adapters"))
469 scrolledwindow = gtk.ScrolledWindow()
470 widget = self.createTagsWidgets(self.tags_list)
471 scrolledwindow.add(widget)
473 notebook.append_page(scrolledwindow, gtk.Label("Tags"))
475 scrolledwindow = gtk.ScrolledWindow()
476 widget = self.createRecordsWidgets(self.records_list)
477 scrolledwindow.add(widget)
478 notebook.append_page(scrolledwindow, gtk.Label("Records"))
480 dialog.connect('response', self.dlg_onResponse)
481 # dialog.vbox.pack_end(vbox, True, True, 0)
485 if self.neardDialog is None:
486 self.neardDialog = self.createDialog()
487 self.neardDialog.show_all()
489 def __init__(self, title = None, response_callback = None):
491 self.response_callback = response_callback
492 self.neardDialog = None
494 self.adapters_list = gtk.ListStore(gobject.TYPE_STRING, # path =0
495 gobject.TYPE_STRING, # Name = 1
496 gobject.TYPE_BOOLEAN, # powered = 2
497 gobject.TYPE_BOOLEAN, # polling = 3
498 gobject.TYPE_STRING, # protocols = 4
499 gobject.TYPE_STRING) # tags = 5
501 self.tags_list = gtk.ListStore(gobject.TYPE_STRING, # path =0
502 gobject.TYPE_STRING, # Name = 1
503 gobject.TYPE_BOOLEAN, # Read Only 2
504 gobject.TYPE_STRING, # Type = 3
505 gobject.TYPE_STRING) # Record = 4
507 self.records_list = gtk.ListStore(gobject.TYPE_STRING, # path =0
508 gobject.TYPE_STRING, # Name = 1
509 gobject.TYPE_STRING, # Type = 2
510 gobject.TYPE_STRING) # content = 3
512 Neard.__init__(self, self.adapter_UpdateUI, self.adapter_RemoveUI
513 , self.tag_UpdateUI, self.record_UpdateUI)
516 def wr_onResponse(self, dialog, response):
517 if response != gtk.RESPONSE_ACCEPT:
519 content = self.content_entry.get_text()
520 type_name = self.type_combo.get_active_text()
521 bus = dbus.SystemBus()
522 record_path = self.path
523 tag_path = record_path[:record_path.rfind("/")]
524 tag = dbus.Interface(bus.get_object("org.neard", tag_path), "org.neard.Tag")
525 if type_name in ["Text"]:
526 content1 = content.split()
527 tag.Write({"Type" : type_name,
528 "Encoding" : content1[0],
529 "Language" : content1[1],
530 "Representation" : ' '.join(content1[2:])})
532 tag.Write({"Type" : type_name,
536 def __init__(self, parent = None, path = None, type_name = None):
538 type_combo = gtk.combo_box_new_text()
539 type_combo.append_text('Text')
540 type_combo.append_text('URI')
541 type_combo.append_text('SmartPoster')
542 if type_name == 'Text':
543 type_combo.set_active(0)
544 elif type_name == 'URI':
545 type_combo.set_active(1)
546 elif type_name == 'SmartPoster':
547 type_combo.set_active(2)
549 content_entry = gtk.Entry()
550 fixed.put(type_combo, 20, 40)
551 fixed.put(content_entry, 150, 40)
552 type_label = gtk.Label("Type")
553 content_label = gtk.Label("Content")
554 fixed.put(type_label, 20, 15)
555 fixed.put(content_label, 150, 15)
557 record_dialog = gtk.Dialog("Write Record", parent,
558 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
559 (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
560 self.record_dialog = record_dialog
561 record_dialog.set_default_size(280, 120)
562 record_dialog.set_position(gtk.WIN_POS_CENTER)
563 record_dialog.connect('response', self.wr_onResponse)
564 hbox = record_dialog.get_content_area()
565 hbox.pack_start(fixed)
566 self.type_combo = type_combo
567 self.content_entry = content_entry
571 self.record_dialog.run()
572 self.record_dialog.destroy()
574 ##=================================================================
575 if __name__ == "__main__":
577 def endmainloop(response):
580 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
581 mainloop = gobject.MainLoop()
583 m = NeardUI("Neard", endmainloop)