Package sabayon :: Package sources :: Module paneldelegate
[hide private]
[frames] | no frames]

Source Code for Module sabayon.sources.paneldelegate

  1  # 
  2  # Copyright (C) 2005 Red Hat, Inc. 
  3  # 
  4  # This program is free software; you can redistribute it and/or modify 
  5  # it under the terms of the GNU General Public License as published by 
  6  # the Free Software Foundation; either version 2 of the License, or 
  7  # (at your option) any later version. 
  8  # 
  9  # This program is distributed in the hope that it will be useful, 
 10  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 12  # GNU General Public License for more details. 
 13  # 
 14  # You should have received a copy of the GNU General Public License 
 15  # along with this program; if not, write to the Free Software 
 16  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 17  # 
 18   
 19  import os 
 20  import gconf 
 21  import gconfsource 
 22  import subprocess 
 23  import bonobo 
 24  import xdg.DesktopEntry 
 25   
 26  try: 
 27      import userprofile 
 28      import util 
 29      from config import * 
 30      import debuglog 
 31  except: 
 32      from sabayon import userprofile 
 33      from sabayon import util 
 34      from sabayon.config import * 
 35      from sabayon import debuglog 
 36   
37 -def dprint (fmt, *args):
38 debuglog.debug_log (False, debuglog.DEBUG_LOG_DOMAIN_PANEL_DELEGATE, fmt % args)
39 40 PANEL_LAUNCHER_DIR = ".gnome2/panel2.d/default/launchers" 41
42 -def copy_dir (src_client, dst_client, dst_address, dir):
43 for entry in src_client.all_entries (dir): 44 schema_name = entry.get_schema_name () 45 if schema_name: 46 gconfsource.associate_schema (dst_address, entry.key, schema_name) 47 if entry.value and not entry.get_is_default (): 48 dst_client.set (entry.key, entry.value) 49 for subdir in src_client.all_dirs (dir): 50 copy_dir (src_client, dst_client, dst_address, subdir)
51
52 -class PanelChange (userprofile.ProfileChange):
53 - def __init__ (self, source, delegate, id):
54 userprofile.ProfileChange.__init__ (self, source, delegate) 55 self.id = id
56 - def get_id (self):
57 return self.id
58 - def commit_change (self, mandatory):
59 pass
60
61 -class PanelAddedChange (PanelChange):
62 - def __init__ (self, source, delegate, id):
63 PanelChange.__init__ (self, source, delegate, id)
64 - def get_short_description (self):
65 return _("Panel '%s' added") % self.id
66
67 -class PanelRemovedChange (PanelChange):
68 - def __init__ (self, source, delegate, id):
69 PanelChange.__init__ (self, source, delegate, id)
70 - def get_short_description (self):
71 return _("Panel '%s' removed") % self.id
72
73 -class PanelAppletAddedChange (PanelChange):
74 - def __init__ (self, source, delegate, id):
75 PanelChange.__init__ (self, source, delegate, id)
76 - def get_short_description (self):
77 return _("Applet '%s' added" % self.id)
78 # FIXME: This only works if panel object type is bonobo-applet. Are all applets bonobo-applets ? 79 # FIXME: Race condition with the code below. 80 # panel_applet = self.delegate.PanelApplet(self.delegate, self.id) 81 # toplevel_id = panel_applet.toplevel_id 82 # name = panel_applet.name 83 84 # panel_toplevel = self.delegate.PanelToplevel(self.delegate, toplevel_id) 85 # panel_orientation = panel_toplevel.orientation 86 87 # if panel_orientation == "top": 88 # return _("Applet %s added to top panel") % name 89 # elif panel_orientation == "bottom": 90 # return _("Applet %s added to bottom panel") % name 91 # elif panel_orientation == "left": 92 # return _("Applet %s added to left panel") % name 93 # else: 94 # return _("Applet %s added to right panel") % name 95
96 -class PanelAppletRemovedChange (PanelChange):
97 - def __init__ (self, source, delegate, id):
98 PanelChange.__init__ (self, source, delegate, id)
99 - def get_short_description (self):
100 return _("Applet '%s' removed" % self.id)
101 # FIXME: This only works if panel object type is bonobo-applet. Are all applets bonobo-applets ? 102 # FIXME: Race condition with the code below. 103 # panel_applet = self.delegate.PanelApplet(self.delegate, self.id) 104 # toplevel_id = panel_applet.toplevel_id 105 # name = panel_applet.name 106 107 # panel_toplevel = self.delegate.PanelToplevel(self.delegate, toplevel_id) 108 # panel_orientation = panel_toplevel.orientation 109 110 # if panel_orientation == "top": 111 # return _("Applet %s removed from top panel") % name 112 # elif panel_orientation == "bottom": 113 # return _("Applet %s removed from bottom panel") % name 114 # elif panel_orientation == "left": 115 # return _("Applet %s removed from left panel") % name 116 # else: 117 # return _("Applet %s removed from right panel") % name 118
119 -class PanelObjectAddedChange (PanelChange):
120 - def __init__ (self, source, delegate, id):
121 PanelChange.__init__ (self, source, delegate, id)
122 - def get_short_description (self):
123 return _("Object '%s' added" % self.id)
124 # FIXME: Race condition with code below. 125 # panel_object = self.delegate.PanelObject(self.delegate, self.id) 126 # toplevel_id = panel_object.toplevel_id 127 # name = panel_object.name 128 129 # panel_toplevel = self.delegate.PanelToplevel(self.delegate, toplevel_id) 130 # panel_orientation = panel_toplevel.orientation 131 132 # if panel_orientation == "top": 133 # return _("%s added to top panel") % name 134 # elif panel_orientation == "bottom": 135 # return _("%s added to bottom panel") % name 136 # elif panel_orientation == "left": 137 # return _("%s added to left panel") % name 138 # else: 139 # return _("%s added to right panel") % name 140
141 - def commit_change (self, mandatory):
142 # Might have to commit a launcher file 143 launcher = self.delegate.get_gconf_client ().get_string (PANEL_KEY_BASE + "/objects/" + self.id + "/launcher_location") 144 if launcher and launcher[0] != '/': 145 file = PANEL_LAUNCHER_DIR + "/" + launcher 146 self.source.storage.add (file, self.delegate.home_dir, self.delegate.name)
147
148 -class PanelObjectRemovedChange (PanelChange):
149 - def __init__ (self, source, delegate, id):
150 PanelChange.__init__ (self, source, delegate, id)
151 - def get_short_description (self):
152 return _("Object '%s' removed" % self.id)
153 # FIXME: Race condition with code below. 154 # panel_object = self.delegate.PanelObject(self.delegate, self.id) 155 # toplevel_id = panel_object.toplevel_id 156 # name = panel_object.name 157 158 # panel_toplevel = self.delegate.PanelToplevel(self.delegate, toplevel_id) 159 # panel_orientation = panel_toplevel.orientation 160 161 # if panel_orientation == "top": 162 # return _("%s removed from top panel") % name 163 # elif panel_orientation == "bottom": 164 # return _("%s removed from bottom panel") % name 165 # elif panel_orientation == "left": 166 # return _("%s removed from left panel") % name 167 # else: 168 # return _("%s removed from right panel") % name 169
170 - def commit_change (self, mandatory):
171 launcher = self.delegate.get_gconf_client ().get_string (PANEL_KEY_BASE + "/objects/" + self.id + "/launcher_location") 172 if launcher and launcher[0] != '/': 173 file = PANEL_LAUNCHER_DIR + "/" + launcher 174 self.source.storage.remove (file)
175
176 -class PanelDelegate (userprofile.SourceDelegate):
177 - class PanelThing:
178 - def __init__ (self, delegate, id, added, removed):
179 self.delegate = delegate 180 self.id = id 181 self.added = added 182 self.removed = removed 183 self.gconf_client = self.delegate.get_gconf_client () 184 self.SORTPRIORITY = 60
185
186 - def _copy_tree (self, dir):
187 if not self.gconf_client.dir_exists(dir): 188 (src_client, src_address) = gconfsource.get_client_and_address_for_path (os.path.join (util.get_home_dir (), '.gconf')) 189 (dst_client, dst_address) = gconfsource.get_client_and_address_for_path (os.path.join (util.get_home_dir (), GCONF_DEFAULTS_SOURCE)) 190 copy_dir (src_client, dst_client, dst_address, dir)
191
192 - class PanelToplevel (PanelThing):
193 - def __init__ (self, delegate, id, added = False, removed = False):
194 PanelDelegate.PanelThing.__init__ (self, delegate, id, added, removed) 195 196 self._copy_tree (PANEL_KEY_BASE + "/toplevels/" + id) 197 198 self.orientation = self.gconf_client.get_string (PANEL_KEY_BASE + "/toplevels/" + id + "/orientation")
199 200 # FIXME: which of the following attributes do we really need? 201 # self.name = self.gconf_client.get_string (PANEL_KEY_BASE + "/toplevels/" + toplevel_id + "/name") 202 # self.expand = self.gconf_client.get_bool (PANEL_KEY_BASE + "/toplevels/" + toplevel_id + "/expand") 203
204 - class PanelApplet (PanelThing):
205 - def __init__ (self, delegate, id, added = False, removed = False):
206 PanelDelegate.PanelThing.__init__ (self, delegate, id, added, removed) 207 208 self._copy_tree (PANEL_KEY_BASE + "/applets/" + id) 209 210 toplevel_key_name = PANEL_KEY_BASE + "/applets/" + id + "/toplevel_id" 211 bonobo_iid_key_name = PANEL_KEY_BASE + "/applets/" + id + "/bonobo_iid" 212 213 self.toplevel_id = self.gconf_client.get_string (toplevel_key_name) 214 self.bonobo_iid = self.gconf_client.get_string (bonobo_iid_key_name) 215 216 dprint ("Creating PanelApplet for '%s' (toplevel_key %s, toplevel_id %s, bonobo_key %s, bonobo_iid %s)", 217 id, 218 toplevel_key_name, self.toplevel_id, 219 bonobo_iid_key_name, self.bonobo_iid) 220 221 if self.bonobo_iid: 222 applet = bonobo.activation.query("iid == '" + self.bonobo_iid + "'" ) 223 for i in applet: 224 for prop in i.props: 225 if prop.name == "name": 226 self.name = prop.v.value_string #FIXME: This probably won't return localised names
227 228 229
230 - class PanelObject (PanelThing):
231 - def __init__ (self, delegate, id, added = False, removed = False):
232 PanelDelegate.PanelThing.__init__ (self, delegate, id, added, removed) 233 234 self._copy_tree (PANEL_KEY_BASE + "/objects/" + id) 235 236 self.toplevel_id = self.gconf_client.get_string (PANEL_KEY_BASE + "/objects/" + id + "/toplevel_id") 237 self.object_type = self.gconf_client.get_string (PANEL_KEY_BASE + "/objects/" + id + "/object_type") 238 239 if self.object_type == "drawer-object": 240 # Translators: This is a drawer in gnome-panel (where you can put applets) 241 self.name = _("Drawer") 242 elif self.object_type == "menu-object": 243 self.name = _("Main Menu") 244 elif self.object_type == "launcher-object": 245 launcher_location = self.gconf_client.get_string (PANEL_KEY_BASE + "/objects/" + id + "/launcher_location") 246 if launcher_location[0] == '/': 247 desktop_file = launcher_location 248 elif launcher_location[0:7] == "file://": # See what happens when you drag and drop from the menu 249 desktop_file = launcher_location[7:] 250 else: 251 desktop_file = PANEL_LAUNCHER_DIR + "/" + launcher_location 252 launcher = xdg.DesktopEntry.DesktopEntry(desktop_file) 253 self.name = _("%s launcher") % launcher.getName() 254 elif self.object_type == "action-applet": 255 action_type = self.gconf_client.get_string (PANEL_KEY_BASE + "/objects/" + id + "/action_type") 256 if action_type == "lock": 257 self.name = _("Lock Screen button") 258 elif action_type == "logout": 259 self.name = _("Logout button") 260 elif action_type == "run": 261 self.name = _("Run Application button") 262 elif action_type == "search": 263 self.name = _("Search button") 264 elif action_type == "force-quit": 265 self.name = _("Force Quit button") 266 elif action_type == "connect-server": 267 self.name = _("Connect to Server button") 268 elif action_type == "shutdown": 269 self.name = _("Shutdown button") 270 elif action_type == "screenshot": 271 self.name = _("Screenshot button") 272 273 else: 274 self.name = _("Unknown") 275 else: 276 self.name = _("Menu Bar")
277
278 - def __init__ (self, source):
279 userprofile.SourceDelegate.__init__ (self, _("Panel"), source, PANEL_KEY_BASE) 280 281 self.home_dir = util.get_home_dir() 282 self.toplevels = {} 283 self.applets = {} 284 self.objects = {}
285
286 - def get_gconf_client (self):
287 return self.source.gconf_client
288
289 - def __read_panel_config (self):
290 dprint ("Reading initial panel config"); 291 292 dprint ("Toplevels:"); 293 for id in self.get_gconf_client ().get_list (PANEL_KEY_BASE + "/general/toplevel_id_list", gconf.VALUE_STRING): 294 if not self.toplevels.has_key (id): 295 dprint (" %s", id); 296 self.toplevels[id] = PanelDelegate.PanelToplevel (self, id) 297 298 dprint ("Applets:"); 299 for id in self.get_gconf_client ().get_list (PANEL_KEY_BASE + "/general/applet_id_list", gconf.VALUE_STRING): 300 if not self.applets.has_key (id): 301 dprint (" %s", id); 302 self.applets[id] = PanelDelegate.PanelApplet (self, id) 303 304 dprint ("Objects:"); 305 for id in self.get_gconf_client ().get_list (PANEL_KEY_BASE + "/general/object_id_list", gconf.VALUE_STRING): 306 if not self.objects.has_key (id): 307 dprint (" %s", id); 308 self.objects[id] = PanelDelegate.PanelObject (self, id)
309
310 - def __handle_id_list_change (self, change, dict, thing_class, added_class, removed_class):
311 if not change.value or \ 312 change.value.type != gconf.VALUE_LIST or \ 313 change.value.get_list_type () != gconf.VALUE_STRING: 314 return True 315 316 id_list = [] 317 for v in change.value.get_list (): 318 id_list.append (v.get_string ()) 319 320 added = [] 321 for id in id_list: 322 if dict.has_key (id) and not dict[id].removed: 323 continue 324 if not dict.has_key (id): 325 dict[id] = thing_class (self, id, True) 326 else: 327 dict[id].added = True 328 dict[id].removed = False 329 added.append (id) 330 331 removed = [] 332 for id in dict: 333 if id in id_list: 334 continue 335 if dict.has_key (id) and not dict[id].removed: 336 dict[id].removed = True 337 removed.append (id) 338 339 dprint ("%s changed: (%s) added, (%s) removed\n", 340 change.key, added, removed); 341 342 for id in added: 343 self.source.emit ("changed", added_class (self.source, self, id)) 344 for id in removed: 345 self.source.emit ("changed", removed_class (self.source, self, id)) 346 347 return True
348
349 - def handle_change (self, change):
350 if change.key.startswith (PANEL_KEY_BASE + "/toplevels/"): 351 toplevel_id = change.key.split ("/")[4] 352 if not self.toplevels.has_key (toplevel_id) or \ 353 self.toplevels[toplevel_id].added or \ 354 self.toplevels[toplevel_id].removed: 355 return True 356 357 elif change.key.startswith (PANEL_KEY_BASE + "/objects/"): 358 object_id = change.key.split ("/")[4] 359 if not self.objects.has_key (object_id) or \ 360 self.objects[object_id].added or \ 361 self.objects[object_id].removed: 362 return True 363 364 elif change.key.startswith (PANEL_KEY_BASE + "/applets"): 365 applet_id = change.key.split ("/")[4] 366 if not self.applets.has_key (applet_id) or \ 367 self.applets[applet_id].added or \ 368 self.applets[applet_id].removed: 369 return True 370 371 elif change.key == PANEL_KEY_BASE + "/general/toplevel_id_list": 372 return self.__handle_id_list_change (change, 373 self.toplevels, 374 PanelDelegate.PanelToplevel, 375 PanelAddedChange, 376 PanelRemovedChange) 377 378 elif change.key == PANEL_KEY_BASE + "/general/applet_id_list": 379 return self.__handle_id_list_change (change, 380 self.applets, 381 PanelDelegate.PanelApplet, 382 PanelAppletAddedChange, 383 PanelAppletRemovedChange) 384 385 elif change.key == PANEL_KEY_BASE + "/general/object_id_list": 386 return self.__handle_id_list_change (change, 387 self.objects, 388 PanelDelegate.PanelObject, 389 PanelObjectAddedChange, 390 PanelObjectRemovedChange) 391 392 return False
393
394 - def __get_current_list (self, dict):
395 id_list = [] 396 for id in dict: 397 if dict[id].added: 398 continue 399 id_list.append (id) 400 return id_list
401
402 - def __commit_added_change (self, change, mandatory, dict, id_list_name, dir_name):
403 if not dict.has_key (change.id): 404 return 405 406 thing = dict[change.id] 407 if not thing.added: 408 return 409 410 change.commit_change (mandatory) 411 412 (client, address) = self.source.get_committing_client_and_address (mandatory) 413 414 copy_dir (self.get_gconf_client (), client, address, PANEL_KEY_BASE + "/" + dir_name + "/" + thing.id) 415 416 id_list = self.__get_current_list (dict) 417 id_list.append (thing.id) 418 client.set_list (PANEL_KEY_BASE + "/general/" + id_list_name, gconf.VALUE_STRING, id_list) 419 420 thing.added = False
421
422 - def __commit_removed_change (self, change, mandatory, dict, id_list_name, dir_name):
423 if not dict.has_key (change.id): 424 return 425 426 thing = dict[change.id] 427 if not thing.removed: 428 return 429 430 change.commit_change (mandatory) 431 432 (client, address) = self.source.get_committing_client_and_address (mandatory) 433 434 id_list = self.__get_current_list (dict) 435 if thing.id in id_list: 436 id_list.remove (thing.id) 437 client.set_list (PANEL_KEY_BASE + "/general/" + id_list_name, gconf.VALUE_STRING, id_list) 438 gconfsource.recursive_unset (client, PANEL_KEY_BASE + "/" + dir_name + "/" + thing.id) 439 440 del dict[change.id]
441
442 - def commit_change (self, change, mandatory = False):
443 if isinstance (change, PanelAddedChange): 444 self.__commit_added_change (change, 445 mandatory, 446 self.toplevels, 447 "toplevel_id_list", 448 "toplevels") 449 elif isinstance (change, PanelRemovedChange): 450 self.__commit_removed_change (change, 451 mandatory, 452 self.toplevels, 453 "toplevel_id_list", 454 "toplevels") 455 elif isinstance (change, PanelAppletAddedChange): 456 self.__commit_added_change (change, 457 mandatory, 458 self.applets, 459 "applet_id_list", 460 "applets") 461 elif isinstance (change, PanelAppletRemovedChange): 462 self.__commit_removed_change (change, 463 mandatory, 464 self.applets, 465 "applet_id_list", 466 "applets") 467 elif isinstance (change, PanelObjectAddedChange): 468 self.__commit_added_change (change, 469 mandatory, 470 self.objects, 471 "object_id_list", 472 "objects") 473 elif isinstance (change, PanelObjectRemovedChange): 474 self.__commit_removed_change (change, 475 mandatory, 476 self.objects, 477 "object_id_list", 478 "objects")
479
480 - def get_path_description (self, path):
481 return "Panel launcher: %s"%os.path.basename(path)
482
483 - def start_monitoring (self):
484 # Need to do this here so gconf paths are setup 485 self.__read_panel_config () 486 pass
487
488 - def stop_monitoring (self):
489 """Stop monitoring for configuration changes.""" 490 # Nothing to do here 491 pass
492
493 - def sync_changes (self):
494 # Nothing to do here 495 pass
496
497 - def set_enforce_mandatory (self, enforce):
498 # Nothing to do here 499 pass
500
501 - def __apply_foreach (self, source, path):
502 self.source.storage.extract (path, self.home_dir)
503
504 - def apply (self, is_sabayon_session):
505 self.source.storage.foreach (self.__apply_foreach, source = self.name) 506 pass
507
508 -def get_gconf_delegate (source):
509 return PanelDelegate (source)
510
511 -class PanelFileDelegate (userprofile.SourceDelegate):
512 - def __init__ (self, source):
513 userprofile.SourceDelegate.__init__ (self, _("Panel File"), source, PANEL_LAUNCHER_DIR)
514
515 - def handle_change (self, change):
516 dprint ("Ignoring file chage due to panel delegation: %s"%change) 517 return True
518
519 - def start_monitoring (self):
520 pass
521
522 - def stop_monitoring (self):
523 pass
524
525 - def sync_changes (self):
526 pass
527
528 - def set_enforce_mandatory (self, enforce):
529 pass
530
531 - def apply (self, is_sabayon_session):
532 pass
533
534 -def get_files_delegate(source):
535 return PanelFileDelegate(source)
536 537 538 # 539 # Unit tests 540 #
541 -def run_unit_tests ():
542 import gobject 543 import os 544 import os.path 545 import time 546 import tempfile 547 import shutil 548 549 # Clear out any cruft 550 subprocess.call (["gconftool-2", "--recursive-unset", "%s/toplevels/foo" % PANEL_KEY_BASE]) 551 subprocess.call (["gconftool-2", "--recursive-unset", "%s/objects/foo" % PANEL_KEY_BASE]) 552 subprocess.call (["gconftool-2", "--recursive-unset", "%s/applets/foo" % PANEL_KEY_BASE]) 553 time.sleep (1) 554 555 client = gconf.client_get_default () 556 557 for id_list_name in ("toplevel_id_list", "object_id_list", "applet_id_list"): 558 id_list = client.get_list (PANEL_KEY_BASE + "/general/" + id_list_name, gconf.VALUE_STRING) 559 while "foo" in id_list: 560 id_list.remove ("foo") 561 client.set_list (PANEL_KEY_BASE + "/general/" + id_list_name, gconf.VALUE_STRING, id_list) 562 563 temp_path = tempfile.mkdtemp (prefix = "test-paneldelegate-") 564 565 # Create a dummy source with a PanelDelegate 566 class TempSource (userprofile.ProfileSource): 567 def __init__ (self, temp_path): 568 userprofile.ProfileSource.__init__ (self, "panel-temp") 569 self.delegates.append (PanelDelegate (self)) 570 self.temp_path = temp_path 571 self.defaults_client = None 572 self.defaults_address = None 573 self.mandatory_client = None 574 self.mandatory_address = None
575 def get_committing_client_and_address (self, mandatory): 576 if not mandatory: 577 if not self.defaults_client: 578 (client, address) = gconfsource.get_client_and_address_for_path ( 579 os.path.join (self.temp_path, GCONF_DEFAULTS_SOURCE)) 580 self.defaults_client = client 581 self.defaults_address = address 582 return (self.defaults_client, self.defaults_address) 583 else: 584 if not self.mandatory_client: 585 (client, address) = gconfsource.get_client_and_address_for_path ( 586 os.path.join (self.temp_path, GCONF_MANDATORY_SOURCE)) 587 self.mandatory_client = client 588 self.mandatory_address = address 589 return (self.mandatory_client, self.mandatory_address) 590 gobject.type_register (TempSource) 591 source = TempSource (temp_path) 592 593 # Set up the client 594 def handle_notify (client, cnx_id, entry, source): 595 source.emit_change (gconfsource.GConfChange (source, entry.key, entry.value)) 596 client.add_dir (PANEL_KEY_BASE + "", gconf.CLIENT_PRELOAD_RECURSIVE) 597 notify_id = client.notify_add (PANEL_KEY_BASE + "", handle_notify, source) 598 599 # Trap filtered changes 600 global changes 601 changes = [] 602 def handle_change (source, change): 603 global changes 604 changes.append (change) 605 source.connect ("changed", handle_change) 606 607 # Need to run the mainloop to get notifications. 608 # The notification is only dispatched once the set 609 # operation has complete 610 main_loop = gobject.MainLoop () 611 def poll (main_loop): 612 while main_loop.get_context ().pending (): 613 main_loop.get_context ().iteration (False) 614 615 # Recursively copy a dir 616 def copy_dir (client, dst, src): 617 for entry in client.all_entries (src): 618 key = dst + "/" + os.path.basename (entry.key) 619 client.set (key, entry.value) 620 for dir in client.all_dirs (src): 621 subdir = os.path.basename (dir) 622 copy_dir (client, dst + "/" + subdir, src + "/" + subdir) 623 624 # Set random uninterpreted key 625 show_program_list = client.get_bool (PANEL_KEY_BASE + "/general/show_program_list") 626 client.set_bool (PANEL_KEY_BASE + "/general/show_program_list", not show_program_list) 627 poll (main_loop) 628 629 # Set up a panel on the right 630 copy_dir (client, PANEL_KEY_BASE + "/toplevels/foo", PANEL_KEY_BASE + "/toplevels/top_panel") 631 poll (main_loop) 632 633 # Set up a clock applet 634 copy_dir (client, PANEL_KEY_BASE + "/applets/foo", PANEL_KEY_BASE + "/applets/clock") 635 client.set_string (PANEL_KEY_BASE + "/applets/foo/toplevel_id", "foo") 636 poll (main_loop) 637 638 # Set up a menu bar 639 copy_dir (client, PANEL_KEY_BASE + "/objects/foo", PANEL_KEY_BASE + "/objects/menu_bar") 640 client.set_string (PANEL_KEY_BASE + "/objects/foo/toplevel_id", "foo") 641 poll (main_loop) 642 643 # Add the new panel to the list of panels 644 toplevels = client.get_list (PANEL_KEY_BASE + "/general/toplevel_id_list", gconf.VALUE_STRING) 645 toplevels.append ("foo") 646 client.set_list (PANEL_KEY_BASE + "/general/toplevel_id_list", gconf.VALUE_STRING, toplevels) 647 poll (main_loop) 648 649 # Add the new clock to the list of applets 650 applets = client.get_list (PANEL_KEY_BASE + "/general/applet_id_list", gconf.VALUE_STRING) 651 applets.append ("foo") 652 client.set_list (PANEL_KEY_BASE + "/general/applet_id_list", gconf.VALUE_STRING, applets) 653 poll (main_loop) 654 655 # Add the new menu bar to the list of objects 656 objects = client.get_list (PANEL_KEY_BASE + "/general/object_id_list", gconf.VALUE_STRING) 657 objects.append ("foo") 658 client.set_list (PANEL_KEY_BASE + "/general/object_id_list", gconf.VALUE_STRING, objects) 659 poll (main_loop) 660 661 time.sleep (3) 662 663 client.set_int (PANEL_KEY_BASE + "/toplevels/foo/hide_delay", 5) 664 poll (main_loop) 665 666 assert len (changes) == 4 667 for change in changes: 668 assert isinstance (change, userprofile.ProfileChange) 669 assert isinstance (changes[0], gconfsource.GConfChange) 670 assert changes[0].key == PANEL_KEY_BASE + "/general/show_program_list" 671 for change in changes[1:4]: 672 assert isinstance (change, PanelChange) 673 assert change.id == "foo" 674 675 ( 676 PANEL_ADDED, 677 PANEL_APPLET_ADDED, 678 PANEL_OBJECT_ADDED 679 ) = range (1, 4) 680 681 assert isinstance (changes[PANEL_ADDED], PanelAddedChange) 682 assert isinstance (changes[PANEL_APPLET_ADDED], PanelAppletAddedChange) 683 assert isinstance (changes[PANEL_OBJECT_ADDED], PanelObjectAddedChange) 684 685 source.commit_change (changes[PANEL_ADDED], False) 686 687 subprocess.call (["gconftool-2", "--shutdown"]) 688 time.sleep (1) 689 690 assert os.access (os.path.join (temp_path, GCONF_DEFAULTS_SOURCE + "/apps/panel/general/%gconf.xml"), os.F_OK) 691 assert os.access (os.path.join (temp_path, GCONF_DEFAULTS_SOURCE + "/apps/panel/toplevels/foo/%gconf.xml"), os.F_OK) 692 693 changes = [] 694 695 # Remove the menu bar again 696 while "foo" in objects: 697 objects.remove ("foo") 698 client.set_list (PANEL_KEY_BASE + "/general/object_id_list", gconf.VALUE_STRING, objects) 699 poll (main_loop) 700 701 # Remove the clock again 702 while "foo" in applets: 703 applets.remove ("foo") 704 client.set_list (PANEL_KEY_BASE + "/general/applet_id_list", gconf.VALUE_STRING, applets) 705 poll (main_loop) 706 707 # Remove the panel again 708 while "foo" in toplevels: 709 toplevels.remove ("foo") 710 client.set_list (PANEL_KEY_BASE + "/general/toplevel_id_list", gconf.VALUE_STRING, toplevels) 711 poll (main_loop) 712 713 # Set random uninterpreted key back again 714 client.set_bool (PANEL_KEY_BASE + "/general/show_program_list", show_program_list) 715 poll (main_loop) 716 717 # Shutdown the client again 718 client.notify_remove (notify_id) 719 client.remove_dir (PANEL_KEY_BASE + "") 720 721 assert len (changes) == 4 722 for change in changes: 723 assert isinstance (change, userprofile.ProfileChange) 724 for change in changes[:3]: 725 assert isinstance (change, PanelChange) 726 assert change.id == "foo" 727 assert isinstance (changes[3], gconfsource.GConfChange) 728 assert changes[3].key == PANEL_KEY_BASE + "/general/show_program_list" 729 730 ( 731 PANEL_OBJECT_REMOVED, 732 PANEL_APPLET_REMOVED, 733 PANEL_REMOVED 734 ) = range (3) 735 736 assert isinstance (changes[PANEL_OBJECT_REMOVED], PanelObjectRemovedChange) 737 assert isinstance (changes[PANEL_APPLET_REMOVED], PanelAppletRemovedChange) 738 assert isinstance (changes[PANEL_REMOVED], PanelRemovedChange) 739 740 source.commit_change (changes[PANEL_REMOVED], False) 741 742 dprint ("Committed changes to %s", temp_path) 743 subprocess.call (["gconftool-2", "--shutdown"]) 744 time.sleep (1) 745 746 assert not os.access (os.path.join (temp_path, GCONF_DEFAULTS_SOURCE + "/apps/panel/toplevels/foo/%gconf.xml"), os.F_OK) 747 748 # Bye, bye cruft 749 subprocess.call (["gconftool-2", "--recursive-unset", "%s/toplevels/foo" % PANEL_KEY_BASE]) 750 subprocess.call (["gconftool-2", "--recursive-unset", "%s/objects/foo" % PANEL_KEY_BASE]) 751 subprocess.call (["gconftool-2", "--recursive-unset", "%s/applets/foo" % PANEL_KEY_BASE]) 752 753 shutil.rmtree (temp_path, True) 754