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