Updating download.html page with Git information
[pythoncad.git] / PythonCAD / Interface / Gtk / gtkmodify.py
blobe22535ae398f2bc53c1c8312e04779d3a7a28d5a
2 # Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 Art Haas
4 # This file is part of PythonCAD.
5 #
6 # PythonCAD is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # PythonCAD is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with PythonCAD; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 # functions for doing modifications on drawing
22 # entities
25 import pygtk
26 pygtk.require('2.0')
27 import gtk
29 from math import atan2, pi
31 from PythonCAD.Generic.dimension import Dimension
32 from PythonCAD.Generic.dimension import LinearDimension
33 from PythonCAD.Generic.dimension import HorizontalDimension
34 from PythonCAD.Generic.dimension import VerticalDimension
35 from PythonCAD.Generic.dimension import RadialDimension
36 from PythonCAD.Generic.dimension import AngularDimension
37 from PythonCAD.Generic import color
38 from PythonCAD.Generic.graphicobject import GraphicObject
39 from PythonCAD.Generic.segment import Segment
40 from PythonCAD.Generic.circle import Circle
41 from PythonCAD.Generic.arc import Arc
42 from PythonCAD.Generic.polyline import Polyline
43 from PythonCAD.Generic.text import TextStyle, TextBlock
44 from PythonCAD.Generic.hcline import HCLine
45 from PythonCAD.Generic.acline import ACLine
46 from PythonCAD.Generic.vcline import VCLine
47 from PythonCAD.Generic.cline import CLine
48 from PythonCAD.Generic import util
49 from PythonCAD.Generic import split
51 import PythonCAD.Generic.units
52 import PythonCAD.Generic.move
53 import PythonCAD.Generic.transfer
54 import PythonCAD.Generic.delete
55 import PythonCAD.Generic.rotate
58 # common code
61 def select_motion_notify(gtkimage, widget, event, tool):
62 _tx, _ty = tool.getLocation()
63 _px, _py = gtkimage.coordToPixTransform(_tx, _ty)
64 _gc = gtkimage.getGC()
65 _x = int(event.x)
66 _y = int(event.y)
67 _cp = tool.getCurrentPoint()
68 if _cp is not None:
69 _xc, _yc = _cp
70 _xmin = min(_xc, _px)
71 _ymin = min(_yc, _py)
72 _rw = abs(_xc - _px)
73 _rh = abs(_yc - _py)
74 widget.window.draw_rectangle(_gc, False, _xmin, _ymin, _rw, _rh)
75 tool.setCurrentPoint(_x, _y)
76 _xmin = min(_x, _px)
77 _ymin = min(_y, _py)
78 _rw = abs(_x - _px)
79 _rh = abs(_y - _py)
80 widget.window.draw_rectangle(_gc, False, _xmin, _ymin, _rw, _rh)
81 return True
84 # move objects
87 def move_objects(gtkimage, objlist, tool):
88 _init_func = tool.getHandler("initialize")
89 _dx, _dy = tool.getDistance()
90 _image = gtkimage.getImage()
91 _image.startAction()
92 try:
93 PythonCAD.Generic.move.move_objects(objlist, _dx, _dy)
94 finally:
95 _image.endAction()
96 gtkimage.setPrompt(_('Click in the drawing area or enter a distance.'))
97 tool.reset()
98 _init_func(gtkimage, tool)
100 def move_button_press(gtkimage, tool):
101 _x, _y = gtkimage.image.getCurrentPoint()
103 # need to find if the point is an intersection of drawing objects ...
105 tool.pushObject(_x)
106 tool.pushObject(_y)
107 return True
109 def move_end_button_press_cb(gtkimage, widget, event, tool):
110 _image = gtkimage.getImage()
111 _x2, _y2 = _image.getCurrentPoint()
112 _x1, _y1 = tool.getLocation()
113 _xmin = min(_x1, _x2)
114 _xmax = max(_x1, _x2)
115 _ymin = min(_y1, _y2)
116 _ymax = max(_y1, _y2)
117 _active_layer = _image.getActiveLayer()
118 _objlist = _active_layer.objsInRegion(_xmin, _ymin, _xmax, _ymax)
119 move_objects(gtkimage, _objlist, tool)
120 return True
122 def move_elem_button_press_cb(gtkimage, widget, event, tool):
123 _tol = gtkimage.getTolerance()
124 _image = gtkimage.getImage()
125 _x, _y = _image.getCurrentPoint()
126 _objdict = _image.mapPoint(_x, _y, _tol, None)
127 if len(_objdict):
128 _active_layer = _image.getActiveLayer()
129 if _active_layer in _objdict:
130 _objs = []
131 for _obj, _pt in _objdict[_active_layer]:
132 _objs.append(_obj)
133 _dx, _dy = tool.getDistance()
134 move_objects(gtkimage, _objs, tool)
135 else:
136 _pt, _pc = _image.getClosestPoint(_x, _y, tolerance=_tol)
137 if _pt is not None:
138 _x, _y = _pt.getCoords()
139 else:
140 _x, _y = _pc
141 tool.setLocation(_x, _y)
142 tool.setHandler("motion_notify", select_motion_notify)
143 tool.setHandler("button_press", move_end_button_press_cb)
144 gtkimage.setPrompt(_('Click the second point for defining the region'))
145 _gc = gtkimage.getGC()
146 _gc.set_line_attributes(1, gtk.gdk.LINE_SOLID,
147 gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER)
148 _gc.set_function(gtk.gdk.INVERT)
149 return True
152 # move horizontal
155 def move_horizontal_entry_event(gtkimage, widget, tool):
156 _entry = gtkimage.getEntry()
157 _text = _entry.get_text()
158 _entry.delete_text(0,-1)
159 if len(_text):
160 _image = gtkimage.getImage()
161 _dist = util.get_float(eval(_text, _image.getImageVariables()))
162 tool.setDistance(_dist, 0.0)
163 if _image.hasSelection():
164 move_objects(gtkimage, _image.getSelectedObjects(), tool)
165 else:
166 gtkimage.setPrompt(_('Click on the objects to move.'))
167 tool.setHandler("button_press", move_elem_button_press_cb)
168 tool.delHandler("entry_event")
170 def move_horizontal_second_button_press_cb(gtkimage, widget, event, tool):
171 _tol = gtkimage.getTolerance()
172 _image = gtkimage.getImage()
173 _x, _y = _image.getCurrentPoint()
174 _pt, _pc = _image.getClosestPoint(_x, _y, tolerance=_tol)
175 if _pt is not None:
176 _x, _y = _pt.getCoords()
177 else:
178 _x, _y = _pc
179 _x1, _y1 = tool.getLocation()
180 tool.setDistance((_x - _x1), 0.0)
181 if _image.hasSelection():
182 move_objects(gtkimage, _image.getSelectedObjects(), tool)
183 else:
184 tool.clearLocation()
185 gtkimage.setPrompt(_('Select the objects to move.'))
186 tool.setHandler("button_press", move_elem_button_press_cb)
187 tool.delHandler("entry_event")
188 return True
190 def move_horizontal_first_button_press_cb(gtkimage, widget, event, tool):
191 _tol = gtkimage.getTolerance()
192 _image = gtkimage.getImage()
193 _x, _y = _image.getCurrentPoint()
194 _pt, _pc = _image.getClosestPoint(_x, _y, tolerance=_tol)
195 if _pt is not None:
196 _x, _y = _pt.getCoords()
197 else:
198 _x, _y = _pc
199 tool.setLocation(_x, _y)
200 gtkimage.setPrompt(_('Click another point to define the distance'))
201 tool.setHandler("button_press", move_horizontal_second_button_press_cb)
202 return True
204 def move_horizontal_init(gtkimage, tool=None):
205 gtkimage.setPrompt(_('Click in the drawing area or enter the distance.'))
206 _tool = gtkimage.getImage().getTool()
207 _tool.setHandler("button_press", move_horizontal_first_button_press_cb)
208 _tool.setHandler("entry_event", move_horizontal_entry_event)
209 _tool.setHandler("initialize", move_horizontal_init)
213 # move vertical
216 def move_vertical_entry_event(gtkimage, widget, tool):
217 _entry = gtkimage.getEntry()
218 _text = _entry.get_text()
219 _entry.delete_text(0,-1)
220 if len(_text):
221 _image = gtkimage.getImage()
222 _dist = util.get_float(eval(_text, _image.getImageVariables()))
223 tool.setDistance(0.0, _dist)
224 if _image.hasSelection():
225 move_objects(gtkimage, _image.getSelectedObjects(), tool)
226 else:
227 gtkimage.setPrompt(_('Click on the objects to move.'))
228 tool.setHandler("button_press", move_elem_button_press_cb)
229 tool.delHandler("entry_event")
231 def move_vertical_second_button_press_cb(gtkimage, widget, event, tool):
232 _tol = gtkimage.getTolerance()
233 _image = gtkimage.getImage()
234 _x, _y = _image.getCurrentPoint()
235 _pt, _pc = _image.getClosestPoint(_x, _y, tolerance=_tol)
236 if _pt is not None:
237 _x, _y = _pt.getCoords()
238 else:
239 _x, _y = _pc
240 _x1, _y1 = tool.getLocation()
241 tool.setDistance(0.0, (_y - _y1))
242 if _image.hasSelection():
243 move_objects(gtkimage, _image.getSelectedObjects(), tool)
244 else:
245 tool.clearLocation()
246 gtkimage.setPrompt(_('Select the objects to move.'))
247 tool.setHandler("button_press", move_elem_button_press_cb)
248 tool.delHandler("entry_event")
249 return True
251 def move_vertical_first_button_press_cb(gtkimage, widget, event, tool):
252 _tol = gtkimage.getTolerance()
253 _image = gtkimage.getImage()
254 _x, _y = _image.getCurrentPoint()
255 _pt, _pc = _image.getClosestPoint(_x, _y, tolerance=_tol)
256 if _pt is not None:
257 _x, _y = _pt.getCoords()
258 else:
259 _x, _y = _pc
260 tool.setLocation(_x, _y)
261 gtkimage.setPrompt(_('Click another point to define the distance'))
262 tool.setHandler("button_press", move_vertical_second_button_press_cb)
263 return True
265 def move_vertical_init(gtkimage, tool=None):
266 gtkimage.setPrompt(_('Click in the drawing area or enter the distance.'))
267 _tool = gtkimage.getImage().getTool()
268 _tool.setHandler("button_press", move_vertical_first_button_press_cb)
269 _tool.setHandler("entry_event", move_vertical_entry_event)
270 _tool.setHandler("initialize", move_vertical_init)
274 # move based on two mouse clicks
277 def move_xy_entry_event(gtkimage, widget, tool):
278 _entry = gtkimage.getEntry()
279 _text = _entry.get_text()
280 _entry.delete_text(0,-1)
281 if len(_text):
282 _image = gtkimage.getImage()
283 _x, _y = eval(_text, _image.getImageVariables())
284 tool.setDistance(util.get_float(_x), util.get_float(_y))
285 if _image.hasSelection():
286 move_objects(gtkimage, _image.getSelectedObjects(), tool)
287 else:
288 gtkimage.setPrompt(_('Click on the objects to move.'))
289 tool.setHandler("button_press", move_elem_button_press_cb)
290 tool.delHandler("entry_event")
292 def move_xy_second_button_press_cb(gtkimage, widget, event, tool):
293 _tol = gtkimage.getTolerance()
294 _image = gtkimage.getImage()
295 _x, _y = _image.getCurrentPoint()
296 _pt, _pc = _image.getClosestPoint(_x, _y, tolerance=_tol)
297 if _pt is not None:
298 _x, _y = _pt.getCoords()
299 else:
300 _x, _y = _pc
301 _x1, _y1 = tool.getLocation()
302 tool.setDistance((_x - _x1), (_y - _y1))
303 if _image.hasSelection():
304 move_objects(gtkimage, _image.getSelectedObjects(), tool)
305 else:
306 tool.clearLocation()
307 gtkimage.setPrompt(_('Select the objects to move.'))
308 tool.setHandler("button_press", move_elem_button_press_cb)
309 tool.delHandler("entry_event")
310 return True
312 def move_xy_first_button_press_cb(gtkimage, widget, event, tool):
313 _tol = gtkimage.getTolerance()
314 _image = gtkimage.getImage()
315 _x, _y = _image.getCurrentPoint()
316 _pt, _pc = _image.getClosestPoint(_x, _y, tolerance=_tol)
317 if _pt is not None:
318 _x, _y = _pt.getCoords()
319 else:
320 _x, _y = _pc
321 tool.setLocation(_x, _y)
322 gtkimage.setPrompt(_('Click another point to define the distance'))
323 tool.setHandler("button_press", move_xy_second_button_press_cb)
324 return True
326 def move_twopoint_init(gtkimage, tool=None):
327 gtkimage.setPrompt(_('Click in the drawing area or enter the x and y distances.'))
328 _tool = gtkimage.getImage().getTool()
329 _tool.setHandler("button_press", move_xy_first_button_press_cb)
330 _tool.setHandler("entry_event", move_xy_entry_event)
331 _tool.setHandler("initialize", move_twopoint_init)
335 # delete objects
338 def delete_region_end_cb(gtkimage, widget, event, tool):
339 _image = gtkimage.getImage()
340 _x2, _y2 = _image.getCurrentPoint()
341 _x1, _y1 = tool.getLocation()
342 _xmin = min(_x1, _x2)
343 _xmax = max(_x1, _x2)
344 _ymin = min(_y1, _y2)
345 _ymax = max(_y1, _y2)
346 tool.delHandler("motion_notify")
347 tool.setHandler("button_press", delete_button_press_cb)
348 _active_layer = _image.getActiveLayer()
349 _objs = _active_layer.objsInRegion(_xmin, _ymin, _xmax, _ymax)
350 if len(_objs):
351 _image.startAction()
352 try:
353 PythonCAD.Generic.delete.delete_objects(_objs)
354 finally:
355 _image.endAction()
356 tool.reset()
357 delete_mode_init(gtkimage)
359 def delete_button_press_cb(gtkimage, widget, event, tool):
360 _tol = gtkimage.getTolerance()
361 _image = gtkimage.getImage()
362 _x, _y = _image.getCurrentPoint()
363 _active_layer = _image.getActiveLayer()
364 _objs = _active_layer.mapPoint((_x, _y), _tol)
365 if len(_objs):
366 _dims = []
367 _image.startAction()
368 try:
369 for _obj in _objs:
370 if isinstance(_obj, Dimension):
371 _dims.append(_obj)
372 elif isinstance(_obj, tuple):
373 _entity, _pt = _obj
374 _active_layer.delObject(_entity)
375 else:
376 raise TypeError, "Unhandled object: " + `_obj`
377 for _dim in _dims:
378 if _dim in _active_layer: # it may have been removed ...
379 _active_layer.delObject(_dim)
380 finally:
381 _image.endAction()
382 else:
383 tool.setLocation(_x, _y)
384 tool.setHandler("motion_notify", select_motion_notify)
385 tool.setHandler("button_press", delete_region_end_cb)
386 gtkimage.setPrompt(_('Click the second point for defining the region'))
387 _gc = gtkimage.getGC()
388 _gc.set_line_attributes(1, gtk.gdk.LINE_SOLID,
389 gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER)
390 _gc.set_function(gtk.gdk.INVERT)
391 return True
393 def delete_mode_init(gtkimage, tool=None):
394 gtkimage.setPrompt(_('Click on the items you want to delete.'))
395 _tool = gtkimage.getImage().getTool()
396 _tool.setHandler("button_press", delete_button_press_cb)
397 _tool.setHandler("initialize", delete_mode_init)
398 _image = gtkimage.getImage()
399 if _image.hasSelection():
400 _objs = _image.getSelectedObjects()
401 _image.startAction()
402 try:
403 PythonCAD.Generic.delete.delete_objects(_objs)
404 finally:
405 _image.endAction()
408 # stretch operations
411 def stretch_end_button_press_cb(gtkimage, widget, event, tool):
412 _image = gtkimage.getImage()
413 _x2, _y2 = _image.getCurrentPoint()
414 _y1 = tool.popObject()
415 _x1 = tool.popObject()
416 _xmin = min(_x1, _x2)
417 _xmax = max(_x1, _x2)
418 _ymin = min(_y1, _y2)
419 _ymax = max(_y1, _y2)
420 tool.delHandler("motion_notify")
421 _active_layer = _image.getActiveLayer()
422 _dx, _dy = tool.getDistance()
423 _image.startAction()
424 try:
425 for _pt in _active_layer.getLayerEntities("point"):
426 if _pt.inRegion(_xmin, _ymin, _xmax, _ymax):
427 _pt.move(_dx, _dy)
428 finally:
429 _image.endAction()
430 tool.clearLocation()
431 tool.clearCurrentPoint()
432 tool.setHandler("button_press", stretch_elem_button_press_cb)
433 return True
435 def stretch_elem_button_press_cb(gtkimage, widget, event, tool):
436 _tol = gtkimage.getTolerance()
437 _image = gtkimage.getImage()
438 _x, _y = _image.getCurrentPoint()
439 _active_layer = _image.getActiveLayer()
440 _pt = None
441 _pts = _active_layer.find('point', _x, _y, _tol)
442 if len(_pts):
443 _dx, _dy = tool.getDistance()
444 _image.startAction()
445 try:
446 for _pt in _pts:
447 _pt.move(_dx, _dy)
448 finally:
449 _image.endAction()
450 else:
451 tool.pushObject(_x)
452 tool.pushObject(_y)
453 tool.setLocation(_x, _y)
454 tool.setHandler("motion_notify", select_motion_notify)
455 tool.setHandler("button_press", stretch_end_button_press_cb)
456 gtkimage.setPrompt(_('Click the second point for defining the region'))
457 _gc = gtkimage.getGC()
458 _gc.set_line_attributes(1, gtk.gdk.LINE_SOLID,
459 gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER)
460 _gc.set_function(gtk.gdk.INVERT)
461 return True
464 # stretch horizontal
467 def stretch_horiz_button_press_cb(gtkimage, widget, event, tool):
468 if not len(tool):
469 move_button_press(gtkimage, tool)
470 gtkimage.setPrompt(_('Click a second point to indicate the horizontal distance'))
471 else:
472 _x, _y = gtkimage.image.getCurrentPoint()
474 # see if the point is at an intersection of drawing objects ...
476 _y1 = tool.popObject()
477 _x1 = tool.popObject()
478 tool.setDistance((_x - _x1), 0.0)
479 gtkimage.setPrompt(_('Select the points to move.'))
480 tool.delHandler("entry_event")
481 tool.setHandler("button_press", stretch_elem_button_press_cb)
482 return True
484 def stretch_horiz_entry_event(gtkimage, widget, tool):
485 _entry = gtkimage.getEntry()
486 _text = _entry.get_text()
487 _entry.delete_text(0,-1)
488 if len(_text):
489 _dist = util.get_float(eval(_text, gtkimage.image.getImageVariables()))
490 tool.setDistance(_dist, 0.0)
491 gtkimage.setPrompt(_('Select the points to move.'))
492 tool.setHandler("button_press", stretch_elem_button_press_cb)
493 tool.delHandler("entry_event")
495 def stretch_horizontal_init(gtkimage, tool=None):
496 gtkimage.setPrompt(_('Click on a point or enter the horizontal distance.'))
497 _tool = gtkimage.getImage().getTool()
498 _tool.initialize()
499 _tool.setHandler("button_press", stretch_horiz_button_press_cb)
500 _tool.setHandler("entry_event", stretch_horiz_entry_event)
501 _tool.setHandler("initialize", stretch_horizontal_init)
505 # stretch vertical
508 def stretch_vert_button_press_cb(gtkimage, widget, event, tool):
509 if not len(tool):
510 move_button_press(gtkimage, tool)
511 gtkimage.setPrompt(_('Click a second point to indicate the vertical distance'))
512 else:
513 _x, _y = gtkimage.image.getCurrentPoint()
515 # see if the point is at an intersection of drawing objects ...
517 _y1 = tool.popObject()
518 _x1 = tool.popObject()
519 tool.setDistance(0.0, (_y - _y1))
520 gtkimage.setPrompt(_('Select the points to move.'))
521 tool.delHandler("entry_event")
522 tool.setHandler("button_press", stretch_elem_button_press_cb)
523 return True
525 def stretch_vert_entry_event(gtkimage, widget, tool):
526 _entry = gtkimage.getEntry()
527 _text = _entry.get_text()
528 _entry.delete_text(0,-1)
529 if len(_text):
530 _dist = util.get_float(eval(_text, gtkimage.image.getImageVariables()))
531 tool.setDistance(0.0, _dist)
532 gtkimage.setPrompt(_('Select the points to move.'))
533 tool.setHandler("button_press", stretch_elem_button_press_cb)
534 tool.delHandler("entry_event")
536 def stretch_vertical_init(gtkimage, tool=None):
537 gtkimage.setPrompt(_('Click in the drawing area or enter the distance.'))
538 _tool = gtkimage.getImage().getTool()
539 _tool.initialize()
540 _tool.setHandler("button_press", stretch_vert_button_press_cb)
541 _tool.setHandler("entry_event", stretch_vert_entry_event)
542 _tool.setHandler("initialize", stretch_vertical_init)
546 # stretch x/y
549 def stretch_xy_entry_event(gtkimage, widget, tool):
550 _entry = gtkimage.getEntry()
551 _text = _entry.get_text()
552 _entry.delete_text(0,-1)
553 if len(_text):
554 _x, _y = eval(_text, gtkimage.image.getImageVariables())
555 tool.setDistance(util.get_float(_x), util.get_float(_y))
556 gtkimage.setPrompt(_('Select the points to move.'))
557 tool.setHandler("button_press", stretch_elem_button_press_cb)
558 tool.delHandler("entry_event")
560 def stretch_xy_second_button_press_cb(gtkimage, widget, event, tool):
561 _tol = gtkimage.getTolerance()
562 _image = gtkimage.getImage()
563 _x, _y = _image.getCurrentPoint()
564 _pt, _pc = _image.getClosestPoint(_x, _y, tolerance=_tol)
565 if _pt is not None:
566 _x, _y = _pt.getCoords()
567 else:
568 _x, _y = _pc
569 _x1, _y1 = tool.getLocation()
570 tool.setDistance((_x - _x1), (_y - _y1))
571 tool.clearLocation()
572 gtkimage.setPrompt(_('Select the points to move.'))
573 tool.setHandler("button_press", stretch_elem_button_press_cb)
574 tool.delHandler("entry_event")
575 return True
577 def stretch_xy_first_button_press_cb(gtkimage, widget, event, tool):
578 _tol = gtkimage.getTolerance()
579 _image = gtkimage.getImage()
580 _x, _y = _image.getCurrentPoint()
581 _pt, _pc = _image.getClosestPoint(_x, _y, tolerance=_tol)
582 if _pt is not None:
583 _x, _y = _pt.getCoords()
584 else:
585 _x, _y = _pc
586 tool.setLocation(_x, _y)
587 gtkimage.setPrompt(_('Click another point to define the distance'))
588 tool.setHandler("button_press", stretch_xy_second_button_press_cb)
589 return True
591 def stretch_xy_init(gtkimage, tool=None):
592 gtkimage.setPrompt(_('Click in the drawing area or enter the x and y distances.'))
593 _tool = gtkimage.getImage().getTool()
594 _tool.setHandler("button_press", stretch_xy_first_button_press_cb)
595 _tool.setHandler("entry_event", stretch_xy_entry_event)
596 _tool.setHandler("initialize", stretch_xy_init)
600 # rotate objects
603 def rotate_objects(gtkimage, objlist, tool):
604 _init_func = tool.getHandler("initialize")
605 _cx, _cy = tool.getRotationPoint()
606 _angle = tool.getAngle()
607 _image = gtkimage.getImage()
608 _image.startAction()
609 try:
610 PythonCAD.Generic.rotate.rotate_objects(objlist, _cx, _cy, _angle)
611 finally:
612 _image.endAction()
613 tool.reset()
614 _init_func(gtkimage, tool)
616 def rotate_end_button_press_cb(gtkimage, widget, event, tool):
617 _image = gtkimage.getImage()
618 _x2, _y2 = _image.getCurrentPoint()
619 _x1, _y1 = tool.getLocation()
620 _xmin = min(_x1, _x2)
621 _xmax = max(_x1, _x2)
622 _ymin = min(_y1, _y2)
623 _ymax = max(_y1, _y2)
624 _active_layer = _image.getActiveLayer()
625 _objlist = _active_layer.objsInRegion(_xmin, _ymin, _xmax, _ymax)
626 rotate_objects(gtkimage, _objlist, tool)
627 return True
629 def rotate_elem_button_press_cb(gtkimage, widget, event, tool):
630 _tol = gtkimage.getTolerance()
631 _image = gtkimage.getImage()
632 _x, _y = _image.getCurrentPoint()
633 _objdict = _image.mapPoint(_x, _y, _tol, None)
634 if len(_objdict):
635 _active_layer = _image.getActiveLayer()
636 if _active_layer in _objdict:
637 _objs = []
638 for _obj, _pt in _objdict[_active_layer]:
639 _objs.append(_obj)
640 rotate_objects(gtkimage, _objs, tool)
641 else:
642 _pt, _pc = _image.getClosestPoint(_x, _y, tolerance=_tol)
643 if _pt is not None:
644 _x, _y = _pt.getCoords()
645 else:
646 _x, _y = _pc
647 tool.setLocation(_x, _y)
648 tool.setHandler("motion_notify", select_motion_notify)
649 tool.setHandler("button_press", rotate_end_button_press_cb)
650 gtkimage.setPrompt(_('Click the second point for defining the region'))
651 _gc = gtkimage.getGC()
652 _gc.set_line_attributes(1, gtk.gdk.LINE_SOLID,
653 gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER)
654 _gc.set_function(gtk.gdk.INVERT)
655 return True
657 def rotate_angle_entry_event(gtkimage, widget, tool):
658 _entry = gtkimage.getEntry()
659 _text = _entry.get_text()
660 _entry.delete_text(0,-1)
661 if len(_text):
662 _angle = eval(_text, gtkimage.image.getImageVariables())
663 tool.setAngle(util.get_float(_angle))
664 gtkimage.setPrompt(_('Select the objects to rotate'))
665 tool.delHandler("entry_event")
666 tool.setHandler("button_press", rotate_elem_button_press_cb)
668 def rotate_angle_second_button_press_cb(gtkimage, widget, event, tool):
669 _tol = gtkimage.getTolerance()
670 _image = gtkimage.getImage()
671 _x, _y = _image.getCurrentPoint()
672 _objdict = _image.mapPoint(_x, _y, _tol)
673 _a2 = None
674 if len(_objdict):
675 _active_layer = _image.getActiveLayer()
676 if _active_layer in _objdict:
677 for _obj, _pt in _objdict[_active_layer]:
678 if isinstance(_obj, HCLine):
679 _a2 = 0.0
680 elif isinstance(_obj, VCLine):
681 _a2 = 90.0
682 elif isinstance(_obj, ACLine):
683 _a2 = _obj.getAngle()
684 elif isinstance(_obj, CLine):
685 _p1, _p2 = _obj.getKeypoints()
686 _a2 = atan2((_p2.y - _p1.y), (_p2.x - _p1.x)) * (180.0/pi)
687 else:
688 pass
689 if _a2 is not None:
690 break
691 if _a2 is not None:
692 _cl = tool.getObject(0)
693 if isinstance(_cl, HCLine):
694 _a1 = 0.0
695 elif isinstance(_cl, VCLine):
696 _a1 = 90.0
697 elif isinstance(_cl, ACLine):
698 _a1 = _cl.getAngle()
699 elif isinstance(_cl, CLine):
700 _p1, _p2 = _cl.getKeypoints()
701 _a1 = atan2((_p2.y - _p1.y), (_p2.x - _p1.x)) * (180.0/pi)
702 else:
703 raise RuntimeError, "Unexpected conline type: " + `type(_cl)`
704 _angle = _a2 - _a1
705 if abs(_angle) > 1e-10:
706 tool.setAngle(_angle)
707 gtkimage.setPrompt(_('Select the objects to rotate'))
708 tool.delHandler("entry_event")
709 tool.setHandler("button_press", rotate_elem_button_press_cb)
710 return True
712 def rotate_angle_first_button_press_cb(gtkimage, widget, event, tool):
713 _tol = gtkimage.getTolerance()
714 _image = gtkimage.getImage()
715 _x, _y = _image.getCurrentPoint()
716 _objdict = _image.mapPoint(_x, _y, _tol)
717 if len(_objdict):
718 _active_layer = _image.getActiveLayer()
719 if _active_layer in _objdict:
720 for _obj, _pt in _objdict[_active_layer]:
721 if isinstance(_obj, (HCLine, VCLine, ACLine, CLine)):
722 tool.pushObject(_obj)
723 tool.setHandler("button_press",
724 rotate_angle_second_button_press_cb)
725 gtkimage.setPrompt(_('Click on another construction line to define the angle of rotation or enter the rotation angle.'))
726 break
727 return True
729 def rotate_point_entry_event(gtkimage, widget, tool):
730 _entry = gtkimage.getEntry()
731 _text = _entry.get_text()
732 _entry.delete_text(0,-1)
733 if len(_text):
734 _x, _y = eval(_text, gtkimage.image.getImageVariables())
735 tool.setRotationPoint(util.get_float(_x), util.get_float(_y))
736 gtkimage.setPrompt(_('Click on a construction line or enter the rotation angle.'))
737 tool.setHandler("entry_event", rotate_angle_entry_event)
738 tool.setHandler("button_press", rotate_angle_first_button_press_cb)
740 def rotate_point_button_press_cb(gtkimage, widget, event, tool):
741 _tol = gtkimage.getTolerance()
742 _image = gtkimage.getImage()
743 _x, _y = _image.getCurrentPoint()
744 _pt, _pc = _image.getClosestPoint(_x, _y, tolerance=_tol)
745 if _pt is not None:
746 _x, _y = _pt.getCoords()
747 else:
748 _x, _y = _pc
749 tool.setRotationPoint(_x, _y)
750 gtkimage.setPrompt(_('Click on a construction line or enter the rotation angle'))
751 tool.setHandler("button_press", rotate_angle_first_button_press_cb)
752 tool.setHandler("entry_event", rotate_angle_entry_event)
753 return True
755 def rotate_init(gtkimage, tool=None):
756 gtkimage.setPrompt(_('Click in the drawing area or enter the rotation center coordinates.'))
757 _tool = gtkimage.getImage().getTool()
758 _tool.setHandler("button_press", rotate_point_button_press_cb)
759 _tool.setHandler("entry_event", rotate_point_entry_event)
760 _tool.setHandler("initialize", rotate_init)
764 # split objects into two pieces or at intersection points
767 def split_end_button_press_cb(gtkimage, widget, event, tool):
768 _image = gtkimage.getImage()
769 _x2, _y2 = _image.getCurrentPoint()
770 _y1 = tool.popObject()
771 _x1 = tool.popObject()
772 _xmin = min(_x1, _x2)
773 _xmax = max(_x1, _x2)
774 _ymin = min(_y1, _y2)
775 _ymax = max(_y1, _y2)
776 tool.delHandler("motion_notify")
777 _active_layer = _image.getActiveLayer()
778 _objs = _active_layer.objsInRegion(_xmin, _ymin, _xmax, _ymax, True)
779 if len(_objs):
780 _splitable = []
781 for _obj in _objs:
782 if isinstance(_obj, (Segment, Circle, Arc, Polyline)):
783 _splitable.append(_obj)
784 if len(_splitable):
785 _image.startAction()
786 try:
787 split.split_objects(_splitable)
788 finally:
789 _image.endAction()
790 gtkimage.setPrompt(_('Click on the objects you want to split.'))
791 tool.clearLocation()
792 tool.clearCurrentPoint()
793 tool.setHandler("button_press", split_object_button_press_cb)
794 return True
796 def split_object_button_press_cb(gtkimage, widget, event, tool):
797 _tol = gtkimage.getTolerance()
798 _image = gtkimage.getImage()
799 _x, _y = _image.getCurrentPoint()
800 _active_layer = _image.getActiveLayer()
801 _objlist = _active_layer.mapPoint((_x, _y), _tol, None)
802 if len(_objlist):
803 for _obj, _pt in _objlist:
804 _px, _py = _pt.getCoords()
805 if isinstance(_obj, Segment):
806 _image.startAction()
807 try:
808 _segs = split.split_segment_at(_obj, _px, _py)
809 if _segs is not None:
810 _active_layer.delObject(_obj)
811 _s1, _s2 = _segs
812 _active_layer.addObject(_s1)
813 _active_layer.addObject(_s2)
814 finally:
815 _image.endAction()
816 elif isinstance(_obj, Arc):
817 _image.startAction()
818 try:
819 _arcs = split.split_arc_at(_obj, _px, _py)
820 if _arcs is not None:
821 _active_layer.delObject(_obj)
822 _a1, _a2 = _arcs
823 _active_layer.addObject(_a1)
824 _active_layer.addObject(_a2)
825 finally:
826 _image.endAction()
827 elif isinstance(_obj, Circle):
828 _image.startAction()
829 try:
830 _arc = split.split_circle_at(_obj, _px, _py)
831 if _arc is not None:
832 _active_layer.delObject(_obj)
833 _active_layer.addObject(_arc)
834 finally:
835 _image.endAction()
836 elif isinstance(_obj, Polyline):
837 _image.startAction()
838 try:
839 if split.split_polyline_at(_obj, _px, _py):
840 _obj.erase(gtkimage)
841 _obj.draw(gtkimage)
842 finally:
843 _image.endAction()
844 else:
845 pass
846 else:
847 tool.pushObject(_x)
848 tool.pushObject(_y)
849 tool.setLocation(_x, _y)
850 tool.setHandler("motion_notify", select_motion_notify)
851 tool.setHandler("button_press", split_end_button_press_cb)
852 gtkimage.setPrompt(_('Click the second point for defining the region'))
853 _gc = gtkimage.getGC()
854 _gc.set_line_attributes(1, gtk.gdk.LINE_SOLID,
855 gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER)
856 _gc.set_function(gtk.gdk.INVERT)
857 return True
859 def split_object_init(gtkimage, tool=None):
860 gtkimage.setPrompt(_('Click on the objects you want to split'))
861 _tool = gtkimage.getImage().getTool()
862 _tool.initialize()
863 _tool.setHandler("initialize", split_object_init)
864 _tool.setHandler("button_press", split_object_button_press_cb)
865 _image = gtkimage.getImage()
866 if _image.hasSelection():
867 _splitable = []
868 for _obj in _image.getSelectedObjects():
869 if isinstance(_obj, (Segment, Circle, Arc, Polyline)):
870 _splitable.append(_obj)
871 if len(_splitable):
872 _image.startAction()
873 try:
874 split.split_objects(_splitable)
875 finally:
876 _image.endAction()
879 # transfer objects from one layer to another
882 def transfer_end_button_press_cb(gtkimage, widget, event, tool):
883 _image = gtkimage.getImage()
884 _x2, _y2 = _image.getCurrentPoint()
885 _y1 = tool.popObject()
886 _x1 = tool.popObject()
887 _xmin = min(_x1, _x2)
888 _xmax = max(_x1, _x2)
889 _ymin = min(_y1, _y2)
890 _ymax = max(_y1, _y2)
891 tool.delHandler("motion_notify")
892 _active_layer = _image.getActiveLayer()
893 _layers = [_image.getTopLayer()]
894 _objdict = {}
895 while len(_layers):
896 _layer = _layers.pop()
897 if _layer is not _active_layer:
898 if _layer.isVisible():
899 _objs = _layer.objsInRegion(_xmin, _ymin, _xmax, _ymax)
900 if len(_objs):
901 _objdict[_layer] = _objs
902 _layers.extend(_layer.getSublayers())
903 if len(_objdict):
904 _image.startAction()
905 try:
906 for _layer in _objdict:
907 if _layer is not _active_layer:
908 _objs = _objdict[_layer]
909 PythonCAD.Generic.transfer.transfer_objects(_objs, _active_layer)
910 finally:
911 _image.endAction()
912 tool.clearLocation()
913 tool.clearCurrentPoint()
914 tool.setHandler("button_press", transfer_object_button_press_cb)
915 return True
917 def transfer_object_button_press_cb(gtkimage, widget, event, tool):
918 _tol = gtkimage.getTolerance()
919 _image = gtkimage.getImage()
920 _x, _y = _image.getCurrentPoint()
921 _active_layer = _image.getActiveLayer()
922 _objdict = _image.mapPoint(_x, _y, _tol, None)
923 if len(_objdict):
924 _image.startAction()
925 try:
926 for _layer in _objdict:
927 if _layer is not _active_layer:
928 _objs = []
929 for _obj, _pt in _objdict[_layer]:
930 _objs.append(_obj)
931 PythonCAD.Generic.transfer.transfer_objects(_objs, _active_layer)
932 finally:
933 _image.endAction()
934 else:
935 tool.pushObject(_x)
936 tool.pushObject(_y)
937 tool.setLocation(_x, _y)
938 tool.setHandler("motion_notify", select_motion_notify)
939 tool.setHandler("button_press", transfer_end_button_press_cb)
940 gtkimage.setPrompt(_('Click the second point for defining the region'))
941 gc = gtkimage.getGC()
942 gc.set_line_attributes(1, gtk.gdk.LINE_SOLID,
943 gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER)
944 gc.set_function(gtk.gdk.INVERT)
945 return True
947 def transfer_object_init(gtkimage, tool=None):
948 gtkimage.setPrompt(_('Click on the objects you want to transfer to the active layer'))
949 _tool = gtkimage.getImage().getTool()
950 _tool.initialize()
951 _tool.setHandler("button_press", transfer_object_button_press_cb)
954 # common attribute changing code
957 def _change_attribute(gtkimage, objlist, tool=None):
958 _tool = gtkimage.getImage().getTool()
959 _init = _tool.getHandler('initialize')
960 _attr = _tool.getAttribute()
961 _value = _tool.getValue()
962 if len(objlist):
963 _image = gtkimage.getImage()
964 _image.startAction()
965 try:
966 for _obj in objlist:
967 getattr(_obj, _attr)(_value)
968 finally:
969 _image.endAction()
970 _tool.reset()
971 _init(gtkimage, _tool)
973 def change_attr_second_button_press_cb(gtkimage, widget, event, tool):
974 _tol = gtkimage.getTolerance()
975 _image = gtkimage.getImage()
976 _x, _y = _image.getCurrentPoint()
977 _active_layer = _image.getActiveLayer()
978 _pts = _active_layer.find('point', _x, _y)
979 if len(_pts) > 0:
980 _x, _y = _pts[0].getCoords()
981 _x1, _y1 = tool.getLocation()
982 _xmin = min(_x1, _x)
983 _ymin = min(_y1, _y)
984 _xmax = max(_x1, _x)
985 _ymax = max(_y1, _y)
986 _objs = []
987 _filter = tool.getFilter()
988 _objtype = tool.getObjtype()
989 for _obj in _active_layer.objsInRegion(_xmin, _ymin, _xmax, _ymax):
990 if _filter is not None:
991 _fobj = _filter(tool, _obj)
992 if _fobj is not None:
993 _objs.append(_fobj)
994 elif _objtype is not None:
995 if isinstance(_obj, _objtype):
996 _objs.append(_obj)
997 else:
998 _objs.append(_obj)
999 _change_attribute(gtkimage, _objs, tool)
1000 return True
1002 def change_attr_first_button_press_cb(gtkimage, widget, event, tool):
1003 _tol = gtkimage.getTolerance()
1004 _image = gtkimage.getImage()
1005 _x, _y = _image.getCurrentPoint()
1006 _objdict = _image.mapPoint(_x, _y, _tol, None)
1007 if len(_objdict):
1008 _active_layer = _image.getActiveLayer()
1009 if _active_layer in _objdict:
1010 _objs = []
1011 _objtype = tool.getObjtype()
1012 for _obj, _pt in _objdict[_active_layer]:
1013 if _objtype is None:
1014 _objs.append(_obj)
1015 else:
1016 if isinstance(_obj, _objtype):
1017 _objs.append(_obj)
1018 _change_attribute(gtkimage, _objs, tool)
1019 else:
1020 _pt, _pc = _image.getClosestPoint(_x, _y, tolerance=_tol)
1021 if _pt is not None:
1022 _x, _y = _pt.getCoords()
1023 else:
1024 _x, _y = _pc
1025 tool.setLocation(_x, _y)
1026 tool.setHandler("motion_notify", select_motion_notify)
1027 tool.setHandler("button_press", change_attr_second_button_press_cb)
1028 gtkimage.setPrompt(_('Click the second point for defining the region'))
1029 gtkimage.getGC().set_function(gtk.gdk.INVERT)
1030 return True
1033 # change color
1036 def change_color_init(gtkimage, tool=None):
1037 _tool = gtkimage.getImage().getTool()
1038 _tool.setHandler("initialize", change_color_init)
1039 _image = gtkimage.getImage()
1040 if _image.hasSelection():
1041 _objs = []
1042 for _obj in _image.getSelectedObjects():
1043 if isinstance(_obj, GraphicObject):
1044 _objs.append(_obj)
1045 _change_attribute(gtkimage, _objs, _tool)
1046 else:
1047 gtkimage.setPrompt(_('Click the items you want the color to change.'))
1048 _tool.setHandler("button_press", change_attr_first_button_press_cb)
1050 def change_color_dialog(gtkimage):
1051 _window = gtkimage.getWindow()
1052 _dialog = gtk.ColorSelectionDialog(_('Set Active Color'))
1053 _dialog.set_transient_for(_window)
1054 _colorsel = _dialog.colorsel
1055 _image = gtkimage.getImage()
1056 _prev_color = _image.getOption('LINE_COLOR')
1057 _gtk_color = gtkimage.getColor(_prev_color)
1058 _colorsel.set_previous_color(_gtk_color)
1059 _colorsel.set_current_color(_gtk_color)
1060 _colorsel.set_has_palette(True)
1061 _color = None
1062 _response = _dialog.run()
1063 if _response == gtk.RESPONSE_OK:
1064 _gtk_color = _colorsel.get_current_color()
1065 _r = int(round((_gtk_color.red/65535.0) * 255.0))
1066 _g = int(round((_gtk_color.green/65535.0) * 255.0))
1067 _b = int(round((_gtk_color.blue/65535.0) * 255.0))
1068 for _c in _image.getImageEntities('color'):
1069 if _c.r == _r and _c.g == _g and _c.b == _b:
1070 _color = _c
1071 break
1072 if _color is None:
1073 _color = color.Color(_r, _g, _b)
1074 _dialog.destroy()
1075 return _color
1078 # change linetypes
1081 def change_linetype_init(gtkimage, tool=None):
1082 _tool = gtkimage.getImage().getTool()
1083 _tool.setHandler("initialize", change_linetype_init)
1084 _image = gtkimage.getImage()
1085 if _image.hasSelection():
1086 _objs = []
1087 for _obj in _image.getSelectedObjects():
1088 if isinstance(_obj, GraphicObject):
1089 _objs.append(_obj)
1090 _change_attribute(gtkimage, _objs, _tool)
1091 else:
1092 gtkimage.setPrompt(_('Click the items you want the linetype to change.'))
1093 _tool.setHandler("button_press", change_attr_first_button_press_cb)
1095 def change_linetype_dialog(gtkimage):
1096 _window = gtkimage.getWindow()
1097 _dialog = gtk.Dialog(_('Change Linetype'), _window,
1098 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
1099 (gtk.STOCK_OK, gtk.RESPONSE_OK,
1100 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1101 _hbox = gtk.HBox(False, 2)
1102 _hbox.set_border_width(2)
1103 _dialog.vbox.pack_start(_hbox, False, False, 0)
1105 _label = gtk.Label(_('Linetype:'))
1106 _hbox.pack_start(_label, False, False, 0)
1107 _image = gtkimage.getImage()
1108 _clt = _image.getOption('LINE_TYPE')
1109 _linetypes = _image.getImageEntities('linetype')
1110 _idx = 0
1111 if hasattr(gtk, 'ComboBox'): # PyGTK 2.4
1112 _widget = gtk.combo_box_new_text()
1113 for _i in range(len(_linetypes)):
1114 _lt = _linetypes[_i]
1115 if _lt is _clt:
1116 _idx = _i
1117 _widget.append_text(_lt.getName())
1118 _widget.set_active(_idx)
1119 else:
1120 _menu = gtk.Menu()
1121 for _i in range(len(_linetypes)):
1122 _lt = _linetypes[_i]
1123 if _lt is _clt:
1124 _idx = _i
1125 _item = gtk.MenuItem(_lt.getName())
1126 _menu.append(_item)
1127 _widget = gtk.OptionMenu()
1128 _widget.set_menu(_menu)
1129 _widget.set_history(_idx)
1130 _hbox.pack_start(_widget, True, True, 0)
1131 _dialog.show_all()
1132 _lt = None
1133 _response = _dialog.run()
1134 if _response == gtk.RESPONSE_OK:
1135 if isinstance(_widget, gtk.ComboBox):
1136 _idx = _widget.get_active()
1137 elif isinstance(_widget, gtk.OptionMenu):
1138 _idx = _widget.get_history()
1139 else:
1140 raise TypeError, "Unexpected widget: " + `type(_widget)`
1141 _lt = _linetypes[_idx]
1142 _dialog.destroy()
1143 return _lt
1146 # change thickness
1149 def change_thickness_init(gtkimage, tool=None):
1150 _tool = gtkimage.getImage().getTool()
1151 _tool.setHandler("initialize", change_thickness_init)
1152 _image = gtkimage.getImage()
1153 if _image.hasSelection():
1154 _objs = []
1155 for _obj in _image.getSelectedObjects():
1156 if isinstance(_obj, GraphicObject):
1157 _objs.append(_obj)
1158 _change_attribute(gtkimage, _objs, _tool)
1159 else:
1160 gtkimage.setPrompt(_('Click the items you want the thickness to change.'))
1161 _tool.setHandler("button_press", change_attr_first_button_press_cb)
1163 def change_thickness_dialog(gtkimage):
1164 _window = gtkimage.getWindow()
1165 _dialog = gtk.Dialog(_('Change Thickness'), _window,
1166 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
1167 (gtk.STOCK_OK, gtk.RESPONSE_OK,
1168 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1169 _hbox = gtk.HBox(False, 2)
1170 _hbox.set_border_width(2)
1171 _dialog.vbox.pack_start(_hbox, False, False, 0)
1172 _label = gtk.Label(_('Thickness:'))
1173 _hbox.pack_start(_label, False, False, 0)
1174 _thickness = gtkimage.image.getOption('LINE_THICKNESS')
1175 _adj = gtk.Adjustment(_thickness, 0.0001, 20.0, 0.1, 1.0, 1.0)
1176 _sb = gtk.SpinButton(_adj)
1177 _sb.set_digits(1)
1178 _sb.set_numeric(False)
1179 _hbox.pack_start(_sb, True, True, 0)
1180 _dialog.show_all()
1181 _t = None
1182 _response = _dialog.run()
1183 if _response == gtk.RESPONSE_OK:
1184 _t = float(_sb.get_value())
1185 _dialog.destroy()
1186 return _t
1189 # change the style
1192 def change_style_init(gtkimage, tool=None):
1193 _tool = gtkimage.getImage().getTool()
1194 _tool.setHandler("initialize", change_style_init)
1195 _image = gtkimage.getImage()
1196 if _image.hasSelection():
1197 _objs = []
1198 for _obj in _image.getSelectedObjects():
1199 if isinstance(_obj, GraphicObject):
1200 _objs.append(_obj)
1201 _change_attribute(gtkimage, _objs, _tool)
1202 else:
1203 gtkimage.setPrompt(_('Click the items you want the style to change.'))
1204 _tool.setHandler("button_press", change_attr_first_button_press_cb)
1206 def change_style_dialog(gtkimage):
1207 _window = gtkimage.getWindow()
1208 _dialog = gtk.Dialog(_('Change Style'), _window,
1209 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
1210 (gtk.STOCK_OK, gtk.RESPONSE_OK,
1211 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1212 _hbox = gtk.HBox(False, 2)
1213 _hbox.set_border_width(2)
1214 _dialog.vbox.pack_start(_hbox, False, False, 0)
1215 _label = gtk.Label(_('Style:'))
1216 _image = gtkimage.getImage()
1217 _cst = _image.getOption('LINE_STYLE')
1218 _styles = _image.getImageEntities('style')
1219 _idx = 0
1220 if hasattr(gtk, 'ComboBox'): # PyGTK 2.4
1221 _widget = gtk.combo_box_new_text()
1222 for _i in range(len(_styles)):
1223 _s = _styles[_i]
1224 if _s is _cst:
1225 _idx = _i
1226 _widget.append_text(_s.getName())
1227 _widget.set_active(_idx)
1228 else:
1229 _menu = gtk.Menu()
1230 for _i in range(len(_styles)):
1231 _s = _styles[_i]
1232 if _s is _cst:
1233 _idx = _i
1234 _item = gtk.MenuItem(_s.getName())
1235 _menu.append(_item)
1236 _widget = gtk.OptionMenu()
1237 _widget.set_menu(_menu)
1238 _widget.set_history(_idx)
1239 _hbox.pack_start(_label, False, False, 0)
1240 _hbox.pack_start(_widget, True, True, 0)
1241 _dialog.show_all()
1242 _s = None
1243 _response = _dialog.run()
1244 if _response == gtk.RESPONSE_OK:
1245 if isinstance(_widget, gtk.ComboBox):
1246 _idx = _widget.get_active()
1247 elif isinstance(_widget, gtk.OptionMenu):
1248 _idx = _widget.get_history()
1249 else:
1250 raise TypeError, "Unexpected widget: " + `type(_widget)`
1251 _s = _styles[_idx]
1252 _dialog.destroy()
1253 return _s
1256 # Change TextBlock properties
1259 def change_textblock_size_init(gtkimage, tool=None):
1260 _tool = gtkimage.getImage().getTool()
1261 _tool.setHandler("initialize", change_textblock_size_init)
1262 _image = gtkimage.getImage()
1263 if _image.hasSelection():
1264 _objs = []
1265 for _obj in _image.getSelectedObjects():
1266 if isinstance(_obj, TextBlock):
1267 _objs.append(_obj)
1268 _change_attribute(gtkimage, _objs, _tool)
1269 else:
1270 gtkimage.setPrompt(_('Click the items you want the size to change.'))
1271 _tool.setHandler("button_press", change_attr_first_button_press_cb)
1273 def change_textblock_size_dialog(gtkimage, key):
1274 _window = gtkimage.getWindow()
1275 _dialog = gtk.Dialog(_('Change Text Size'), _window,
1276 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
1277 (gtk.STOCK_OK, gtk.RESPONSE_OK,
1278 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1279 _hbox = gtk.HBox(False, 2)
1280 _hbox.set_border_width(2)
1281 _dialog.vbox.pack_start(_hbox, False, False, 0)
1282 _label = gtk.Label(_('Text Size:'))
1283 _hbox.pack_start(_label, False, False, 0)
1284 _size = gtkimage.image.getOption(key)
1285 _adj = gtk.Adjustment(_size, 0.0001, 400.0, 0.1, 1.0, 1.0)
1286 _sb = gtk.SpinButton(_adj)
1287 _sb.set_digits(1)
1288 _sb.set_numeric(False)
1289 _hbox.pack_start(_sb, True, True, 0)
1290 _dialog.show_all()
1291 _size = None
1292 _response = _dialog.run()
1293 if _response == gtk.RESPONSE_OK:
1294 _size = float(_sb.get_value())
1295 _dialog.destroy()
1296 return _size
1298 def change_textblock_family_init(gtkimage, tool=None):
1299 _tool = gtkimage.getImage().getTool()
1300 _tool.setHandler("initialize", change_textblock_family_init)
1301 _image = gtkimage.getImage()
1302 if _image.hasSelection():
1303 _objs = []
1304 for _obj in _image.getSelectedObjects():
1305 if isinstance(_obj, TextBlock):
1306 _objs.append(_obj)
1307 _change_attribute(gtkimage, _objs, _tool)
1308 else:
1309 gtkimage.setPrompt(_('Click the objects you want the family to change.'))
1310 _tool.setHandler("button_press", change_attr_first_button_press_cb)
1312 def change_textblock_family_dialog(gtkimage, key):
1313 _window = gtkimage.getWindow()
1314 _dialog = gtk.Dialog(_('Change Font Family'), _window,
1315 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
1316 (gtk.STOCK_OK, gtk.RESPONSE_OK,
1317 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1318 _hbox = gtk.HBox(False, 2)
1319 _hbox.set_border_width(2)
1320 _dialog.vbox.pack_start(_hbox, False, False, 0)
1321 _families = []
1322 for _family in _window.get_pango_context().list_families():
1323 _families.append(_family.get_name())
1324 _families.sort()
1325 _label = gtk.Label(_('Family:'))
1326 _family = gtkimage.image.getOption(key)
1327 _idx = 0
1328 if hasattr(gtk, 'ComboBox'): # PyGTK 2.4
1329 _widget = gtk.combo_box_new_text()
1330 for _i in range(len(_families)):
1331 _f = _families[_i]
1332 if _f == _family:
1333 _idx = _i
1334 _widget.append_text(_f)
1335 _widget.set_active(_idx)
1336 else:
1337 _menu = gtk.Menu()
1338 for _i in range(len(_families)):
1339 _f = _families[_i]
1340 if _f == _family:
1341 _idx = _i
1342 _item = gtk.MenuItem(_f)
1343 _menu.append(_item)
1344 _widget = gtk.OptionMenu()
1345 _widget.set_menu(_menu)
1346 _widget.set_history(_idx)
1347 _hbox.pack_start(_label, False, False, 0)
1348 _hbox.pack_start(_widget, True, True, 0)
1349 _dialog.show_all()
1350 _family = None
1351 _response = _dialog.run()
1352 if _response == gtk.RESPONSE_OK:
1353 if isinstance(_widget, gtk.ComboBox):
1354 _idx = _widget.get_active()
1355 elif isinstance(_widget, gtk.OptionMenu):
1356 _idx = _widget.get_history()
1357 else:
1358 raise TypeError, "Unexpected widget: " + `type(_widget)`
1359 _family = _families[_idx]
1360 _dialog.destroy()
1361 return _family
1363 def change_textblock_weight_init(gtkimage, tool=None):
1364 _tool = gtkimage.getImage().getTool()
1365 _tool.setHandler("initialize", change_textblock_weight_init)
1366 _image = gtkimage.getImage()
1367 if _image.hasSelection():
1368 _objs = []
1369 for _obj in _image.getSelectedObjects():
1370 if isinstance(_obj, TextBlock):
1371 _objs.append(_obj)
1372 _change_attribute(gtkimage, _objs, _tool)
1373 else:
1374 gtkimage.setPrompt(_('Click the objects you want the weight to change.'))
1375 _tool.setHandler("button_press", change_attr_first_button_press_cb)
1377 def change_textblock_weight_dialog(gtkimage, key):
1378 _window = gtkimage.getWindow()
1379 _dialog = gtk.Dialog(_('Change Text Weight'), _window,
1380 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
1381 (gtk.STOCK_OK, gtk.RESPONSE_OK,
1382 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1383 _hbox = gtk.HBox(False, 2)
1384 _hbox.set_border_width(2)
1385 _dialog.vbox.pack_start(_hbox, False, False, 0)
1386 _label = gtk.Label(_('Text Weight:'))
1387 _weight = gtkimage.image.getOption(key)
1388 _idx = 0
1389 if hasattr(gtk, 'ComboBox'): # PyGTK 2.4
1390 _widget = gtk.combo_box_new_text()
1391 _widget.append_text(_('NORMAL'))
1392 if _weight == TextStyle.WEIGHT_NORMAL:
1393 _idx = 0
1394 _widget.append_text(_('LIGHT'))
1395 if _weight == TextStyle.WEIGHT_LIGHT:
1396 _idx = 1
1397 _widget.append_text(_('BOLD'))
1398 if _weight == TextStyle.WEIGHT_BOLD:
1399 _idx = 2
1400 _widget.append_text(_('HEAVY'))
1401 if _weight == TextStyle.WEIGHT_HEAVY:
1402 _idx = 3
1403 _widget.set_active(_idx)
1404 else:
1405 _menu = gtk.Menu()
1406 _item = gtk.MenuItem(_('NORMAL'))
1407 _menu.append(_item)
1408 if _weight == TextStyle.WEIGHT_NORMAL:
1409 _idx = 0
1410 _item = gtk.MenuItem(_('LIGHT'))
1411 _menu.append(_item)
1412 if _weight == TextStyle.WEIGHT_LIGHT:
1413 _idx = 1
1414 _item = gtk.MenuItem(_('BOLD'))
1415 _menu.append(_item)
1416 if _weight == TextStyle.WEIGHT_BOLD:
1417 _idx = 2
1418 _item = gtk.MenuItem(_('HEAVY'))
1419 _menu.append(_item)
1420 if _weight == TextStyle.WEIGHT_HEAVY:
1421 _idx = 3
1422 _widget = gtk.OptionMenu()
1423 _widget.set_menu(_menu)
1424 _widget.set_history(_idx)
1425 _hbox.pack_start(_label, False, False, 0)
1426 _hbox.pack_start(_widget, True, True, 0)
1427 _dialog.show_all()
1428 _weight = None
1429 _response = _dialog.run()
1430 if _response == gtk.RESPONSE_OK:
1431 if isinstance(_widget, gtk.ComboBox):
1432 _weight = _widget.get_active()
1433 elif isinstance(_widget, gtk.OptionMenu):
1434 _weight = _widget.get_history()
1435 else:
1436 raise TypeError, "Unexpected widget: " + `type(_widget)`
1437 _dialog.destroy()
1438 return _weight
1440 def change_textblock_style_init(gtkimage, tool=None):
1441 _tool = gtkimage.getImage().getTool()
1442 _tool.setHandler("initialize", change_textblock_style_init)
1443 _image = gtkimage.getImage()
1444 if _image.hasSelection():
1445 _objs = []
1446 for _obj in _image.getSelectedObjects():
1447 if isinstance(_obj, TextBlock):
1448 _objs.append(_obj)
1449 _change_attribute(gtkimage, _objs, _tool)
1450 else:
1451 gtkimage.setPrompt(_('Click the objects you want the style to change.'))
1452 _tool.setHandler("button_press", change_attr_first_button_press_cb)
1454 def change_textblock_style_dialog(gtkimage, key):
1455 _window = gtkimage.getWindow()
1456 _dialog = gtk.Dialog(_('Change Text Style'), _window,
1457 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
1458 (gtk.STOCK_OK, gtk.RESPONSE_OK,
1459 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1460 _hbox = gtk.HBox(False, 2)
1461 _hbox.set_border_width(2)
1462 _dialog.vbox.pack_start(_hbox, False, False, 0)
1463 _label = gtk.Label(_('Text Style:'))
1464 _style = gtkimage.image.getOption(key)
1465 _idx = 0
1466 if hasattr(gtk, 'ComboBox'): # PyGTK 2.4
1467 _widget = gtk.combo_box_new_text()
1468 _widget.append_text(_('NORMAL'))
1469 if _style == TextStyle.FONT_NORMAL:
1470 _idx = 0
1471 _widget.append_text(_('OBLIQUE'))
1472 if _style == TextStyle.FONT_OBLIQUE:
1473 _idx = 1
1474 _widget.append_text(_('ITALIC'))
1475 if _style == TextStyle.FONT_ITALIC:
1476 _idx = 2
1477 _widget.set_active(_idx)
1478 else:
1479 _menu = gtk.Menu()
1480 _item = gtk.MenuItem(_('NORMAL'))
1481 _menu.append(_item)
1482 if _style == TextStyle.FONT_NORMAL:
1483 _idx = 0
1484 _item = gtk.MenuItem(_('OBLIQUE'))
1485 _menu.append(_item)
1486 if _style == TextStyle.FONT_OBLIQUE:
1487 _idx = 1
1488 _item = gtk.MenuItem(_('ITALIC'))
1489 _menu.append(_item)
1490 if _style == TextStyle.FONT_ITALIC:
1491 _idx = 2
1492 _widget = gtk.OptionMenu()
1493 _widget.set_menu(_menu)
1494 _widget.set_history(_idx)
1495 _hbox.pack_start(_label, False, False, 0)
1496 _hbox.pack_start(_widget, True, True, 0)
1497 _dialog.show_all()
1498 _style = None
1499 _response = _dialog.run()
1500 if _response == gtk.RESPONSE_OK:
1501 if isinstance(_widget, gtk.ComboBox):
1502 _style = _widget.get_active()
1503 elif isinstance(_widget, gtk.OptionMenu):
1504 _style = _widget.get_history()
1505 else:
1506 raise TypeError, "Unexpected widget: " + `type(_widget)`
1507 _dialog.destroy()
1508 return _style
1510 def change_textblock_alignment_init(gtkimage, tool=None):
1511 _tool = gtkimage.getImage().getTool()
1512 _tool.setHandler("initialize", change_textblock_alignment_init)
1513 _image = gtkimage.getImage()
1514 if _image.hasSelection():
1515 _objs = []
1516 for _obj in _image.getSelectedObjects():
1517 if isinstance(_obj, TextBlock):
1518 _objs.append(_obj)
1519 _change_attribute(gtkimage, _objs, _tool)
1520 else:
1521 gtkimage.setPrompt(_('Click the objects you want the alignment to change.'))
1522 _tool.setHandler("button_press", change_attr_first_button_press_cb)
1524 def change_textblock_alignment_dialog(gtkimage, key):
1525 _window = gtkimage.getWindow()
1526 _dialog = gtk.Dialog(_('Change Text Alignment'), _window,
1527 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
1528 (gtk.STOCK_OK, gtk.RESPONSE_OK,
1529 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1530 _hbox = gtk.HBox(False, 2)
1531 _hbox.set_border_width(2)
1532 _dialog.vbox.pack_start(_hbox, False, False, 0)
1533 _label = gtk.Label(_('Text Alignment:'))
1534 _align = gtkimage.image.getOption(key)
1535 _idx = 0
1536 if hasattr(gtk, 'ComboBox'): # PyGTK 2.4
1537 _widget = gtk.combo_box_new_text()
1538 _widget.append_text(_('LEFT'))
1539 if _align == TextStyle.ALIGN_LEFT:
1540 _idx = 0
1541 _widget.append_text(_('CENTER'))
1542 if _align == TextStyle.ALIGN_CENTER:
1543 _idx = 1
1544 _widget.append_text(_('RIGHT'))
1545 if _align == TextStyle.ALIGN_RIGHT:
1546 _idx = 2
1547 _widget.set_active(_idx)
1548 else:
1549 _menu = gtk.Menu()
1550 _item = gtk.MenuItem(_('LEFT'))
1551 _menu.append(_item)
1552 if _align == TextStyle.ALIGN_LEFT:
1553 _idx = 0
1554 _item = gtk.MenuItem(_('CENTER'))
1555 _menu.append(_item)
1556 if _align == TextStyle.ALIGN_CENTER:
1557 _idx = 1
1558 _item = gtk.MenuItem(_('RIGHT'))
1559 _menu.append(_item)
1560 if _align == TextStyle.ALIGN_RIGHT:
1561 _idx = 2
1562 _widget = gtk.OptionMenu()
1563 _widget.set_menu(_menu)
1564 _widget.set_history(_idx)
1565 _hbox.pack_start(_label, False, False, 0)
1566 _hbox.pack_start(_widget, True, True, 0)
1567 _dialog.show_all()
1568 _align = None
1569 _response = _dialog.run()
1570 if _response == gtk.RESPONSE_OK:
1571 if isinstance(_widget, gtk.ComboBox):
1572 _align = _widget.get_active()
1573 elif isinstance(_widget, gtk.OptionMenu):
1574 _align = _widget.get_history()
1575 else:
1576 raise TypeError, "Unexpected widget: " + `type(_widget)`
1577 _dialog.destroy()
1578 return _align
1580 def change_textblock_color_init(gtkimage, tool=None):
1581 _tool = gtkimage.getImage().getTool()
1582 _tool.setHandler("initialize", change_textblock_color_init)
1583 _image = gtkimage.getImage()
1584 if _image.hasSelection():
1585 _objs = []
1586 for _obj in _image.getSelectedObjects():
1587 if isinstance(_obj, TextBlock):
1588 _objs.append(_obj)
1589 _change_attribute(gtkimage, _objs, _tool)
1590 else:
1591 gtkimage.setPrompt(_('Click the objects you want the color to change.'))
1592 _tool.setHandler("button_press", change_attr_first_button_press_cb)
1594 def change_textblock_color_dialog(gtkimage, key):
1595 _window = gtkimage.getWindow()
1596 _dialog = gtk.ColorSelectionDialog(_('Change Font Color'))
1597 _dialog.set_transient_for(_window)
1598 _colorsel = _dialog.colorsel
1599 _image = gtkimage.getImage()
1600 _color = _image.getOption(key)
1601 _gtk_color = gtkimage.getColor(_color)
1602 _colorsel.set_previous_color(_gtk_color)
1603 _colorsel.set_current_color(_gtk_color)
1604 _colorsel.set_has_palette(True)
1605 _color = None
1606 _response = _dialog.run()
1607 if _response == gtk.RESPONSE_OK:
1608 _gtk_color = _colorsel.get_current_color()
1609 _r = int(round((_gtk_color.red/65535.0) * 255.0))
1610 _g = int(round((_gtk_color.green/65535.0) * 255.0))
1611 _b = int(round((_gtk_color.blue/65535.0) * 255.0))
1612 for _c in _image.getImageEntities('color'):
1613 if _c.r == _r and _c.g == _g and _c.b == _b:
1614 _color = _c
1615 break
1616 if _color is None:
1617 _color = color.Color(_r, _g, _b)
1618 _dialog.destroy()
1619 return _color
1622 # Change Dimension Properties
1625 def change_dim_offset_init(gtkimage, tool=None):
1626 _tool = gtkimage.getImage().getTool()
1627 _tool.setHandler("initialize", change_dim_offset_init)
1628 _image = gtkimage.getImage()
1629 if _image.hasSelection():
1630 _objs = []
1631 for _obj in _image.getSelectedObjects():
1632 if isinstance(_obj, Dimension):
1633 _objs.append(_obj)
1634 _change_attribute(gtkimage, _objs, _tool)
1635 else:
1636 gtkimage.setPrompt(_('Click the dimension you want the offset to change.'))
1637 _tool.setHandler("button_press", change_attr_first_button_press_cb)
1639 def change_dim_offset_dialog(gtkimage):
1640 _window = gtkimage.getWindow()
1641 _dialog = gtk.Dialog(_('Change Offset Length'), _window,
1642 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
1643 (gtk.STOCK_OK, gtk.RESPONSE_OK,
1644 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1645 _hbox = gtk.HBox(False, 2)
1646 _hbox.set_border_width(2)
1647 _dialog.vbox.pack_start(_hbox, False, False, 0)
1648 _label = gtk.Label(_('Length:'))
1649 _hbox.pack_start(_label, False, False, 0)
1650 _offset = gtkimage.image.getOption('DIM_OFFSET')
1651 _adj = gtk.Adjustment(_offset, 0.01, 200.0, 0.1, 1.0, 1.0)
1652 _sb = gtk.SpinButton(_adj)
1653 _sb.set_digits(2)
1654 _sb.set_numeric(False)
1655 _hbox.pack_start(_sb, True, True, 0)
1656 _dialog.show_all()
1657 _offset = None
1658 _response = _dialog.run()
1659 if _response == gtk.RESPONSE_OK:
1660 _offset = float(_sb.get_value())
1661 _dialog.destroy()
1662 return _offset
1664 def change_dim_extension_init(gtkimage, tool=None):
1665 _tool = gtkimage.getImage().getTool()
1666 _tool.setHandler("initialize", change_dim_extension_init)
1667 _image = gtkimage.getImage()
1668 if _image.hasSelection():
1669 _objs = []
1670 for _obj in _image.getSelectedObjects():
1671 if isinstance(_obj, Dimension):
1672 _objs.append(_obj)
1673 _change_attribute(gtkimage, _objs, _tool)
1674 else:
1675 gtkimage.setPrompt(_('Click the dimension you want the extension to change.'))
1676 _tool.setHandler("button_press", change_attr_first_button_press_cb)
1678 def change_dim_extension_dialog(gtkimage):
1679 _window = gtkimage.getWindow()
1680 _dialog = gtk.Dialog(_('Change Extension Length'), _window,
1681 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
1682 (gtk.STOCK_OK, gtk.RESPONSE_OK,
1683 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1684 _hbox = gtk.HBox(False, 2)
1685 _hbox.set_border_width(2)
1686 _dialog.vbox.pack_start(_hbox, False, False, 0)
1687 _label = gtk.Label(_('Length:'))
1688 _hbox.pack_start(_label, False, False, 0)
1689 _extlen = gtkimage.image.getOption('DIM_EXTENSION')
1690 _adj = gtk.Adjustment(_extlen, 0.01, 200.0, 0.1, 1.0, 1.0)
1691 _sb = gtk.SpinButton(_adj)
1692 _sb.set_digits(2)
1693 _sb.set_numeric(False)
1694 _hbox.pack_start(_sb, True, True, 0)
1695 _dialog.show_all()
1696 _extlen = None
1697 _response = _dialog.run()
1698 if _response == gtk.RESPONSE_OK:
1699 _extlen = float(_sb.get_value())
1700 _dialog.destroy()
1701 return _extlen
1703 def change_dim_endpoint_init(gtkimage, tool=None):
1704 _tool = gtkimage.getImage().getTool()
1705 _tool.setHandler("initialize", change_dim_endpoint_init)
1706 _image = gtkimage.getImage()
1707 if _image.hasSelection():
1708 _objs = []
1709 for _obj in _image.getSelectedObjects():
1710 if isinstance(_obj, Dimension):
1711 _objs.append(_obj)
1712 _change_attribute(gtkimage, _objs, _tool)
1713 else:
1714 gtkimage.setPrompt(_('Click the dimension you want the endpoint type to change.'))
1715 _tool.setHandler("button_press", change_attr_first_button_press_cb)
1717 def change_dim_endpoint_dialog(gtkimage):
1718 _window = gtkimage.getWindow()
1719 _dialog = gtk.Dialog(_('Change Endpoint Markers'), _window,
1720 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
1721 (gtk.STOCK_OK, gtk.RESPONSE_OK,
1722 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1723 _hbox = gtk.HBox(False, 2)
1724 _hbox.set_border_width(2)
1725 _dialog.vbox.pack_start(_hbox, False, False, 0)
1726 _label = gtk.Label(_('Endpoints:'))
1727 _endpt = gtkimage.image.getOption('DIM_ENDPOINT')
1728 _idx = 0
1729 if hasattr(gtk, 'ComboBox'): # PyGTK 2.4
1730 _widget = gtk.combo_box_new_text()
1731 _widget.append_text(_('None'))
1732 if _endpt == Dimension.DIM_ENDPT_NONE:
1733 _idx = 0
1734 _widget.append_text(_('Arrow'))
1735 if _endpt == Dimension.DIM_ENDPT_ARROW:
1736 _idx = 1
1737 _widget.append_text(_('Filled Arrow'))
1738 if _endpt == Dimension.DIM_ENDPT_FILLED_ARROW:
1739 _idx = 2
1740 _widget.append_text(_('Slash'))
1741 if _endpt == Dimension.DIM_ENDPT_SLASH:
1742 _idx = 3
1743 _widget.append_text(_('Circle'))
1744 if _endpt == Dimension.DIM_ENDPT_CIRCLE:
1745 _idx = 4
1746 _widget.set_active(_idx)
1747 else:
1748 _menu = gtk.Menu()
1749 _item = gtk.MenuItem(_('None'))
1750 _menu.append(_item)
1751 if _endpt == Dimension.DIM_ENDPT_NONE:
1752 _idx = 0
1753 _item = gtk.MenuItem(_('Arrow'))
1754 _menu.append(_item)
1755 if _endpt == Dimension.DIM_ENDPT_ARROW:
1756 _idx = 1
1757 _item = gtk.MenuItem(_('Filled Arrow'))
1758 _menu.append(_item)
1759 if _endpt == Dimension.DIM_ENDPT_FILLED_ARROW:
1760 _idx = 2
1761 _item = gtk.MenuItem(_('Slash'))
1762 _menu.append(_item)
1763 if _endpt == Dimension.DIM_ENDPT_SLASH:
1764 _idx = 3
1765 _item = gtk.MenuItem(_('Circle'))
1766 _menu.append(_item)
1767 if _endpt == Dimension.DIM_ENDPT_CIRCLE:
1768 _idx = 4
1769 _widget = gtk.OptionMenu()
1770 _widget.set_menu(_menu)
1771 _widget.set_history(_idx)
1772 _hbox.pack_start(_label, False, False, 0)
1773 _hbox.pack_start(_widget, True, True, 0)
1774 _dialog.show_all()
1775 _endpt = None
1776 _response = _dialog.run()
1777 if _response == gtk.RESPONSE_OK:
1778 if isinstance(_widget, gtk.ComboBox):
1779 _endpt = _widget.get_active()
1780 elif isinstance(_widget, gtk.OptionMenu):
1781 _endpt = _widget.get_history()
1782 else:
1783 raise TypeError, "Unexpected widget: " + `type(_widget)`
1784 _dialog.destroy()
1785 return _endpt
1787 def change_dim_endpoint_size_init(gtkimage, tool=None):
1788 _tool = gtkimage.getImage().getTool()
1789 _tool.setHandler("initialize", change_dim_endpoint_size_init)
1790 _image = gtkimage.getImage()
1791 if _image.hasSelection():
1792 _objs = []
1793 for _obj in _image.getSelectedObjects():
1794 if isinstance(_obj, Dimension):
1795 _objs.append(_obj)
1796 _change_attribute(gtkimage, _objs, _tool)
1797 else:
1798 gtkimage.setPrompt(_('Click the dimension you want the endpoint size to change.'))
1799 tool.setHandler("button_press", change_attr_first_button_press_cb)
1801 def change_dim_endpoint_size_dialog(gtkimage):
1802 _window = gtkimage.getWindow()
1803 _dialog = gtk.Dialog(_('Change Endpoint Size'), _window,
1804 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
1805 (gtk.STOCK_OK, gtk.RESPONSE_OK,
1806 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1807 _hbox = gtk.HBox(False, 2)
1808 _hbox.set_border_width(2)
1809 _dialog.vbox.pack_start(_hbox, False, False, 0)
1810 _label = gtk.Label(_('Length:'))
1811 _hbox.pack_start(_label, False, False, 0)
1812 _size = gtkimage.image.getOption('DIM_ENDPOINT_SIZE')
1813 _adj = gtk.Adjustment(_size, 0.01, 200.0, 0.1, 1.0, 1.0)
1814 _sb = gtk.SpinButton(_adj)
1815 _sb.set_digits(2)
1816 _sb.set_numeric(False)
1817 _hbox.pack_start(_sb, True, True, 0)
1818 _dialog.show_all()
1819 _size = None
1820 _response = _dialog.run()
1821 if _response == gtk.RESPONSE_OK:
1822 _size = float(_sb.get_value())
1823 _dialog.destroy()
1824 return _size
1826 def change_dim_dual_mode_init(gtkimage, tool=None):
1827 _tool = gtkimage.getImage().getTool()
1828 _tool.setHandler("initialize", change_dim_dual_mode_init)
1829 _image = gtkimage.getImage()
1830 if _image.hasSelection():
1831 _objs = []
1832 for _obj in _image.getSelectedObjects():
1833 if isinstance(_obj, Dimension):
1834 _objs.append(_obj)
1835 _change_attribute(gtkimage, _objs, _tool)
1836 else:
1837 gtkimage.setPrompt(_('Click the dimension you want to change the dual dimension display.'))
1838 _tool.setHandler("button_press", change_attr_first_button_press_cb)
1840 def change_dim_dual_mode_dialog(gtkimage):
1841 _window = gtkimage.getWindow()
1842 _dialog = gtk.Dialog(_('Change Dual Mode'), _window,
1843 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
1844 (gtk.STOCK_OK, gtk.RESPONSE_OK,
1845 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1846 _hbox = gtk.HBox(False, 2)
1847 _hbox.set_border_width(2)
1848 _dialog.vbox.pack_start(_hbox, False, False, 0)
1849 _cb = gtk.CheckButton(_('Display Two Dimension Values'))
1850 _mode = gtkimage.image.getOption('DIM_DUAL_MODE')
1851 _cb.set_active(_mode)
1852 _hbox.pack_start(_cb, True, True, 0)
1853 _dialog.show_all()
1854 _mode = None
1855 _response = _dialog.run()
1856 if _response == gtk.RESPONSE_OK:
1857 _mode = _cb.get_active()
1858 _dialog.destroy()
1859 return _mode
1861 def change_dim_dual_mode_offset_init(gtkimage, tool=None):
1862 _tool = gtkimage.getImage().getTool()
1863 _tool.setHandler("initialize", change_dim_dual_mode_offset_init)
1864 _image = gtkimage.getImage()
1865 if _image.hasSelection():
1866 _objs = []
1867 for _obj in _image.getSelectedObjects():
1868 if isinstance(_obj, Dimension):
1869 _objs.append(_obj)
1870 _change_attribute(gtkimage, _objs, _tool)
1871 else:
1872 gtkimage.setPrompt(_('Click the dimension you want to change the dual dimension offset value.'))
1873 _tool.setHandler("button_press", change_attr_first_button_press_cb)
1875 def change_dim_dual_mode_offset_dialog(gtkimage):
1876 _window = gtkimage.getWindow()
1877 _dialog = gtk.Dialog(_('Change Dual Mode Offset'), _window,
1878 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
1879 (gtk.STOCK_OK, gtk.RESPONSE_OK,
1880 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1881 _hbox = gtk.HBox(False, 2)
1882 _hbox.set_border_width(2)
1883 _dialog.vbox.pack_start(_hbox, False, False, 0)
1884 _label = gtk.Label(_('Length:'))
1885 _hbox.pack_start(_label, False, False, 0)
1886 _offset = gtkimage.image.getOption('DIM_DUAL_MODE_OFFSET')
1887 _adj = gtk.Adjustment(_offset, 0.01, 200.0, 0.1, 1.0, 1.0)
1888 _sb = gtk.SpinButton(_adj)
1889 _sb.set_digits(2)
1890 _sb.set_numeric(False)
1891 _hbox.pack_start(_sb, True, True, 0)
1892 _dialog.show_all()
1893 _offset = None
1894 _response = _dialog.run()
1895 if _response == gtk.RESPONSE_OK:
1896 _offset = float(_sb.get_value())
1897 _dialog.destroy()
1898 return _offset
1900 def change_dim_thickness_init(gtkimage, tool=None):
1901 _tool = gtkimage.getImage().getTool()
1902 _tool.setHandler("initialize", change_dim_thickness_init)
1903 _image = gtkimage.getImage()
1904 if _image.hasSelection():
1905 _objs = []
1906 for _obj in _image.getSelectedObjects():
1907 if isinstance(_obj, Dimension):
1908 _objs.append(_obj)
1909 _change_attribute(gtkimage, _objs, _tool)
1910 else:
1911 gtkimage.setPrompt(_('Click the dimension you want to change the thickess.'))
1912 _tool.setHandler("button_press", change_attr_first_button_press_cb)
1914 def change_dim_thickness_dialog(gtkimage):
1915 _window = gtkimage.getWindow()
1916 _dialog = gtk.Dialog(_('Change Dim Thickness'), _window,
1917 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
1918 (gtk.STOCK_OK, gtk.RESPONSE_OK,
1919 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1920 _hbox = gtk.HBox(False, 2)
1921 _hbox.set_border_width(2)
1922 _dialog.vbox.pack_start(_hbox, False, False, 0)
1923 _label = gtk.Label(_('Thickness:'))
1924 _hbox.pack_start(_label, False, False, 0)
1925 _t = gtkimage.image.getOption('DIM_THICKNESS')
1926 _adj = gtk.Adjustment(_t, 0.01, 200.0, 0.1, 1.0, 1.0)
1927 _sb = gtk.SpinButton(_adj)
1928 _sb.set_digits(2)
1929 _sb.set_numeric(False)
1930 _hbox.pack_start(_sb, True, True, 0)
1931 _dialog.show_all()
1932 _t = None
1933 _response = _dialog.run()
1934 if _response == gtk.RESPONSE_OK:
1935 _t = float(_sb.get_value())
1936 _dialog.destroy()
1937 return _t
1939 def change_dim_color_init(gtkimage, tool=None):
1940 _tool = gtkimage.getImage().getTool()
1941 _tool.setHandler("initialize", change_dim_color_init)
1942 _image = gtkimage.getImage()
1943 if _image.hasSelection():
1944 _objs = []
1945 for _obj in _image.getSelectedObjects():
1946 if isinstance(_obj, Dimension):
1947 _objs.append(_obj)
1948 _change_attribute(gtkimage, _objs, _tool)
1949 else:
1950 gtkimage.setPrompt(_('Click the dimension you want to change the color.'))
1951 _tool.setHandler("button_press", change_attr_first_button_press_cb)
1953 def change_dim_color_dialog(gtkimage):
1954 _window = gtkimage.getWindow()
1955 _dialog = gtk.ColorSelectionDialog(_('Change Dimension Color'))
1956 _dialog.set_transient_for(_window)
1957 _colorsel = _dialog.colorsel
1958 _image = gtkimage.getImage()
1959 _color = _image.getOption('DIM_COLOR')
1960 _gtk_color = gtkimage.getColor(_color)
1961 _colorsel.set_previous_color(_gtk_color)
1962 _colorsel.set_current_color(_gtk_color)
1963 _colorsel.set_has_palette(True)
1964 _color = None
1965 _response = _dialog.run()
1966 if _response == gtk.RESPONSE_OK:
1967 _gtk_color = _colorsel.get_current_color()
1968 _r = int(round((_gtk_color.red/65535.0) * 255.0))
1969 _g = int(round((_gtk_color.green/65535.0) * 255.0))
1970 _b = int(round((_gtk_color.blue/65535.0) * 255.0))
1971 for _c in _image.getImageEntities('color'):
1972 if _c.r == _r and _c.g == _g and _c.b == _b:
1973 _color = _c
1974 break
1975 if _color is None:
1976 _color = color.Color(_r, _g, _b)
1977 _dialog.destroy()
1978 return _color
1981 # Change DimString properties
1984 def _dimstring_filter_proc(tool, obj):
1985 _ds = None
1986 if isinstance(obj, Dimension):
1987 if tool.getPrimary():
1988 _ds = obj.getPrimaryDimstring()
1989 else:
1990 _ds = obj.getSecondaryDimstring()
1991 return _ds
1993 def _ldimstring_filter_proc(tool, obj):
1994 _ds = None
1995 if isinstance(obj, (LinearDimension,
1996 HorizontalDimension,
1997 VerticalDimension)):
1998 if tool.getPrimary():
1999 _ds = obj.getPrimaryDimstring()
2000 else:
2001 _ds = obj.getSecondaryDimstring()
2002 return _ds
2004 def _rdimstring_filter_proc(tool, obj):
2005 _ds = None
2006 if isinstance(obj, RadialDimension):
2007 if tool.getPrimary():
2008 _ds = obj.getPrimaryDimstring()
2009 else:
2010 _ds = obj.getSecondaryDimstring()
2011 return _ds
2013 def _adimstring_filter_proc(tool, obj):
2014 _ds = None
2015 if isinstance(obj, AngularDimension):
2016 if tool.getPrimary():
2017 _ds = obj.getPrimaryDimstring()
2018 else:
2019 _ds = obj.getSecondaryDimstring()
2020 return _ds
2022 def change_dimstr_prefix_dialog(gtkimage, key):
2023 _window = gtkimage.getWindow()
2024 _dialog = gtk.Dialog(_('Change Prefix'), _window,
2025 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
2026 (gtk.STOCK_OK, gtk.RESPONSE_OK,
2027 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
2028 _hbox = gtk.HBox(False, 2)
2029 _hbox.set_border_width(2)
2030 _dialog.vbox.pack_start(_hbox, False, False, 0)
2031 _label = gtk.Label(_('Prefix:'))
2032 _hbox.pack_start(_label, True, True, 0)
2033 _prefix = gtkimage.image.getOption(key)
2034 _entry = gtk.Entry()
2035 _entry.set_text(_prefix)
2036 _hbox.pack_start(_entry, True, True, 0)
2037 _dialog.show_all()
2038 _prefix = None
2039 _response = _dialog.run()
2040 if _response == gtk.RESPONSE_OK:
2041 _prefix = _entry.get_text()
2042 _dialog.destroy()
2043 return _prefix
2045 def change_dimstr_suffix_dialog(gtkimage, key):
2046 _window = gtkimage.getWindow()
2047 _dialog = gtk.Dialog(_('Change Suffix'), _window,
2048 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
2049 (gtk.STOCK_OK, gtk.RESPONSE_OK,
2050 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
2051 _hbox = gtk.HBox(False, 2)
2052 _hbox.set_border_width(2)
2053 _dialog.vbox.pack_start(_hbox, False, False, 0)
2054 _label = gtk.Label(_('Suffix:'))
2055 _hbox.pack_start(_label, True, True, 0)
2056 _suffix = gtkimage.image.getOption(key)
2057 _entry = gtk.Entry()
2058 _entry.set_text(_suffix)
2059 _hbox.pack_start(_entry, True, True, 0)
2060 _dialog.show_all()
2061 _suffix = None
2062 _response = _dialog.run()
2063 if _response == gtk.RESPONSE_OK:
2064 _suffix = _entry.get_text()
2065 _dialog.destroy()
2066 return _suffix
2068 def change_dimstr_precision_dialog(gtkimage, key):
2069 _window = gtkimage.getWindow()
2070 _dialog = gtk.Dialog(_('Change Precision'), _window,
2071 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
2072 (gtk.STOCK_OK, gtk.RESPONSE_OK,
2073 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
2074 _hbox = gtk.HBox(False, 2)
2075 _hbox.set_border_width(2)
2076 _dialog.vbox.pack_start(_hbox, False, False, 0)
2077 _label = gtk.Label(_('Precision:'))
2078 _hbox.pack_start(_label, False, False, 0)
2079 _prec = gtkimage.image.getOption(key)
2080 _adj = gtk.Adjustment(_prec, 0, 15, 1, 1, 1)
2081 _sb = gtk.SpinButton(_adj)
2082 _sb.set_digits(0)
2083 _sb.set_numeric(True)
2084 _hbox.pack_start(_sb, True, True, 0)
2085 _dialog.show_all()
2086 _prec = None
2087 _response = _dialog.run()
2088 if _response == gtk.RESPONSE_OK:
2089 _prec = int(_sb.get_value())
2090 _dialog.destroy()
2091 return _prec
2093 def change_dimstr_units_dialog(gtkimage, key):
2094 _window = gtkimage.getWindow()
2095 _dialog = gtk.Dialog(_('Change Units'), _window,
2096 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
2097 (gtk.STOCK_OK, gtk.RESPONSE_OK,
2098 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
2099 _hbox = gtk.HBox(False, 2)
2100 _hbox.set_border_width(2)
2101 _dialog.vbox.pack_start(_hbox, False, False, 0)
2102 _label = gtk.Label(_('Units'))
2103 _hbox.pack_start(_label, False, False, 0)
2104 _units = [(_('Millimeters'), PythonCAD.Generic.units.MILLIMETERS),
2105 (_('Micrometers'), PythonCAD.Generic.units.MICROMETERS),
2106 (_('Meters'), PythonCAD.Generic.units.METERS),
2107 (_('Kilometers'), PythonCAD.Generic.units.KILOMETERS),
2108 (_('Inches'), PythonCAD.Generic.units.INCHES),
2109 (_('Feet'), PythonCAD.Generic.units.FEET),
2110 (_('Yards'), PythonCAD.Generic.units.YARDS),
2111 (_('Miles'), PythonCAD.Generic.units.MILES),
2113 _unit = gtkimage.image.getOption(key)
2114 _idx = 0
2115 if hasattr(gtk, 'ComboBox'): # PyGTK 2.4
2116 _unit_widget = gtk.combo_box_new_text()
2117 for _i in range(len(_units)):
2118 _str, _val = _units[_i]
2119 if _unit == _val:
2120 _idx = _i
2121 _unit_widget.append_text(_str)
2122 _unit_widget.set_active(_idx)
2123 else:
2124 _menu = gtk.Menu()
2125 for _i in range(len(_units)):
2126 _str, _val = _units[_i]
2127 if _unit == _val:
2128 _idx = _i
2129 _item = gtk.MenuItem(_str)
2130 _menu.append(_item)
2131 _unit_widget = gtk.OptionMenu()
2132 _unit_widget.set_menu(_menu)
2133 _unit_widget.set_history(_idx)
2134 _hbox.pack_start(_unit_widget, True, True, 0);
2135 _dialog.show_all()
2136 _unit = None
2137 _response = _dialog.run()
2138 if _response == gtk.RESPONSE_OK:
2139 if hasattr(gtk, 'ComboBox'): # PyGTK 2.4
2140 _idx = _unit_widget.get_active()
2141 else:
2142 _idx = _unit_widget.get_history()
2143 _unit = _units[_idx][1]
2144 _dialog.destroy()
2145 return _unit
2147 def change_dimstr_print_decimal_dialog(gtkimage, key):
2148 _window = gtkimage.getWindow()
2149 _dialog = gtk.Dialog(_('Change Print Decimal'), _window,
2150 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
2151 (gtk.STOCK_OK, gtk.RESPONSE_OK,
2152 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
2153 _hbox = gtk.HBox(False, 2)
2154 _hbox.set_border_width(2)
2155 _dialog.vbox.pack_start(_hbox, False, False, 0)
2156 _cb = gtk.CheckButton(_('Print Trailing Decimal'))
2157 _mode = gtkimage.image.getOption(key)
2158 _cb.set_active(_mode)
2159 _hbox.pack_start(_cb, True, True, 0)
2160 _dialog.show_all()
2161 _mode = None
2162 _response = _dialog.run()
2163 if _response == gtk.RESPONSE_OK:
2164 _mode = _cb.get_active()
2165 _dialog.destroy()
2166 return _mode
2168 def change_dimstr_print_zero_dialog(gtkimage, key):
2169 _window = gtkimage.getWindow()
2170 _dialog = gtk.Dialog(_('Change Print Zero'), _window,
2171 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
2172 (gtk.STOCK_OK, gtk.RESPONSE_OK,
2173 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
2174 _hbox = gtk.HBox(False, 2)
2175 _hbox.set_border_width(2)
2176 _dialog.vbox.pack_start(_hbox, False, False, 0)
2177 _cb = gtk.CheckButton(_('Print Leading Zero'))
2178 _mode = gtkimage.image.getOption(key)
2179 _cb.set_active(_mode)
2180 _hbox.pack_start(_cb, True, True, 0)
2181 _dialog.show_all()
2182 _mode = None
2183 _response = _dialog.run()
2184 if _response == gtk.RESPONSE_OK:
2185 _mode = _cb.get_active()
2186 _dialog.destroy()
2187 return _mode
2189 def _change_dimstring_init(gtkimage, tool=None):
2190 _image = gtkimage.getImage()
2191 _tool = _image.getTool()
2192 if _image.hasSelection():
2193 _primary = tool.getPrimary()
2194 _objs = []
2195 for _obj in _image.getSelectedObjects():
2196 if isinstance(_obj, Dimension):
2197 if _primary:
2198 _objs.append(_obj.getPrimaryDimstring())
2199 else:
2200 _objs.append(_obj.getSecondaryDimstring())
2201 _change_attribute(gtkimage, _objs, _tool)
2202 else:
2203 _tool.setHandler("button_press", change_attr_first_button_press_cb)
2205 def change_dimstr_family_init(gtkimage, tool=None):
2206 gtkimage.setPrompt(_('Click the dimension you want to change the DimString family.'))
2207 _tool = gtkimage.getImage().getTool()
2208 _tool.setHandler("initialize", change_dimstr_family_init)
2209 _tool.setFilter(_dimstring_filter_proc)
2210 _change_dimstring_init(gtkimage)
2212 def change_dimstr_style_init(gtkimage, tool=None):
2213 gtkimage.setPrompt(_('Click the dimension you want to change the DimString style.'))
2214 _tool = gtkimage.getImage().getTool()
2215 _tool.setHandler("initialize", change_dimstr_style_init)
2216 _tool.setFilter(_dimstring_filter_proc)
2217 _change_dimstring_init(gtkimage)
2219 def change_dimstr_weight_init(gtkimage, tool=None):
2220 gtkimage.setPrompt(_('Click the dimension you want to change the DimString weight.'))
2221 _tool = gtkimage.getImage().getTool()
2222 _tool.setHandler("initialize", change_dimstr_weight_init)
2223 _tool.setFilter(_dimstring_filter_proc)
2224 _change_dimstring_init(gtkimage)
2226 def change_dimstr_alignment_init(gtkimage, tool=None):
2227 gtkimage.setPrompt(_('Click the dimension you want to change the DimString alignment.'))
2228 _tool = gtkimage.getImage().getTool()
2229 _tool.setHandler("initialize", change_dimstr_alignment_init)
2230 _tool.setFilter(_dimstring_filter_proc)
2231 _change_dimstring_init(gtkimage)
2233 def change_dimstr_size_init(gtkimage, tool=None):
2234 gtkimage.setPrompt(_('Click the dimension you want to change the DimString size.'))
2235 _tool = gtkimage.getImage().getTool()
2236 _tool.setHandler("initialize", change_dimstr_size_init)
2237 _tool.setFilter(_dimstring_filter_proc)
2238 _change_dimstring_init(gtkimage)
2240 def change_dimstr_color_init(gtkimage, tool=None):
2241 gtkimage.setPrompt(_('Click the dimension you want to change the DimString color.'))
2242 _tool = gtkimage.getImage().getTool()
2243 _tool.setHandler("initialize", change_dimstr_color_init)
2244 _tool.setFilter(_dimstring_filter_proc)
2245 _change_dimstring_init(gtkimage)
2247 def change_ldimstr_prefix_init(gtkimage, tool=None):
2248 gtkimage.setPrompt(_('Click the dimension you want to change the DimString prefix.'))
2249 _tool = gtkimage.getImage().getTool()
2250 _tool.setHandler("initialize", change_ldimstr_prefix_init)
2251 _tool.setFilter(_ldimstring_filter_proc)
2252 _change_dimstring_init(gtkimage)
2254 def change_ldimstr_suffix_init(gtkimage, tool=None):
2255 gtkimage.setPrompt(_('Click the dimension you want to change the DimString suffix.'))
2256 _tool = gtkimage.getImage().getTool()
2257 _tool.setHandler("initialize", change_ldimstr_suffix_init)
2258 _tool.setFilter(_ldimstring_filter_proc)
2259 _change_dimstring_init(gtkimage)
2261 def change_rdimstr_prefix_init(gtkimage, tool=None):
2262 gtkimage.setPrompt(_('Click the RadialDimension you want to change the DimString prefix.'))
2263 _tool = gtkimage.getImage().getTool()
2264 _tool.setHandler("initialize", change_rdimstr_prefix_init)
2265 _tool.setFilter(_rdimstring_filter_proc)
2266 _change_dimstring_init(gtkimage)
2268 def change_rdimstr_suffix_init(gtkimage, tool=None):
2269 gtkimage.setPrompt(_('Click the RadialDimension you want to change the DimString suffix.'))
2270 _tool = gtkimage.getImage().getTool()
2271 _tool.setHandler("initialize", change_rdimstr_suffix_init)
2272 _tool.setFilter(_rdimstring_filter_proc)
2273 _change_dimstring_init(gtkimage)
2275 def change_adimstr_prefix_init(gtkimage, tool=None):
2276 gtkimage.setPrompt(_('Click the AngularDimension you want to change the DimString prefix.'))
2277 _tool = gtkimage.getImage().getTool()
2278 _tool.setHandler("initialize", change_adimstr_prefix_init)
2279 _tool.setFilter(_adimstring_filter_proc)
2280 _change_dimstring_init(gtkimage)
2282 def change_adimstr_suffix_init(gtkimage, tool=None):
2283 gtkimage.setPrompt(_('Click the AngularDimension you want to change the DimString suffix.'))
2284 _tool = gtkimage.getImage().getTool()
2285 _tool.setHandler("initialize", change_adimstr_suffix_init)
2286 _tool.setFilter(_adimstring_filter_proc)
2287 _change_dimstring_init(gtkimage)
2289 def change_dimstr_precision_init(gtkimage, tool=None):
2290 gtkimage.setPrompt(_('Click the dimension you want to change the DimString precision.'))
2291 _tool = gtkimage.getImage().getTool()
2292 _tool.setHandler("initialize", change_dimstr_precision_init)
2293 _tool.setFilter(_dimstring_filter_proc)
2294 _change_dimstring_init(gtkimage)
2296 def change_dimstr_units_init(gtkimage, tool=None):
2297 gtkimage.setPrompt(_('Click the dimension you want to change the DimString units.'))
2298 _tool = gtkimage.getImage().getTool()
2299 _tool.setHandler("initialize", change_dimstr_units_init)
2300 _tool.setFilter(_dimstring_filter_proc)
2301 _change_dimstring_init(gtkimage)
2303 def change_dimstr_print_zero_init(gtkimage, tool=None):
2304 gtkimage.setPrompt(_('Click the dimension you want to change the DimString print leading zero flag.'))
2305 _tool = gtkimage.getImage().getTool()
2306 _tool.setHandler("initialize", change_dimstr_print_zero_init)
2307 _tool.setFilter(_dimstring_filter_proc)
2308 _change_dimstring_init(gtkimage)
2310 def change_dimstr_print_decimal_init(gtkimage, tool=None):
2311 gtkimage.setPrompt(_('Click the dimension you want to change the DimString print trailing decimal flag.'))
2312 _tool = gtkimage.getImage().getTool()
2313 _tool.setHandler("initialize", change_dimstr_print_decimal_init)
2314 _tool.setFilter(_dimstring_filter_proc)
2315 _change_dimstring_init(gtkimage)
2317 def _change_rdim_dia_mode(gtkimage, objlist, tool):
2318 _init = tool.getHandler('initialize')
2319 if len(objlist):
2320 _image = gtkimage.getImage()
2321 _image.startAction()
2322 try:
2323 for _obj in objlist:
2324 _mode = not _obj.getDiaMode()
2325 _obj.setDiaMode(_mode)
2326 finally:
2327 _image.endAction()
2328 tool.reset()
2329 _init(gtkimage)
2331 def _rdim_dia_mode_second_button_press_cb(gtkimage, widget, event, tool):
2332 _tol = gtkimage.getTolerance()
2333 _image = gtkimage.getImage()
2334 _x, _y = _image.getCurrentPoint()
2335 _active_layer = _image.getActiveLayer()
2336 _pts = _active_layer.find('point', _x, _y)
2337 if len(_pts) > 0:
2338 _x, _y = _pts[0].getCoords()
2339 _x1, _y1 = tool.getLocation()
2340 _xmin = min(_x1, _x)
2341 _ymin = min(_y1, _y)
2342 _xmax = max(_x1, _x)
2343 _ymax = max(_y1, _y)
2344 _objs = []
2345 for _obj in _active_layer.objsInRegion(_xmin, _ymin, _xmax, _ymax):
2346 if isinstance(_obj, RadialDimension):
2347 _objs.append(_obj)
2348 _change_rdim_dia_mode(gtkimage, _objs, tool)
2349 return True
2351 def _rdim_dia_mode_first_button_press_cb(gtkimage, widget, event, tool):
2352 _tol = gtkimage.getTolerance()
2353 _image = gtkimage.getImage()
2354 _x, _y = _image.getCurrentPoint()
2355 _objdict = _image.mapPoint(_x, _y, _tol, None)
2356 if len(_objdict):
2357 _active_layer = _image.getActiveLayer()
2358 if _active_layer in _objdict:
2359 _objs = []
2360 for _obj, _pt in _objdict[_active_layer]:
2361 if isinstance(_obj, RadialDimension):
2362 _objs.append(_obj)
2363 _change_rdim_dia_mode(gtkimage, _objs, tool)
2364 else:
2365 _pt, _pc = _image.getClosestPoint(_x, _y, tolerance=_tol)
2366 if _pt is not None:
2367 _x, _y = _pt.getCoords()
2368 else:
2369 _x, _y = _pc
2370 tool.setLocation(_x, _y)
2371 tool.setHandler("motion_notify", select_motion_notify)
2372 tool.setHandler("button_press", _rdim_dia_mode_second_button_press_cb)
2373 gtkimage.setPrompt(_('Click the second point for defining the region'))
2374 gtkimage.getGC().set_function(gtk.gdk.INVERT)
2375 return True
2377 def change_rdim_dia_mode_init(gtkimage, tool=None):
2378 _tool = gtkimage.getImage().getTool()
2379 _tool.setHandler("initialize", change_rdim_dia_mode_init)
2380 _image = gtkimage.getImage()
2381 if _image.hasSelection():
2382 _objs = []
2383 for _obj in _image.getSelectedObjects():
2384 if isinstance(_obj, RadialDimension):
2385 _objs.append(_obj)
2386 _change_rdim_dia_mode(gtkimage, _objs, tool)
2387 else:
2388 gtkimage.setPrompt(_('Click the RadialDimensions to toggle diameter dimension display'))
2389 _tool.setHandler("button_press", _rdim_dia_mode_first_button_press_cb)
2391 def _invert_adim(gtkimage, objlist, tool):
2392 _init = tool.getHandler('initialize')
2393 if len(objlist):
2394 _image = gtkimage.getImage()
2395 _image.startAction()
2396 try:
2397 for _obj in objlist:
2398 _obj.invert()
2399 finally:
2400 _image.endAction()
2401 tool.reset()
2402 _init(gtkimage)
2404 def _invert_adim_second_button_press_cb(gtkimage, widget, event, tool):
2405 _tol = gtkimage.getTolerance()
2406 _image = gtkimage.getImage()
2407 _x, _y = _image.getCurrentPoint()
2408 _active_layer = _image.getActiveLayer()
2409 _pts = _active_layer.find('point', _x, _y)
2410 if len(_pts) > 0:
2411 _x, _y = _pts[0].getCoords()
2412 _x1, _y1 = tool.getLocation()
2413 _xmin = min(_x1, _x)
2414 _ymin = min(_y1, _y)
2415 _xmax = max(_x1, _x)
2416 _ymax = max(_y1, _y)
2417 _objs = []
2418 for _obj in _active_layer.objsInRegion(_xmin, _ymin, _xmax, _ymax):
2419 if isinstance(_obj, AngularDimension):
2420 _objs.append(_obj)
2421 _invert_adim(gtkimage, _objs, tool)
2422 return True
2424 def _invert_adim_first_button_press_cb(gtkimage, widget, event, tool):
2425 _tol = gtkimage.getTolerance()
2426 _image = gtkimage.getImage()
2427 _x, _y = _image.getCurrentPoint()
2428 _objdict = _image.mapPoint(_x, _y, _tol, None)
2429 if len(_objdict):
2430 _active_layer = _image.getActiveLayer()
2431 if _active_layer in _objdict:
2432 _objs = []
2433 for _obj, _pt in _objdict[_active_layer]:
2434 if isinstance(_obj, AngularDimension):
2435 _objs.append(_obj)
2436 _invert_adim(gtkimage, _objs, tool)
2437 else:
2438 _pt, _pc = _image.getClosestPoint(_x, _y, tolerance=_tol)
2439 if _pt is not None:
2440 _x, _y = _pt.getCoords()
2441 else:
2442 _x, _y = _pc
2443 tool.setLocation(_x, _y)
2444 tool.setHandler("motion_notify", select_motion_notify)
2445 tool.setHandler("button_press", _invert_adim_second_button_press_cb)
2446 gtkimage.setPrompt(_('Click the second point for defining the region'))
2447 gtkimage.getGC().set_function(gtk.gdk.INVERT)
2448 return True
2450 def invert_adim_init(gtkimage, tool=None):
2451 _image = gtkimage.getImage()
2452 _tool = _image.getTool()
2453 _tool.setHandler("initialize", invert_adim_init)
2454 if _image.hasSelection():
2455 _objs = []
2456 for _obj in _image.getSelectedObjects():
2457 if isinstance(_obj, AngularDimension):
2458 _objs.append()
2459 _invert_adim(gtkimage, _objs, _tool)
2460 else:
2461 gtkimage.setPrompt(_('Click the AngularDimensions to be inverted'))
2462 _tool.setHandler("button_press", _invert_adim_first_button_press_cb)
2465 # arbitrary zoom
2468 def zoom_end_button_press_cb(gtkimage, widget, event, tool):
2469 _xp, _yp = gtkimage.image.getCurrentPoint()
2470 _x1, _y1 = tool.getLocation()
2471 _xmin = min(_xp, _x1)
2472 _ymin = min(_yp, _y1)
2473 _width, _height = gtkimage.getSize()
2474 _fw = float(_width)
2475 _fh = float(_height)
2476 _wpp = abs(_x1 - _xp)/_fw
2477 _hpp = abs(_y1 - _yp)/_fh
2478 if _wpp > _hpp:
2479 _scale = _wpp
2480 else:
2481 _scale = _hpp
2482 gtkimage.setView(_xmin, _ymin, _scale)
2483 zoom_init(gtkimage)
2484 return True
2486 def zoom_motion_notify(gtkimage, widget, event, tool):
2487 _tx, _ty = tool.getLocation()
2488 _px, _py = gtkimage.coordToPixTransform(_tx, _ty)
2489 # width, height = gtkimage.getSize()
2490 _gc = gtkimage.getGC()
2491 _x = int(event.x)
2492 _y = int(event.y)
2493 _cp = tool.getCurrentPoint()
2495 # it would be nice to draw the rectangle in the current
2496 # shape of the window ...
2498 if _cp is not None:
2499 _xc, _yc = _cp
2500 _xmin = min(_px, _xc)
2501 _ymin = min(_py, _yc)
2502 _rw = abs(_xc - _px)
2503 _rh = abs(_yc - _py)
2504 widget.window.draw_rectangle(_gc, False, _xmin, _ymin, _rw, _rh)
2505 _xmin = min(_x, _px)
2506 _ymin = min(_y, _py)
2507 tool.setCurrentPoint(_x, _y)
2508 _rw = abs(_x - _px)
2509 _rh = abs(_y - _py)
2510 widget.window.draw_rectangle(_gc, False, _xmin, _ymin, _rw, _rh)
2511 return True
2513 def zoom_button_press_cb(gtkimage, widget, event, tool):
2514 _x, _y = gtkimage.image.getCurrentPoint()
2515 tool.setLocation(_x, _y)
2516 tool.setHandler("motion_notify", zoom_motion_notify)
2517 tool.setHandler("button_press", zoom_end_button_press_cb)
2518 gtkimage.setPrompt(_('Click a second point to define the zoom window'))
2519 _gc = gtkimage.getGC()
2520 _gc.set_line_attributes(1, gtk.gdk.LINE_SOLID,
2521 gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER)
2522 _gc.set_function(gtk.gdk.INVERT)
2523 return True
2525 def zoom_init(gtkimage, tool=None):
2526 gtkimage.setPrompt(_('Click in the window.'))
2527 _tool = gtkimage.getImage().getTool()
2528 _tool.initialize()
2529 _tool.setHandler("button_press", zoom_button_press_cb)