1# Group Properties Prototype 2# Copyright (c) 2003, Hans Breuer <hans@breuer.org> 3# 4# with multiple selected (but not grouped) objects builds a dialog 5# which contains widgets to change all different properties of the 6# objects. 7# 8# Known Issues : 9# - Currently the options to be changed are represented by strings 10# This is a limitation of PyDia, which does not wrap Dia's UI 11# elements yet 12# - ... 13 14# This program is free software; you can redistribute it and/or modify 15# it under the terms of the GNU General Public License as published by 16# the Free Software Foundation; either version 2 of the License, or 17# (at your option) any later version. 18# 19# This program is distributed in the hope that it will be useful, 20# but WITHOUT ANY WARRANTY; without even the implied warranty of 21# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22# GNU General Public License for more details. 23# 24# You should have received a copy of the GNU General Public License 25# along with this program; if not, write to the Free Software 26# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 27 28import sys, dia 29 30class CPropsDialog : 31 def __init__(self, diagram, data, props) : 32 import pygtk 33 pygtk.require("2.0") 34 import gtk 35 36 self.diagram = diagram 37 self.data = data 38 self.props = props 39 40 self.win = gtk.Window () 41 self.win.connect("delete_event", self.on_delete) 42 self.win.set_title("Group Properties") 43 44 box1 = gtk.VBox() 45 self.win.add(box1) 46 box1.show() 47 48 box2 = gtk.VBox(spacing=2) 49 box2.set_border_width(10) 50 box1.pack_start(box2) 51 box2.show() 52 53 self.checkboxes = [] 54 self.optionmenues = [] 55 table = gtk.Table(2, len(props), 0) 56 table.set_row_spacings(2) 57 table.set_col_spacings(5) 58 table.set_border_width(5) 59 y = 0 60 for s in props.keys() : 61 w = gtk.CheckButton(s) 62 self.checkboxes.append(w) 63 table.attach(w, 0, 1, y, y+1) 64 w.show() 65 menu = gtk.Menu() 66 milist = None 67 for opt in props[s].opts : 68 #print opt 69 menuitem = gtk.RadioMenuItem (milist, str(opt.value)) 70 milist = menuitem # GSlist 71 menu.append(menuitem) 72 menuitem.show() 73 menu.show () 74 w = gtk.OptionMenu() 75 w.set_menu(menu) 76 self.optionmenues.append(w) 77 table.attach(w, 1, 2, y, y+1) 78 w.show() 79 y = y + 1 80 else : 81 w = gtk.Label("The selected objects don't share any\n properties to change at once.") 82 table.attach(w, 0, 1, y, y+1) 83 w.show() 84 box2.pack_start(table) 85 table.show() 86 87 separator = gtk.HSeparator() 88 box1.pack_start(separator, expand=0) 89 separator.show() 90 91 box2 = gtk.VBox(spacing=10) 92 box2.set_border_width(10) 93 box1.pack_start(box2, expand=0) 94 box2.show() 95 96 button = gtk.Button("Ok") 97 button.connect("clicked", self.on_ok) 98 box2.pack_start(button) 99 button.set_flags(gtk.CAN_DEFAULT) 100 button.grab_default() 101 button.show() 102 self.win.show() 103 104 def on_ok (self, *args) : 105 grp = self.diagram.get_sorted_selected() 106 # change the requested properties 107 for i in range(0, len(self.checkboxes)) : 108 cb = self.checkboxes[i] 109 om = self.optionmenues[i] 110 if cb.get_active() : 111 for o in grp : 112 s = self.props.keys()[i] 113 o.properties[s] = self.props[s].opts[om.get_history()] 114 self.data.update_extents () 115 self.diagram.flush() 116 self.win.destroy() 117 118 def on_delete (self, *args) : 119 self.win.destroy () 120 121class PropInfo : 122 def __init__ (self, t, n, o) : 123 self.num = 1 124 self.type = t 125 self.name = n 126 self.opts = [o] 127 def __str__ (self) : 128 return self.name + ":" + str(self.opts) 129 def Add (self, o) : 130 self.num = self.num + 1 131 self.opts.append(o) 132 133def dia_objects_props_cb (data, flags) : 134 d = dia.active_display().diagram 135 grp = d.get_sorted_selected() 136 allProps = {} 137 numProps = len(grp) 138 # check for properties common to all select objects 139 for o in grp : 140 props = o.properties 141 for s in props.keys() : 142 if props[s].visible : 143 if allProps.has_key(s) : 144 allProps[s].Add(props[s]) 145 else : 146 allProps[s] = PropInfo(props[s].type, props[s].name, props[s]) 147 # now eliminate all props not common ... 148 for s in allProps.keys() : 149 if allProps[s].num < numProps : 150 del allProps[s] 151 # ... and all props already equal 152 for s in allProps.keys() : 153 o1 = allProps[s].opts[0] 154 for o in allProps[s].opts : 155 if o1.value != o.value : 156 o1 = None 157 break 158 if o1 != None : 159 del allProps[s] 160 else : 161 # if there is something left ensure unique values 162 uniques = {} 163 for o in allProps[s].opts : 164 if uniques.has_key(o.value) : 165 continue 166 uniques[o.value] = o 167 allProps[s].opts = [] 168 for v in uniques.keys() : 169 allProps[s].opts.append(uniques[v]) 170 # display the dialog 171 try : 172 dlg = CPropsDialog(d, data, allProps) 173 except ImportError : 174 dia.message(0, "Dialog creation failed. Missing pygtk?") 175 176dia.register_action ("DialogsGroupproperties", "Dia Group Properties", 177 "/DisplayMenu/Dialogs/DialogsExtensionStart", 178 dia_objects_props_cb) 179