def add_atom_to( self, a1, bond_to_use=None, pos=None): """adds new atom bound to atom id with bond, the position of new atom can be specified in pos or is decided calling find_place(), if x, y is specified and matches already existing atom it will be used instead of creating new one """ if pos != None: x, y = pos else: if bond_to_use: x, y = self.find_place( a1, Screen.any_to_px( self.paper.standard.bond_length), added_order=bond_to_use.order) else: x, y = self.find_place( a1, Screen.any_to_px( self.paper.standard.bond_length)) a2 = None # the new atom if pos: # try if the coordinates are the same as of another atom for at in self.atoms: if abs( at.x - x) < 2 and abs( at.y - y) < 2 and not at == a1: a2 = at break if not a2: a2 = self.create_new_atom( x, y) b = bond_to_use or bond( self.paper.standard, order=1, type='n') self.add_edge( a1, a2, e=b) b.molecule = self b.draw() return a2, b
def on_begin( self, scaling=None): self.paper.unselect_all() if self.paper.get_paper_property( 'crop_svg'): if len( self.paper.find_all()) <= 1: # background only Store.log( _('There is nothing to export. If you want to export an empty paper disable cropping of the drawing in the File/Properties menu.'), message_type="error") return 0 x1, y1, x2, y2 = self.paper.get_cropping_bbox() dx = x2-x1 dy = y2-y1 scalex, scaley = scaling or self.get_scaling( dx, dy) if not scalex: # the setting of scaling was canceled return 0 self.transformer = transform.transform() self.transformer.set_move( -x1, -y1) self.transformer.set_scaling_xy( scalex, scaley) else: dx = Screen.mm_to_px( self.paper._paper_properties['size_x']) dy = Screen.mm_to_px( self.paper._paper_properties['size_y']) scalex, scaley = scaling or self.get_scaling( dx, dy) if not scalex: # the setting of scaling was canceled return 0 self.transformer = transform.transform() self.transformer.set_scaling_xy( scalex, scaley) x1, y1, x2, y2 = self.transformer.transform_4( (0, 0, dx, dy)) self.pagesize = tuple( map( round, (x2-x1, y2-y1))) self.attrs['text_to_curves'] = False self.converter = self.converter_class( **self.attrs) return 1
def on_begin( self): self.paper.unselect_all() scale = 720.0/self.paper.winfo_fpixels( '254m') if self.paper.get_paper_property( 'crop_svg'): margin = self.paper.get_paper_property('crop_margin') items = list( self.paper.find_all()) items.remove( self.paper.background) if not items: Store.log( _('There is nothing to export. If you want to export an empty paper disable cropping of the drawing in the File/Properties menu.'), message_type="error") return 0 x1, y1, x2, y2 = self.paper.list_bbox( items) self.transformer = transform.transform() self.transformer.set_move( -x1+margin, -y1+margin) self.transformer.set_scaling( scale) dx = x2-x1 +2*margin dy = y2-y1 +2*margin else: self.transformer = transform.transform() self.transformer.set_scaling( scale) dx = Screen.mm_to_px( self.paper._paper_properties['size_x']) dy = Screen.mm_to_px( self.paper._paper_properties['size_y']) self.canvas = self.init_canvas( pagesize=(scale*dx, scale*dy)) self.converter = self.converter_class() return 1
def add_atom_to(self, a1, bond_to_use=None, pos=None): """adds new atom bound to atom id with bond, the position of new atom can be specified in pos or is decided calling find_place(), if x, y is specified and matches already existing atom it will be used instead of creating new one """ if pos != None: x, y = pos else: if bond_to_use: x, y = self.find_place(a1, Screen.any_to_px( self.paper.standard.bond_length), added_order=bond_to_use.order) else: x, y = self.find_place( a1, Screen.any_to_px(self.paper.standard.bond_length)) a2 = None # the new atom if pos: # try if the coordinates are the same as of another atom for at in self.atoms: if abs(at.x - x) < 2 and abs(at.y - y) < 2 and not at == a1: a2 = at break if not a2: a2 = self.create_new_atom(x, y) b = bond_to_use or bond(self.paper.standard, order=1, type='n') self.add_edge(a1, a2, e=b) b.molecule = self b.draw() return a2, b
def add_plus_mark( self, o, page): s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( o.atom.line_color), fill_color=self.paper.any_color_to_rgb_string( o.atom.area_color), stroke_width=Screen.px_to_cm( 1)) style_name = self.get_appropriate_style_name( s) # we must process oval first - it would otherwise cover the lines for i in o.items: if self.paper.type( i) == "oval": x, y, x2, y2 = map( Screen.px_to_cm, self.paper.coords( i)) size = Screen.px_to_cm( o.size) dom_extensions.elementUnder( page, 'draw:ellipse', (( 'svg:x', '%fcm' % x), ( 'svg:y', '%fcm' % y), ( 'svg:width', '%fcm' % size), ( 'svg:height', '%fcm' % size), ( 'draw:style-name', style_name))) for i in o.items: if self.paper.type( i) == "line": coords = self.paper.coords( i) # because some weird bug in tcl/tk i had to hack the coordinates in marks.py # the hack is reversed here in order to get the coords back # I also reduce the size of the mark a little #if o.items.index( i) == 1: # coords[0] += 0 # coords[2] += -1 #elif o.items.index( i) == 2: # coords[1] += 0 # coords[3] += -1 # end of hack coords = map( Screen.px_to_cm, coords) self.create_oo_line( coords, page, style_name)
def add_arrow( self, a, page): for item in a.items: # polygons (arrow heads, etc.) if self.paper.type( item) == "polygon": a_color = self.paper.itemcget( item, "fill") l_color = self.paper.itemcget( item, "outline") l_width = float( self.paper.itemcget( item, "width")) s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( l_color), fill_color=self.paper.any_color_to_rgb_string( a_color), stroke_width=Screen.px_to_cm( l_width)) style_name = self.get_appropriate_style_name( s) ps = geometry.coordinate_flat_list_to_xy_tuples( self.paper.coords( item)) points = [map( Screen.px_to_cm, p) for p in ps] self.create_oo_polygon( points, page, style_name) # polylines - standard arrows elif self.paper.type( item) == "line": line_pin = a._pins.index( self.paper.itemcget( item, 'arrow')) end_pin, start_pin = None,None if line_pin==1 or line_pin==3: end_pin = 1 if line_pin==2 or line_pin==3: start_pin = 1 l_color = self.paper.itemcget( item, "fill") l_width = float( self.paper.itemcget( item, "width")) s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( l_color), marker_end=end_pin, marker_start=start_pin, stroke_width=Screen.px_to_cm( l_width)) style_name = self.get_appropriate_style_name( s) ps = geometry.coordinate_flat_list_to_xy_tuples( self.paper.coords( item)) points = [map( Screen.px_to_cm, p) for p in ps] if self.paper.itemcget( item, "smooth") == "0": self.create_oo_polyline( points, page, style_name) else: self.create_oo_bezier( points, page, style_name)
def add_plus_mark(self, o, page): s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string(o.atom.line_color), fill_color=self.paper.any_color_to_rgb_string(o.atom.area_color), stroke_width=Screen.px_to_cm(1)) style_name = self.get_appropriate_style_name(s) # we must process oval first - it would otherwise cover the lines for i in o.items: if self.paper.type(i) == "oval": x, y, x2, y2 = map(Screen.px_to_cm, self.paper.coords(i)) size = Screen.px_to_cm(o.size) dom_extensions.elementUnder(page, 'draw:ellipse', (('svg:x', '%fcm' % x), ('svg:y', '%fcm' % y), ('svg:width', '%fcm' % size), ('svg:height', '%fcm' % size), ('draw:style-name', style_name))) for i in o.items: if self.paper.type(i) == "line": coords = self.paper.coords(i) # because some weird bug in tcl/tk i had to hack the coordinates in marks.py # the hack is reversed here in order to get the coords back # I also reduce the size of the mark a little #if o.items.index( i) == 1: # coords[0] += 0 # coords[2] += -1 #elif o.items.index( i) == 2: # coords[1] += 0 # coords[3] += -1 # end of hack coords = map(Screen.px_to_cm, coords) self.create_oo_line(coords, page, style_name)
def on_begin(self): self.paper.unselect_all() scale = 720.0 / self.paper.winfo_fpixels('254m') if self.paper.get_paper_property('crop_svg'): margin = self.paper.get_paper_property('crop_margin') items = list(self.paper.find_all()) items.remove(self.paper.background) if not items: Store.log(_( 'There is nothing to export. If you want to export an empty paper disable cropping of the drawing in the File/Properties menu.' ), message_type="error") return 0 x1, y1, x2, y2 = self.paper.list_bbox(items) self.transformer = transform.transform() self.transformer.set_move(-x1 + margin, -y1 + margin) self.transformer.set_scaling(scale) dx = x2 - x1 + 2 * margin dy = y2 - y1 + 2 * margin else: self.transformer = transform.transform() self.transformer.set_scaling(scale) dx = Screen.mm_to_px(self.paper._paper_properties['size_x']) dy = Screen.mm_to_px(self.paper._paper_properties['size_y']) self.canvas = self.init_canvas(pagesize=(scale * dx, scale * dy)) self.converter = self.converter_class() return 1
def switch_to_type( self, type): if type in "wha" and self.type not in "wha": # get the standard width only if the changes is not within the "wha" group self.wedge_width = Screen.any_to_px( self.paper.standard.wedge_width) elif type not in "wha" and self.type in "wha": # when both are outside the 'wha' do the similar self.bond_width = Screen.any_to_px( self.paper.standard.bond_width) self.type = type
def read_standard_values( self, standard, old_standard=None): meta_enabled.read_standard_values( self, standard, old_standard=old_standard) # wedge width if not old_standard or (standard.wedge_width != old_standard.wedge_width): self.wedge_width = Screen.any_to_px( standard.wedge_width) # line width if not old_standard or (standard.line_width != old_standard.line_width): self.line_width = Screen.any_to_px( standard.line_width) # bond width if not old_standard or (standard.bond_width != old_standard.bond_width): if hasattr( self, 'bond_width'): self.bond_width = misc.signum( self.bond_width) * Screen.any_to_px( standard.bond_width) else: self.bond_width = Screen.any_to_px( standard.bond_width)
def add_radical_mark(self, o, page): s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string(o.atom.line_color), fill_color=self.paper.any_color_to_rgb_string(o.atom.line_color), stroke_width=Screen.px_to_cm(0.1)) style_name = self.get_appropriate_style_name(s) for i in o.items: x, y, x2, y2 = map(Screen.px_to_cm, self.paper.coords(i)) size = Screen.px_to_cm(o.size) dom_extensions.elementUnder( page, 'draw:ellipse', (('svg:x', '%fcm' % x), ('svg:y', '%fcm' % y), ('svg:width', '%fcm' % size), ('svg:height', '%fcm' % size), ('draw:style-name', style_name)))
def add_radical_mark( self, o, page): s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( o.atom.line_color), fill_color=self.paper.any_color_to_rgb_string( o.atom.line_color), stroke_width=Screen.px_to_cm( 0.1)) style_name = self.get_appropriate_style_name( s) for i in o.items: x, y, x2, y2 = map( Screen.px_to_cm, self.paper.coords( i)) size = Screen.px_to_cm( o.size) dom_extensions.elementUnder( page, 'draw:ellipse', (( 'svg:x', '%fcm' % x), ( 'svg:y', '%fcm' % y), ( 'svg:width', '%fcm' % size), ( 'svg:height', '%fcm' % size), ( 'draw:style-name', style_name)))
def add_polyline(self, o, page): s = graphics_style(stroke_color=self.paper.any_color_to_rgb_string( o.line_color), stroke_width=Screen.px_to_cm(o.line_width)) style_name = self.get_appropriate_style_name(s) points = [map(Screen.px_to_cm, p.get_xy()) for p in o.points] self.create_oo_polyline(points, page, style_name)
def read_package( self, package, atom): typ = package.getAttribute( 'type') cls = globals().get( typ, None) if cls: auto = 0 #package.getAttribute( 'auto') != None and package.getAttribute( 'auto')) or 0 x, y, z = Screen.read_xml_point( package) size = package.getAttribute( 'size') and float( package.getAttribute( 'size')) or None if size: m = cls( atom, x, y, size=size, auto=int(auto)) else: m = cls( atom, x, y, auto=int(auto)) # class specific attributes for (attr, typ) in m.meta__save_attrs.items(): val = package.getAttribute( attr) if val != '': if typ == bool: value = bool( data.booleans.index( val)) elif typ == int: value = int( val) else: value = val setattr( m, attr, value) if hasattr( m, "_after_read_package"): m._after_read_package() return m else: raise ValueError("no such mark type %s" % typ)
def add_polygon( self, o, page): s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( o.line_color), fill_color=self.paper.any_color_to_rgb_string( o.area_color), stroke_width=Screen.px_to_cm( o.line_width)) style_name = self.get_appropriate_style_name( s) points = [map( Screen.px_to_cm, p.get_xy()) for p in o.points] self.create_oo_polygon( points, page, style_name)
def read_package(self, package): """reads the dom element package and sets internal state according to it""" if package.getAttribute('id'): self.id = package.getAttribute('id') pos = package.getElementsByTagName('point')[0] x, y, z = Screen.read_xml_point(pos) self.set_xy(x, y) ft = package.getElementsByTagName('ftext') try: self.xml_ftext = reduce(operator.add, [ e.nodeValue for e in ft[0].childNodes if isinstance(e, dom.Text) ], '') except IndexError: self.xml_ftext = "?" fnt = package.getElementsByTagName('font') if fnt: fnt = fnt[0] self.font_size = int(fnt.getAttribute('size')) self.font_family = fnt.getAttribute('family') if fnt.getAttribute('color'): self.line_color = fnt.getAttribute('color') if package.getAttribute('background-color'): self.area_color = package.getAttribute('background-color')
def read_standard_values(self, standard, old_standard=None): meta_enabled.read_standard_values(self, standard, old_standard=old_standard) if not old_standard or (standard.line_width != old_standard.line_width): self.line_width = Screen.any_to_px(standard.line_width)
def get_package(self, doc): """returns a DOM element describing the object in CDML, doc is the parent document which is used for element creation (the returned element is not inserted into the document)""" a = doc.createElement('text') a.setAttribute('id', self.id) if self.area_color != '': a.setAttribute('background-color', self.area_color) if self.font_size != self.paper.standard.font_size \ or self.font_family != self.paper.standard.font_family \ or self.line_color != self.paper.standard.line_color: font = dom_extensions.elementUnder( a, 'font', attributes=(('size', str(self.font_size)), ('family', self.font_family))) if self.line_color != self.paper.standard.line_color: font.setAttribute('color', self.line_color) x, y = Screen.px_to_text_with_unit((self.x, self.y)) dom_extensions.elementUnder(a, 'point', attributes=(('x', x), ('y', y))) ftext = dom_extensions.elementUnder(a, 'ftext') ftext.appendChild(doc.createTextNode(self.xml_ftext)) return a
def get_transformed_template(self, n, coords, type="empty", paper=None): """type is type of connection - 'bond', 'atom1'(for single atom), 'atom2'(for atom with more than 1 bond), 'empty'""" pap = paper or Store.app.paper pap.onread_id_sandbox_activate() # must be here to mangle the ids current = molecule(pap, package=self.templates[n]) pap.onread_id_sandbox_finish(apply_to=[current]) # id mangling current.name = "" self._scale_ratio = 1 trans = transform() # type empty - just draws the template - no conection if type == "empty": xt1, yt1 = current.t_atom.get_xy() xt2, yt2 = current.next_to_t_atom.get_xy() x1, y1 = coords bond_length = Screen.any_to_px(Store.app.paper.standard.bond_length) current.delete_items([current.t_atom], redraw=0, delete_single_atom=0) trans.set_move(-xt2, -yt2) trans.set_scaling(bond_length / math.sqrt((xt1 - xt2) ** 2 + (yt1 - yt2) ** 2)) trans.set_move(x1, y1) # type atom elif type == "atom1" or type == "atom2": xt1, yt1 = current.t_atom.get_xy() xt2, yt2 = current.next_to_t_atom.get_xy() x1, y1, x2, y2 = coords trans.set_move(-xt2, -yt2) trans.set_scaling( math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2) / math.sqrt((xt1 - xt2) ** 2 + (yt1 - yt2) ** 2) ) trans.set_rotation(math.atan2(xt1 - xt2, yt1 - yt2) - math.atan2(x1 - x2, y1 - y2)) trans.set_move(x2, y2) # type bond elif type == "bond": if not (current.t_bond_first and current.t_bond_second): warn("this template is not capable to be added to bond - sorry.") return None current.delete_items([current.t_atom], redraw=0, delete_single_atom=0) xt1, yt1 = current.t_bond_first.get_xy() xt2, yt2 = current.t_bond_second.get_xy() x1, y1, x2, y2 = coords self._scale_ratio = math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2) / math.sqrt( (xt1 - xt2) ** 2 + (yt1 - yt2) ** 2 ) # further needed for bond.bond_width transformation trans.set_move(-xt1, -yt1) trans.set_rotation(math.atan2(xt1 - xt2, yt1 - yt2) - math.atan2(x1 - x2, y1 - y2)) trans.set_scaling(self._scale_ratio) trans.set_move(x1, y1) self.transform_template(current, trans) # remove obsolete info from template if type == "atom1": current.delete_items([current.t_atom], redraw=0, delete_single_atom=0) elif type == "atom2": current.t_atom.x = x1 current.t_atom.y = y1 current.t_atom = None current.t_bond_first = None current.t_bond_second = None # return ready template return current
def add_electronpair_mark( self, o, page): i = o.items[0] width = float( self.paper.itemcget( i, 'width')) s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( o.atom.line_color), fill_color=self.paper.any_color_to_rgb_string( o.atom.line_color), stroke_width=Screen.px_to_cm( width)) style_name = self.get_appropriate_style_name( s) coords = map( Screen.px_to_cm, self.paper.coords( i)) self.create_oo_line( coords, page, style_name)
def expand( self): """expands the group and returns list of atoms that new drawing afterwords""" if self.group_type == "builtin": names = Store.gm.get_template_names() if self.symbol in names: a2 = self.neighbors[0] x1, y1 = a2.get_xy() x2, y2 = self.get_xy() self.group_graph = Store.gm.get_transformed_template( names.index( self.symbol), (x1,y1,x2,y2), type='atom1') replacement = self.group_graph.next_to_t_atom else: print "unknown group %s" % a.symbol return None elif self.group_type == "chain": self.group_graph = self.molecule.create_graph() p = PT.formula_dict( self.symbol) n = p['C'] last = None for i in range( n): v = self.group_graph.add_vertex() v.x, v.y = None, None if last: self.group_graph.add_edge( last, v) last = v replacement = self.group_graph.vertices[0] replacement.x = self.x replacement.y = self.y elif self.group_type == "implicit": if not self.group_graph: self.set_name( self.symbol, occupied_valency=self.occupied_valency) for v in self.group_graph.vertices: v.x, v.y = None, None v.show = v.symbol != 'C' assert self.connecting_atom != None replacement = self.connecting_atom replacement.x = self.x replacement.y = self.y self.molecule.eat_molecule( self.group_graph) self.molecule.move_bonds_between_atoms( self, replacement) self.molecule.delete_vertex( self) if self.occupied_valency: oasa.coords_generator.calculate_coords( self.molecule, bond_length=-1) else: # if the group is the only vertex of the molecule we must set the bond_length explicitly # and the move the whole molecule replacement.x = None replacement.y = None x, y = self.x, self.y oasa.coords_generator.calculate_coords( self.molecule, bond_length=Screen.any_to_px( self.paper.standard.bond_length)) dx = x - replacement.x dy = y - replacement.y [a.move( dx, dy) for a in self.group_graph.vertices] return self.group_graph.vertices
def add_bond( self, b, page): """adds bond item to page""" s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( b.line_color), stroke_width=Screen.px_to_cm( b.line_width)) style_name = self.get_appropriate_style_name( s) l_group = page # items to export line_items, items = b.get_exportable_items() # the export itself if b.type in 'nhd': for i in items: coords = map( Screen.px_to_cm, self.paper.coords( i)) self.create_oo_line( coords, page, style_name) elif b.type == 'o': for i in items: x, y, x2, y2 = map( Screen.px_to_cm, self.paper.coords( i)) size = Screen.px_to_cm( x2-x) dom_extensions.elementUnder( page, 'draw:ellipse', (( 'svg:x', '%fcm' % x), ( 'svg:y', '%fcm' % y), ( 'svg:width', '%fcm' % size), ( 'svg:height', '%fcm' % size), ( 'draw:style-name', style_name))) elif b.type == 'b': # bold bonds width is determined by the wedge_width s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( b.line_color), stroke_width=Screen.px_to_cm( b.wedge_width)) b_style_name = self.get_appropriate_style_name( s) for i in items: coords = map( Screen.px_to_cm, self.paper.coords( i)) self.create_oo_line( coords, page, b_style_name) elif b.type == 'w': s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( b.line_color), fill_color=self.paper.any_color_to_rgb_string( b.line_color), stroke_width=Screen.px_to_cm( b.line_width)) style_name = self.get_appropriate_style_name( s) for i in items: coords = map( Screen.px_to_cm, self.paper.coords( i)) point_array = [] for i in range( 0, len( coords), 2): point_array.append( (coords[i], coords[i+1])) self.create_oo_polygon( point_array, page, style_name) elif b.type == 'a': s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( b.line_color), stroke_width=Screen.px_to_cm( b.line_width)) style_name = self.get_appropriate_style_name( s) for i in items: coords = self.paper.coords( i) points = [] for j in range( 0, len( coords), 2): points.append( ( Screen.px_to_cm( coords[j]), Screen.px_to_cm(coords[j+1]))) self.create_oo_polyline( points, page, style_name) # line_items for i in line_items: coords = map( Screen.px_to_cm, self.paper.coords( i)) self.create_oo_line( coords, page, style_name)
def add_oval( self, o, page): s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( o.line_color), fill_color=self.paper.any_color_to_rgb_string( o.area_color), stroke_width=Screen.px_to_cm( o.line_width)) style_name = self.get_appropriate_style_name( s) x, y, x2, y2 = map( Screen.px_to_cm, o.coords) dom_extensions.elementUnder( page, 'draw:ellipse', (( 'svg:x', '%fcm' % x), ( 'svg:y', '%fcm' % y), ( 'svg:width', '%fcm' % (x2-x)), ( 'svg:height', '%fcm' % (y2-y)), ( 'draw:style-name', style_name)))
def read_package( self, package): """reads the dom element package and sets internal state according to it""" if package.getAttribute( 'id'): self.id = package.getAttribute( 'id') pnt = package.getElementsByTagName( 'point')[0] self.x, self.y, z = Screen.read_xml_point( pnt) if package.getAttribute( 'font_size'): self.font_size = int( package.getAttribute( 'font_size')) if package.getAttribute( 'color'): self.line_color = package.getAttribute( 'color') if package.getAttribute( 'background-color'): self.area_color = package.getAttribute( 'background-color')
def read_package(self, package): """reads the dom element package and sets internal state according to it""" if package.getAttribute('id'): self.id = package.getAttribute('id') pnt = package.getElementsByTagName('point')[0] self.x, self.y, z = Screen.read_xml_point(pnt) if package.getAttribute('font_size'): self.font_size = int(package.getAttribute('font_size')) if package.getAttribute('color'): self.line_color = package.getAttribute('color') if package.getAttribute('background-color'): self.area_color = package.getAttribute('background-color')
def get_package(self, doc): """returns a DOM element describing the object in CDML, doc is the parent document which is used for element creation (the returned element is not inserted into the document)""" pack = doc.createElement('circle') x1, y1, x2, y2 = Screen.px_to_text_with_unit( self.paper.screen_to_real_coords(self.coords)) dom_extensions.setAttributes( pack, (('x1', x1), ('y1', y1), ('x2', x2), ('y2', y2), ('area_color', self.area_color), ('line_color', self.line_color), ('width', str(self.line_width)))) return pack
def oasa_mol_to_bkchem_mol(mol, paper): m = molecule.molecule(paper) if None in reduce(operator.add, [[a.x, a.y] for a in mol.atoms], []): calc_position = 0 else: calc_position = 1 minx = None maxx = None miny = None maxy = None # atoms for a in mol.vertices: a2 = oasa_atom_to_bkchem_atom(a, paper, m) m.insert_atom(a2) if calc_position: # data for rescaling if not maxx or a2.x > maxx: maxx = a2.x if not minx or a2.x < minx: minx = a2.x if not miny or a2.y < miny: miny = a2.y if not maxy or a2.y > maxy: maxy = a2.y # bonds bond_lengths = [] for b in mol.edges: b2 = oasa_bond_to_bkchem_bond(b, paper) aa1, aa2 = b.vertices atom1 = m.atoms[mol.vertices.index(aa1)] atom2 = m.atoms[mol.vertices.index(aa2)] m.add_edge(atom1, atom2, b2) b2.molecule = m if calc_position: bond_lengths.append( math.sqrt((b2.atom1.x - b2.atom2.x)**2 + (b2.atom1.y - b2.atom2.y)**2)) # rescale if calc_position: bl = sum(bond_lengths) / len(bond_lengths) scale = Screen.any_to_px(paper.standard.bond_length) / bl movex = (maxx + minx) / 2 movey = (maxy + miny) / 2 trans = transform3d.transform3d() trans.set_move(-movex, -movey, 0) trans.set_scaling(scale) trans.set_move(320, 240, 0) for a in m.atoms: a.x, a.y, a.z = trans.transform_xyz(a.x, a.y, a.z) return m
def get_package( self, doc): """returns a DOM element describing the object in CDML, doc is the parent document which is used for element creation (the returned element is not inserted into the document)""" pack = doc.createElement( 'circle') x1, y1, x2, y2 = Screen.px_to_text_with_unit( self.paper.screen_to_real_coords( self.coords)) dom_extensions.setAttributes( pack, (('x1', x1), ('y1', y1), ('x2', x2), ('y2', y2), ('area_color', self.area_color), ('line_color', self.line_color), ('width', str( self.line_width)))) return pack
def get_package(self, doc): """returns a DOM element describing the object in CDML, doc is the parent document which is used for element creation (the returned element is not inserted into the document)""" pls = doc.createElement('plus') pls.setAttribute('id', self.id) x, y = Screen.px_to_text_with_unit((self.x, self.y)) dom_extensions.elementUnder(pls, 'point', (('x', x), ('y', y))) pls.setAttribute('font_size', str(self.font_size)) if self.line_color != '#000': pls.setAttribute('color', self.line_color) if self.area_color != '#ffffff': pls.setAttribute('background-color', self.area_color) return pls
def oasa_mol_to_bkchem_mol( mol, paper): m = molecule.molecule( paper) if None in reduce( operator.add, [[a.x, a.y] for a in mol.atoms], []): calc_position = 0 else: calc_position = 1 minx = None maxx = None miny = None maxy = None # atoms for a in mol.vertices: a2 = oasa_atom_to_bkchem_atom( a, paper, m) m.insert_atom( a2) if calc_position: # data for rescaling if not maxx or a2.x > maxx: maxx = a2.x if not minx or a2.x < minx: minx = a2.x if not miny or a2.y < miny: miny = a2.y if not maxy or a2.y > maxy: maxy = a2.y # bonds bond_lengths = [] for b in mol.edges: b2 = oasa_bond_to_bkchem_bond( b, paper) aa1, aa2 = b.vertices atom1 = m.atoms[ mol.vertices.index( aa1)] atom2 = m.atoms[ mol.vertices.index( aa2)] m.add_edge( atom1, atom2, b2) b2.molecule = m if calc_position: bond_lengths.append( math.sqrt( (b2.atom1.x-b2.atom2.x)**2 + (b2.atom1.y-b2.atom2.y)**2)) # rescale if calc_position: bl = sum( bond_lengths) / len( bond_lengths) scale = Screen.any_to_px( paper.standard.bond_length) / bl movex = (maxx+minx)/2 movey = (maxy+miny)/2 trans = transform3d.transform3d() trans.set_move( -movex, -movey, 0) trans.set_scaling( scale) trans.set_move( 320, 240, 0) for a in m.atoms: a.x, a.y, a.z = trans.transform_xyz( a.x, a.y, a.z) return m
def get_package( self, doc): """returns a DOM element describing the object in CDML, doc is the parent document which is used for element creation (the returned element is not inserted into the document)""" pls = doc.createElement('plus') pls.setAttribute( 'id', self.id) x, y = Screen.px_to_text_with_unit( (self.x, self.y)) dom_extensions.elementUnder( pls, 'point', (('x', x), ('y', y))) pls.setAttribute('font_size', str( self.font_size)) if self.line_color != '#000': pls.setAttribute( 'color', self.line_color) if self.area_color != '#ffffff': pls.setAttribute( 'background-color', self.area_color) return pls
def read_package(self, package): """reads the dom element package and sets internal state according to it""" a = ['no', 'yes'] on_off = ['off', 'on'] self.id = package.getAttribute('id') # marks for m in package.getElementsByTagName('mark'): mrk = marks.mark.read_package(m, self) self.marks.add(mrk) # position self.pos = package.getAttribute('pos') position = package.getElementsByTagName('point')[0] # reading of coords regardless of their unit x, y, z = Screen.read_xml_point(position) if z != None: self.z = z * self.paper.real_to_screen_ratio() # needed to support transparent handling of molecular size x, y = self.paper.real_to_screen_coords((x, y)) self.x = x self.y = y ft = package.getElementsByTagName('ftext') if ft: self.set_name( reduce(operator.add, [ e.nodeValue for e in ft[0].childNodes if isinstance(e, dom.Text) ], '').encode('utf-8')) else: raise TypeError, "not text atom" # font and fill color fnt = package.getElementsByTagName('font') if fnt: fnt = fnt[0] self.font_size = int(fnt.getAttribute('size')) self.font_family = fnt.getAttribute('family') if fnt.getAttribute('color'): self.line_color = fnt.getAttribute('color') # background color if package.getAttributeNode('background-color'): self.area_color = package.getAttribute('background-color') # number if package.getAttribute('show_number'): self.show_number = bool( data.booleans.index(package.getAttribute('show_number'))) if package.getAttribute('number'): self.number = package.getAttribute('number')
def add_orbital( self, o, page): s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( o.atom.line_color), fill_color=self.paper.any_color_to_rgb_string( o.atom.area_color), stroke_width=Screen.px_to_cm( 1.0)) style_name = self.get_appropriate_style_name( s) i = 0 points = [] for c in o._get_my_curve( num_points=50): if not i: x = c i = 1 else: points.append( map( Screen.px_to_cm, (x, c))) i = 0 self.create_oo_polygon( points, page, style_name)
def read_package( self, package): """reads the dom element package and sets internal state according to it""" a = ['no','yes'] on_off = ['off','on'] self.id = package.getAttribute( 'id') # marks for m in package.getElementsByTagName( 'mark'): mrk = marks.mark.read_package( m, self) self.marks.add( mrk) # position self.pos = package.getAttribute( 'pos') position = package.getElementsByTagName( 'point')[0] # reading of coords regardless of their unit x, y, z = Screen.read_xml_point( position) if z != None: self.z = z* self.paper.real_to_screen_ratio() # needed to support transparent handling of molecular size x, y = self.paper.real_to_screen_coords( (x, y)) self.x = x self.y = y ft = package.getElementsByTagName('ftext') if ft: self.set_name(''.join(e.nodeValue for e in ft[0].childNodes if isinstance(e, dom.Text))) else: raise TypeError("Not text atom.") # font and fill color fnt = package.getElementsByTagName('font') if fnt: fnt = fnt[0] self.font_size = int( fnt.getAttribute( 'size')) self.font_family = fnt.getAttribute( 'family') if fnt.getAttribute( 'color'): self.line_color = fnt.getAttribute( 'color') # background color if package.getAttributeNode( 'background-color'): self.area_color = package.getAttribute( 'background-color') # number if package.getAttribute( 'show_number'): self.show_number = bool( data.booleans.index( package.getAttribute( 'show_number'))) if package.getAttribute( 'number'): self.number = package.getAttribute( 'number')
def read_package(self, package): """reads the dom element package and sets internal state according to it""" a = ['no', 'yes'] on_off = ['off', 'on'] self.id = package.getAttribute('id') self.pos = package.getAttribute('pos') position = package.getElementsByTagName('point')[0] # reading of coords regardless of their unit x, y, z = Screen.read_xml_point(position) if z is not None: self.z = z * self.paper.real_to_screen_ratio() # needed to support transparent handling of molecular size x, y = self.paper.real_to_screen_coords((x, y)) self.x = x self.y = y self.symbol = package.getAttribute("name") # font and fill color fnt = package.getElementsByTagName('font') if fnt: fnt = fnt[0] self.font_size = int(fnt.getAttribute('size')) self.font_family = fnt.getAttribute('family') if fnt.getAttribute('color'): self.line_color = fnt.getAttribute('color') # background color if package.getAttributeNode('background-color'): self.area_color = package.getAttribute('background-color') # marks for m in package.getElementsByTagName('mark'): mrk = marks.mark.read_package(m, self) self.marks.add(mrk) # number if package.getAttribute('show_number'): self.show_number = bool( data.booleans.index(package.getAttribute('show_number'))) if package.getAttribute('number'): self.number = package.getAttribute('number') # free_sites if package.getAttribute('free_sites'): self.free_sites = int(package.getAttribute('free_sites'))
def get_package( self, doc): """returns a DOM element describing the object in CDML, doc is the parent document which is used for element creation (the returned element is not inserted into the document)""" a = doc.createElement('text') a.setAttribute( 'id', self.id) if self.area_color != '': a.setAttribute( 'background-color', self.area_color) if self.font_size != self.paper.standard.font_size \ or self.font_family != self.paper.standard.font_family \ or self.line_color != self.paper.standard.line_color: font = dom_extensions.elementUnder( a, 'font', attributes=(('size', str( self.font_size)), ('family', self.font_family))) if self.line_color != self.paper.standard.line_color: font.setAttribute( 'color', self.line_color) x, y = Screen.px_to_text_with_unit( (self.x, self.y)) dom_extensions.elementUnder( a, 'point', attributes=(('x', x),('y', y))) ftext = dom_extensions.elementUnder( a, 'ftext') ftext.appendChild( doc.createTextNode( self.xml_ftext)) return a
def read_package( self, package): """reads the dom element package and sets internal state according to it""" a = ['no','yes'] on_off = ['off','on'] self.id = package.getAttribute( 'id') self.pos = package.getAttribute( 'pos') position = package.getElementsByTagName( 'point')[0] # reading of coords regardless of their unit x, y, z = Screen.read_xml_point( position) if z != None: self.z = z* self.paper.real_to_screen_ratio() # needed to support transparent handling of molecular size x, y = self.paper.real_to_screen_coords( (x, y)) self.x = x self.y = y self.group_type = package.getAttribute( "group-type") if self.group_type in ("implicit","explicit"): #read the graph once pass self.symbol = package.getAttribute( "name") # font and fill color fnt = package.getElementsByTagName('font') if fnt: fnt = fnt[0] self.font_size = int( fnt.getAttribute( 'size')) self.font_family = fnt.getAttribute( 'family') if fnt.getAttribute( 'color'): self.line_color = fnt.getAttribute( 'color') # background color if package.getAttributeNode( 'background-color'): self.area_color = package.getAttribute( 'background-color') # marks for m in package.getElementsByTagName( 'mark'): mrk = marks.mark.read_package( m, self) self.marks.add( mrk) # number if package.getAttribute( 'show_number'): self.show_number = bool( data.booleans.index( package.getAttribute( 'show_number'))) if package.getAttribute( 'number'): self.number = package.getAttribute( 'number')
def read_package( self, package): """reads the dom element package and sets internal state according to it""" if package.getAttribute( 'id'): self.id = package.getAttribute( 'id') pos = package.getElementsByTagName( 'point')[0] x, y, z = Screen.read_xml_point( pos) self.set_xy( x, y) ft = package.getElementsByTagName('ftext') try: self.xml_ftext = reduce( operator.add, [e.nodeValue for e in ft[0].childNodes if isinstance( e, dom.Text)], '') except IndexError: self.xml_ftext = "?" fnt = package.getElementsByTagName('font') if fnt: fnt = fnt[0] self.font_size = int( fnt.getAttribute( 'size')) self.font_family = fnt.getAttribute( 'family') if fnt.getAttribute( 'color'): self.line_color = fnt.getAttribute( 'color') if package.getAttribute( 'background-color'): self.area_color = package.getAttribute( 'background-color')
def write_to_file(self, name): #{"v BKChemu bond.type":"v ChemDraw hodnota atributu Display elementu b"} bondType = { "w": "WedgeBegin", "h": "WedgedHashBegin", "a": "Wavy", "b": "Bold", "d": "Dash", "o": "Dash" } #{"arrow.type v BKChemu":["graphic/ArrowType","arrow/ArrowheadHead","arrow/ ArrowheadTail","arrow/ArrowheadType"]} #"retro":["RetroSynthetic","Full","","Angle"] - nefunguje, potrebuje dalsi povinne atributy arrowType = { "equilibrium": ["Equilibrium", "HalfLeft", "HalfLeft", "Solid"], "equilibrium2": ["Equilibrium", "HalfLeft", "HalfLeft", "Solid"], "normal": ["FullHead", "Full", "", "Solid"], "electron": ["HalfHead", "HalfLeft", "", "Solid"] } colors = [ "#ffffff", "#000000", "#ff0000", "#ffff00", "#00ff00", "#00ffff", "#0000ff", "#ff00ff" ] fonts = ["Arial", "Times New Roman"] out = dom.Document() root = out.createElement("CDXML") out.appendChild(root) elem01 = out.createElement("colortable") root.appendChild(elem01) elem03 = out.createElement("fonttable") root.appendChild(elem03) elem1 = out.createElement("page") root.appendChild(elem1) PaperX = int(Screen.mm_to_px(self.paper.get_paper_property("size_x"))) PaperY = int(Screen.mm_to_px(self.paper.get_paper_property("size_y"))) elem1.setAttribute("BoundingBox", "%d %d %d %d" % (0, 0, PaperX, PaperY)) elem1.setAttribute("Width", str(PaperX)) elem1.setAttribute("Height", str(PaperY)) elem1.setAttribute("DrawingSpace", "poster") for mol in self.paper.molecules: elem2 = out.createElement("fragment") elem1.appendChild(elem2) for atom in mol.atoms: elem3 = out.createElement("n") elem2.appendChild(elem3) elem3.setAttribute("id", re.sub("atom", "", atom.id)) elem3.setAttribute("p", "%f %f" % (atom.x, atom.y)) elem3.setAttribute("NumHydrogens", "%d" % atom.free_valency) if atom.symbol != "C" or atom.show: elem4 = out.createElement("t") elem3.appendChild(elem4) elem6 = out.createElement("s") elem6.setAttribute("size", str(atom.font_size)) elem6.setAttribute("face", "96") elem4.appendChild(elem6) text4 = re.sub("<.*?>", "", atom.xml_ftext) if text4: symbol = out.createTextNode(text4) elem6.appendChild(symbol) else: symbol = out.createTextNode(atom.xml_ftext) elem6.appendChild(symbol) NewColor = self.paper.any_color_to_rgb_string( atom.line_color) if NewColor not in colors: colors.append(NewColor) for color in colors: if color == NewColor: ShowColor = str(colors.index(color) + 2) elem4.setAttribute("color", ShowColor) elem6.setAttribute("color", ShowColor) NewFont = atom.font_family if NewFont not in fonts: fonts.append(NewFont) for font in fonts: if font == NewFont: FontId = str(fonts.index(font) + 3) elem6.setAttribute("font", FontId) for bond in mol.bonds: elem5 = out.createElement("b") elem2.appendChild(elem5) elem5.setAttribute("B", re.sub("atom", "", bond.atom1.id)) elem5.setAttribute("E", re.sub("atom", "", bond.atom2.id)) for bondB, bondC in bondType.items(): if bond.type == bondB: elem5.setAttribute("Display", bondC) elif bond.type == "h" and bond.equithick == 1: elem5.setAttribute("Display", "Hash") NewColor = self.paper.any_color_to_rgb_string(bond.line_color) if NewColor not in colors: colors.append(NewColor) for color in colors: if color == NewColor: ShowColor = str(colors.index(color) + 2) elem5.setAttribute("color", ShowColor) #print int( self.paper.any_color_to_rgb_string( bond.line_color)[1:3], 16) if bond.order > 1: elem5.setAttribute("Order", "%d" % bond.order) #print bond.type,bond.equithick,bond.simple_double for text in self.paper.texts: elem7 = out.createElement("t") elem1.appendChild(elem7) elem7.setAttribute("id", re.sub("text", "", text.id)) elem7.setAttribute("p", "%f %f" % (text.x, text.y)) elem7.setAttribute( "BoundingBox", "%d %d %d %d" % (text.bbox()[0], text.bbox()[1], text.bbox()[2], text.bbox()[3])) minidoc = dom.parseString("<a>%s</a>" % text.xml_ftext.encode('utf-8')) textik = {"i": 2, "b": 1, "sub": 32, "sup": 64} def get_text(el): texts = [] for ch in el.childNodes: if isinstance(ch, dom.Text): parents = [] par = ch.parentNode while not isinstance(par, dom.Document): parents.append(str(par.nodeName)) par = par.parentNode texts.append((ch.nodeValue, parents)) else: texts += get_text(ch) return texts texts2 = get_text(minidoc.childNodes[0]) for text2 in texts2: elem001 = out.createElement("s") elem7.appendChild(elem001) elem001.setAttribute("size", str(text.font_size)) text001 = out.createTextNode(text2[0]) elem001.appendChild(text001) def LogOR(xs): if len(xs) == 0: return 0 else: return xs[0] | LogOR(xs[1:]) Faces = [] for xxx in text2[1]: for P, F in textik.items(): if P == xxx: Faces.append(F) Face = LogOR(Faces) if Face != 0: elem001.setAttribute("face", str(Face)) NewFont = text.font_family if NewFont not in fonts: fonts.append(NewFont) for font in fonts: if font == NewFont: FontId = str(fonts.index(font) + 3) elem001.setAttribute("font", FontId) NewColor = self.paper.any_color_to_rgb_string(text.line_color) if NewColor not in colors: colors.append(NewColor) for color in colors: if color == NewColor: ShowColor = str(colors.index(color) + 2) elem001.setAttribute("color", ShowColor) elem7.setAttribute("color", ShowColor) for plus in self.paper.pluses: elem9 = out.createElement("graphic") elem1.appendChild(elem9) elem9.setAttribute("SymbolType", "Plus") elem9.setAttribute("BoundingBox", "%f %f %f %f" % plus.bbox()) elem9.setAttribute("GraphicType", "Symbol") elem9.setAttribute("id", re.sub("plus", "", plus.id)) #print plus.bbox() NewColor = self.paper.any_color_to_rgb_string(plus.line_color) if NewColor not in colors: colors.append(NewColor) for color in colors: if color == NewColor: ShowColor = str(colors.index(color) + 2) elem9.setAttribute("color", ShowColor) for arrow in self.paper.arrows: arrowPoints = [p.get_xy() for p in arrow.points] elem10 = out.createElement("graphic") elem1.appendChild(elem10) elem10.setAttribute("GraphicType", "Line") for arrowB, arrowC in arrowType.items(): if arrow.type == arrowB: elem10.setAttribute("ArrowType", arrowC[0]) NewColor = self.paper.any_color_to_rgb_string(arrow.line_color) if NewColor not in colors: colors.append(NewColor) for color in colors: if color == NewColor: ShowColor = str(colors.index(color) + 2) elem10.setAttribute("color", ShowColor) elem11 = out.createElement("arrow") elem1.appendChild(elem11) for arrowB, arrowC in arrowType.items(): if arrow.type == arrowB: elem11.setAttribute("ArrowheadHead", arrowC[1]) elem11.setAttribute("ArrowheadTail", arrowC[2]) elem11.setAttribute("ArrowheadType", arrowC[3]) elem11.setAttribute( "Head3D", str(arrowPoints[-1][0]) + " " + str(arrowPoints[-1][1])) elem11.setAttribute( "Tail3D", str(arrowPoints[0][0]) + " " + str(arrowPoints[0][1])) elem11.setAttribute( "BoundingBox", "%f %f %f %f" % (arrowPoints[-1][0], arrowPoints[-1][1], arrowPoints[0][0], arrowPoints[0][1])) elem11.setAttribute("color", ShowColor) #print arrow #print arrow.type for color in colors: elem02 = out.createElement("color") elem01.appendChild(elem02) red = str(int(color[1:3], 16) / 255.0) green = str(int(color[3:5], 16) / 255.0) blue = str(int(color[5:7], 16) / 255.0) elem02.setAttribute("r", red) elem02.setAttribute("g", green) elem02.setAttribute("b", blue) FontId = 3 for font in fonts: elem04 = out.createElement("font") elem03.appendChild(elem04) elem04.setAttribute("id", str(FontId)) FontId += 1 elem04.setAttribute("name", font) with open(name, 'wb') as f: f.write(out.toxml('utf-8'))
def read_standard_values( self, standard, old_standard=None): meta_enabled.read_standard_values( self, standard, old_standard=old_standard) if not old_standard or (standard.line_width != old_standard.line_width): self.line_width = Screen.any_to_px( standard.line_width)
def read_package( self, package): """reads the dom element package and sets internal state according to it""" a = ['no','yes'] on_off = ['off','on'] self.id = package.getAttribute( 'id') # marks (we read them here because they influence the charge) for m in package.getElementsByTagName( 'mark'): mrk = marks.mark.read_package( m, self) self.marks.add( mrk) self.pos = package.getAttribute( 'pos') position = package.getElementsByTagName( 'point')[0] # reading of coords regardless of their unit x, y, z = Screen.read_xml_point( position) if z is not None: self.z = z* self.paper.real_to_screen_ratio() # needed to support transparent handling of molecular size x, y = self.paper.real_to_screen_coords( (x, y)) self.x = x self.y = y ft = package.getElementsByTagName('ftext') if ft: self.set_name(''.join([e.toxml('utf-8') for e in ft[0].childNodes]), check_valency=0, interpret=0) else: self.set_name( package.getAttribute( 'name'), check_valency=0) # charge self.charge = package.getAttribute('charge') and int( package.getAttribute('charge')) or 0 # hydrogens if package.getAttribute( 'hydrogens'): self.show_hydrogens = package.getAttribute('hydrogens') else: self.show_hydrogens = 0 # font and fill color fnt = package.getElementsByTagName('font') if fnt: fnt = fnt[0] self.font_size = int( fnt.getAttribute( 'size')) self.font_family = fnt.getAttribute( 'family') if fnt.getAttribute( 'color'): self.line_color = fnt.getAttribute( 'color') # show if package.getAttribute( 'show'): self.show = package.getAttribute( 'show') else: self.show = (self.symbol!='C') # background color if package.getAttributeNode( 'background-color'): self.area_color = package.getAttribute( 'background-color') # multiplicity if package.getAttribute( 'multiplicity'): self.multiplicity = int( package.getAttribute( 'multiplicity')) # valency if package.getAttribute( 'valency'): self.valency = int( package.getAttribute( 'valency')) # number if package.getAttribute( 'show_number'): self.show_number = bool( data.booleans.index( package.getAttribute( 'show_number'))) if package.getAttribute( 'number'): self.number = package.getAttribute( 'number') # free_sites if package.getAttribute( 'free_sites'): self.free_sites = int( package.getAttribute( 'free_sites'))
def expand(self): """expands the group and returns list of atoms that new drawing afterwords""" if self.group_type == "builtin": names = Store.gm.get_template_names() if self.symbol in names: a2 = self.neighbors[0] x1, y1 = a2.get_xy() x2, y2 = self.get_xy() self.group_graph = Store.gm.get_transformed_template( names.index(self.symbol), (x1, y1, x2, y2), type='atom1') replacement = self.group_graph.next_to_t_atom else: print("unknown group %s" % a.symbol) return None elif self.group_type == "chain": self.group_graph = self.molecule.create_graph() p = PT.formula_dict(self.symbol) n = p['C'] last = None for i in range(n): v = self.group_graph.add_vertex() v.x, v.y = None, None if last: self.group_graph.add_edge(last, v) last = v replacement = self.group_graph.vertices[0] replacement.x = self.x replacement.y = self.y elif self.group_type == "implicit": if not self.group_graph: self.set_name(self.symbol, occupied_valency=self.occupied_valency) for v in self.group_graph.vertices: v.x, v.y = None, None v.show = v.symbol != 'C' assert self.connecting_atom is not None replacement = self.connecting_atom replacement.x = self.x replacement.y = self.y self.molecule.eat_molecule(self.group_graph) self.molecule.move_bonds_between_atoms(self, replacement) self.molecule.delete_vertex(self) if self.occupied_valency: oasa.coords_generator.calculate_coords(self.molecule, bond_length=-1) else: # if the group is the only vertex of the molecule we must set the bond_length explicitly # and the move the whole molecule replacement.x = None replacement.y = None x, y = self.x, self.y oasa.coords_generator.calculate_coords( self.molecule, bond_length=Screen.any_to_px(self.paper.standard.bond_length)) dx = x - replacement.x dy = y - replacement.y [a.move(dx, dy) for a in self.group_graph.vertices] return self.group_graph.vertices
def read_package(self, package): """reads the dom element package and sets internal state according to it""" x, y, z = Screen.read_xml_point(package) self.x, self.y = self.paper.real_to_screen_coords((x, y))
def y(self, y): self._y = Screen.any_to_px( y)
def construct_dom_tree( self, top_levels): """constructs the SVG dom from all top_levels""" # the constants border_size = self.paper.get_paper_property( 'crop_margin') # converter px_to_cm_txt = lambda x: Screen.px_to_text_with_unit( x, unit="cm", round_to=5) px_to_mm_txt = lambda x: Screen.px_to_text_with_unit( x, unit="mm", round_to=5) # the code self._id = 0 doc = self.document self.top = dom_extensions.elementUnder( doc, "svg", attributes=(("xmlns", "http://www.w3.org/2000/svg"), ("version", "1.0"))) if self.full_size: sx = self.paper.get_paper_property( 'size_x') sy = self.paper.get_paper_property( 'size_y') dom_extensions.setAttributes( self.top, (("width", '%fmm' % sx), ("height", '%fmm' % sy), ('viewBox', '0 0 %d %d' % (Screen.mm_to_px(sx), Screen.mm_to_px(sy))))) else: items = list( self.paper.find_all()) items.remove( self.paper.background) x1, y1, x2, y2 = self.paper.list_bbox( items) w = px_to_mm_txt( x2 -x1 +2*border_size) h = px_to_mm_txt( y2 -y1 +2*border_size) bx2, by2 = x2-x1+2*border_size, y2-y1+2*border_size dom_extensions.setAttributes( self.top, (("width", w), ("height", h), ("viewBox",'0 0 %d %d' % ( bx2, by2)))) self.group = dom_extensions.elementUnder( self.top, 'g', (('font-size', '12pt'), ('font-family', 'Helvetica'), ('stroke-linecap', 'round'))) if not self.full_size: self.group.setAttribute( 'transform', 'translate(%d,%d)' % (-x1+border_size, -y1+border_size)) # sort the top_levels according to paper.stack cs = [] for c in self.paper.stack: if c in top_levels: cs.append( c) for o in cs: if o.object_type == 'molecule': for b in o.bonds: self.add_bond( b) for a in o.atoms: self.add_atom( a) elif o.object_type == 'arrow': self.add_arrow( o) elif o.object_type == 'text': self.add_text( o) elif o.object_type == 'plus': self.add_plus( o) elif o.object_type in data.vector_graphics_types: if o.object_type == 'rect': self.add_rect( o) elif o.object_type == 'oval': self.add_oval( o) elif o.object_type == 'polygon': self.add_polygon( o) elif o.object_type == 'polyline': self.add_polyline( o)
def done(self, button): """called on dialog exit""" self.dialog.deactivate() if button != _('OK'): pass else: #print self.marks.get() # apply changes for o in self.items: change = 0 # ATOM if o.object_type == 'atom': a = self.atom_show.index(Pmw.SELECT) if a != 2: o.show = a change = 1 # positionning a = self.atom_pos.index(Pmw.SELECT) if a != 2: o.pos = ('center-first', 'center-last')[a] change = 1 if self.atom_charge.get(): a = int(self.atom_charge.get()) if hasattr(o, 'charge') and o.charge != a: o.charge = a change = 1 # hydrogens a = int(self.atom_show_h.index(Pmw.SELECT)) if a != 2: o.show_hydrogens = a change = 1 # font is in common now # BOND elif o.object_type == 'bond': # width is in common now # bond_width d = Screen.any_to_px(self.bond_dist.getvalue()) if d: if d != abs(o.bond_width): o.bond_width = d * misc.signum(o.bond_width) change = 1 # wedge_width d = Screen.any_to_px(self.wedge_width.getvalue()) if d: if d != o.wedge_width: o.wedge_width = d change = 1 # ratio ratio = self.double_length_ratio.getvalue() if ratio: ratio = float(self.double_length_ratio.getvalue()) if ratio != o.double_length_ratio: o.double_length_ratio = ratio change = 1 # ARROW - most is in common now elif o.object_type == 'arrow': if self.arrow_start_changed: o.set_pins(start=self.arrow_start.get()) change = 1 if self.arrow_end_changed: o.set_pins(end=self.arrow_end.get()) change = 1 if self.spline_changed: o.spline = self.spline.get() change = 1 # TEXT - all is in common now # PLUS - all is in common now # VECTOR - all is in common now # COMMON PROPERTIES # LINE COLOR if hasattr(o, 'line_color') and self.line_color.color: if self.line_color.color != o.line_color: o.line_color = self.line_color.color change = 1 # AREA COLOR if hasattr(o, 'area_color') and self.area_color.color: if self.area_color.color != o.area_color: o.area_color = self.area_color.color change = 1 # LINE WIDTH if hasattr(o, 'line_width'): w = Screen.any_to_px(self.line_width.getvalue()) if w: if w != o.line_width: o.line_width = w change = 1 # FONT if hasattr(o, 'font_family'): if self.font_size.get(): a = int(self.font_size.get()) o.font_size = a change = 1 if self.font_family.getcurselection( ) and self.font_family.getcurselection( )[0] != self.used_family: a = self.font_family.getcurselection()[0] o.font_family = a change = 1 # APPLY THE CHANGES if change: o.redraw() self.changes_made = 1 self.cleanup()
def get_transformed_template(self, n, coords, type='empty', paper=None): """type is type of connection - 'bond', 'atom1'(for single atom), 'atom2'(for atom with more than 1 bond), 'empty'""" pap = paper or Store.app.paper pap.onread_id_sandbox_activate() # must be here to mangle the ids current = molecule(pap, package=self.templates[n]) pap.onread_id_sandbox_finish(apply_to=[current]) # id mangling current.name = '' self._scale_ratio = 1 trans = transform() # type empty - just draws the template - no conection if type == 'empty': xt1, yt1 = current.t_atom.get_xy() xt2, yt2 = current.next_to_t_atom.get_xy() x1, y1 = coords bond_length = Screen.any_to_px( Store.app.paper.standard.bond_length) current.delete_items([current.t_atom], redraw=0, delete_single_atom=0) trans.set_move(-xt2, -yt2) trans.set_scaling(bond_length / math.sqrt((xt1 - xt2)**2 + (yt1 - yt2)**2)) trans.set_move(x1, y1) #type atom elif type == 'atom1' or type == 'atom2': xt1, yt1 = current.t_atom.get_xy() xt2, yt2 = current.next_to_t_atom.get_xy() x1, y1, x2, y2 = coords trans.set_move(-xt2, -yt2) trans.set_scaling( math.sqrt((x1 - x2)**2 + (y1 - y2)**2) / math.sqrt((xt1 - xt2)**2 + (yt1 - yt2)**2)) trans.set_rotation( math.atan2(xt1 - xt2, yt1 - yt2) - math.atan2(x1 - x2, y1 - y2)) trans.set_move(x2, y2) #type bond elif type == 'bond': if not (current.t_bond_first and current.t_bond_second): warn( "this template is not capable to be added to bond - sorry." ) return None current.delete_items([current.t_atom], redraw=0, delete_single_atom=0) xt1, yt1 = current.t_bond_first.get_xy() xt2, yt2 = current.t_bond_second.get_xy() x1, y1, x2, y2 = coords self._scale_ratio = math.sqrt( (x1 - x2)**2 + (y1 - y2)**2) / math.sqrt( (xt1 - xt2)**2 + (yt1 - yt2)** 2) # further needed for bond.bond_width transformation trans.set_move(-xt1, -yt1) trans.set_rotation( math.atan2(xt1 - xt2, yt1 - yt2) - math.atan2(x1 - x2, y1 - y2)) trans.set_scaling(self._scale_ratio) trans.set_move(x1, y1) self.transform_template(current, trans) #remove obsolete info from template if type == 'atom1': current.delete_items([current.t_atom], redraw=0, delete_single_atom=0) elif type == 'atom2': current.t_atom.x = x1 current.t_atom.y = y1 current.t_atom = None current.t_bond_first = None current.t_bond_second = None #return ready template return current
def construct_dom_tree(self, top_levels): """Construct the SVG dom from all top_levels. """ # the constants border_size = self.paper.get_paper_property('crop_margin') # converter px_to_cm_txt = lambda x: Screen.px_to_text_with_unit( x, unit="cm", round_to=5) px_to_mm_txt = lambda x: Screen.px_to_text_with_unit( x, unit="mm", round_to=5) # the code self._id = 0 doc = self.document self.top = dom_extensions.elementUnder( doc, "svg", attributes=(("xmlns", "http://www.w3.org/2000/svg"), ("version", "1.0"))) if self.full_size: sx = self.paper.get_paper_property('size_x') sy = self.paper.get_paper_property('size_y') dom_extensions.setAttributes( self.top, (("width", '%fmm' % sx), ("height", '%fmm' % sy), ('viewBox', '0 0 %d %d' % (Screen.mm_to_px(sx), Screen.mm_to_px(sy))))) else: items = list(self.paper.find_all()) items.remove(self.paper.background) x1, y1, x2, y2 = self.paper.list_bbox(items) w = px_to_mm_txt(x2 - x1 + 2 * border_size) h = px_to_mm_txt(y2 - y1 + 2 * border_size) bx2, by2 = x2 - x1 + 2 * border_size, y2 - y1 + 2 * border_size dom_extensions.setAttributes( self.top, (("width", w), ("height", h), ("viewBox", '0 0 %d %d' % (bx2, by2)))) self.group = dom_extensions.elementUnder(self.top, 'g', (('font-size', '12pt'), ('font-family', 'Helvetica'), ('stroke-linecap', 'round'))) if not self.full_size: self.group.setAttribute( 'transform', 'translate(%d,%d)' % (-x1 + border_size, -y1 + border_size)) # sort the top_levels according to paper.stack cs = [] for c in self.paper.stack: if c in top_levels: cs.append(c) for o in cs: if o.object_type == 'molecule': for b in o.bonds: self.add_bond(b) for a in o.atoms: self.add_atom(a) elif o.object_type == 'arrow': self.add_arrow(o) elif o.object_type == 'text': self.add_text(o) elif o.object_type == 'plus': self.add_plus(o) elif o.object_type in data.vector_graphics_types: if o.object_type == 'rect': self.add_rect(o) elif o.object_type == 'oval': self.add_oval(o) elif o.object_type == 'polygon': self.add_polygon(o) elif o.object_type == 'polyline': self.add_polyline(o)
def _set_y( self, y): self._y = Screen.any_to_px( y)
def _set_x( self, x): self._x = Screen.any_to_px( x)
def write_to_file( self, name): #{"v BKChemu bond.type":"v ChemDraw hodnota atributu Display elementu b"} bondType={"w":"WedgeBegin", "h":"WedgedHashBegin", "a":"Wavy", "b":"Bold", "d":"Dash", "o":"Dash" } #{"arrow.type v BKChemu":["graphic/ArrowType","arrow/ArrowheadHead","arrow/ ArrowheadTail","arrow/ArrowheadType"]} #"retro":["RetroSynthetic","Full","","Angle"] - nefunguje, potrebuje dalsi povinne atributy arrowType={"equilibrium":["Equilibrium","HalfLeft","HalfLeft","Solid"], "equilibrium2":["Equilibrium","HalfLeft","HalfLeft","Solid"], "normal":["FullHead","Full","","Solid"], "electron":["HalfHead","HalfLeft","","Solid"] } colors=["#ffffff","#000000","#ff0000","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff"] fonts=["Arial","Times New Roman"] out=dom.Document() root=out.createElement("CDXML") out.appendChild(root) elem01=out.createElement("colortable") root.appendChild(elem01) elem03=out.createElement("fonttable") root.appendChild(elem03) elem1=out.createElement("page") root.appendChild(elem1) PaperX=int(Screen.mm_to_px( self.paper.get_paper_property("size_x") ) ) PaperY=int(Screen.mm_to_px( self.paper.get_paper_property("size_y") ) ) elem1.setAttribute("BoundingBox","%d %d %d %d" % (0,0,PaperX,PaperY) ) elem1.setAttribute("Width",str(PaperX) ) elem1.setAttribute("Height",str(PaperY) ) elem1.setAttribute("DrawingSpace","poster") for mol in self.paper.molecules: elem2=out.createElement("fragment") elem1.appendChild(elem2) for atom in mol.atoms: elem3=out.createElement("n") elem2.appendChild(elem3) elem3.setAttribute("id",re.sub("atom","",atom.id) ) elem3.setAttribute("p","%f %f" %(atom.x,atom.y) ) elem3.setAttribute("NumHydrogens","%d" % atom.free_valency) if atom.symbol != "C" or atom.show: elem4=out.createElement("t") elem3.appendChild(elem4) elem6=out.createElement("s") elem6.setAttribute("size",str(atom.font_size) ) elem6.setAttribute("face","96") elem4.appendChild(elem6) text4 = re.sub( "<.*?>", "", atom.xml_ftext) if text4: symbol=out.createTextNode(text4) elem6.appendChild(symbol) else: symbol=out.createTextNode(atom.xml_ftext) elem6.appendChild(symbol) NewColor=self.paper.any_color_to_rgb_string( atom.line_color) if NewColor not in colors: colors.append (NewColor) for color in colors: if color==NewColor: ShowColor=str(colors.index(color)+2) elem4.setAttribute("color",ShowColor) elem6.setAttribute("color",ShowColor) NewFont=atom.font_family if NewFont not in fonts: fonts.append(NewFont) for font in fonts: if font==NewFont: FontId=str(fonts.index(font)+3) elem6.setAttribute("font",FontId) for bond in mol.bonds: elem5=out.createElement("b") elem2.appendChild(elem5) elem5.setAttribute("B",re.sub("atom","",bond.atom1.id) ) elem5.setAttribute("E",re.sub("atom","",bond.atom2.id) ) for bondB, bondC in bondType.items(): if bond.type==bondB: elem5.setAttribute("Display",bondC) elif bond.type=="h" and bond.equithick==1: elem5.setAttribute("Display","Hash") NewColor=self.paper.any_color_to_rgb_string( bond.line_color) if NewColor not in colors: colors.append (NewColor) for color in colors: if color==NewColor: ShowColor=str(colors.index(color)+2) elem5.setAttribute("color",ShowColor) #print int( self.paper.any_color_to_rgb_string( bond.line_color)[1:3], 16) if bond.order > 1: elem5.setAttribute("Order","%d" % bond.order ) #print bond.type,bond.equithick,bond.simple_double for text in self.paper.texts: elem7=out.createElement("t") elem1.appendChild(elem7) elem7.setAttribute("id",re.sub("text","",text.id)) elem7.setAttribute("p","%f %f" % (text.x,text.y)) elem7.setAttribute("BoundingBox","%d %d %d %d" % (text.bbox()[0],text.bbox()[1],text.bbox()[2],text.bbox()[3]) ) minidoc = dom.parseString( "<a>%s</a>" % text.xml_ftext.encode('utf-8')) textik={"i":2, "b":1, "sub":32, "sup":64 } def get_text( el): texts = [] for ch in el.childNodes: if isinstance( ch, dom.Text): parents = [] par = ch.parentNode while not isinstance( par, dom.Document): parents.append( str(par.nodeName)) par = par.parentNode texts.append((ch.nodeValue, parents)) else: texts += get_text( ch) return texts texts2= get_text(minidoc.childNodes[0]) for text2 in texts2: elem001=out.createElement("s") elem7.appendChild(elem001) elem001.setAttribute("size", str(text.font_size)) text001=out.createTextNode(text2[0]) elem001.appendChild(text001) def LogOR(xs): if len(xs) == 0: return 0 else: return xs[0] | LogOR (xs[1:]) Faces=[] for xxx in text2[1]: for P, F in textik.items(): if P==xxx: Faces.append(F) Face=LogOR(Faces) if Face!=0: elem001.setAttribute("face",str(Face) ) NewFont=text.font_family if NewFont not in fonts: fonts.append(NewFont) for font in fonts: if font==NewFont: FontId=str(fonts.index(font)+3) elem001.setAttribute("font",FontId) NewColor=self.paper.any_color_to_rgb_string(text.line_color) if NewColor not in colors: colors.append (NewColor) for color in colors: if color==NewColor: ShowColor=str(colors.index(color)+2) elem001.setAttribute("color",ShowColor) elem7.setAttribute("color",ShowColor) for plus in self.paper.pluses: elem9=out.createElement("graphic") elem1.appendChild(elem9) elem9.setAttribute("SymbolType","Plus") elem9.setAttribute("BoundingBox","%f %f %f %f" % plus.bbox()) elem9.setAttribute("GraphicType","Symbol") elem9.setAttribute("id",re.sub("plus","",plus.id)) #print plus.bbox() NewColor=self.paper.any_color_to_rgb_string(plus.line_color) if NewColor not in colors: colors.append (NewColor) for color in colors: if color==NewColor: ShowColor=str(colors.index(color)+2) elem9.setAttribute("color",ShowColor) for arrow in self.paper.arrows: arrowPoints=[p.get_xy() for p in arrow.points] elem10=out.createElement("graphic") elem1.appendChild(elem10) elem10.setAttribute("GraphicType","Line") for arrowB, arrowC in arrowType.items(): if arrow.type==arrowB: elem10.setAttribute("ArrowType",arrowC[0]) NewColor=self.paper.any_color_to_rgb_string(arrow.line_color) if NewColor not in colors: colors.append (NewColor) for color in colors: if color==NewColor: ShowColor=str(colors.index(color)+2) elem10.setAttribute("color",ShowColor) elem11=out.createElement("arrow") elem1.appendChild(elem11) for arrowB, arrowC in arrowType.items(): if arrow.type==arrowB: elem11.setAttribute("ArrowheadHead",arrowC[1]) elem11.setAttribute("ArrowheadTail",arrowC[2]) elem11.setAttribute("ArrowheadType",arrowC[3]) elem11.setAttribute("Head3D",str(arrowPoints[-1][0])+" "+str(arrowPoints[-1][1])) elem11.setAttribute("Tail3D",str(arrowPoints[0][0])+" "+str(arrowPoints[0][1])) elem11.setAttribute("BoundingBox","%f %f %f %f" % (arrowPoints[-1][0],arrowPoints[-1][1],arrowPoints[0][0],arrowPoints[0][1]) ) elem11.setAttribute("color",ShowColor) #print arrow #print arrow.type for color in colors: elem02=out.createElement("color") elem01.appendChild(elem02) red=str(int(color[1:3],16)/255.0) green=str(int(color[3:5],16)/255.0) blue=str(int(color[5:7],16)/255.0) elem02.setAttribute("r",red) elem02.setAttribute("g",green) elem02.setAttribute("b",blue) FontId=3 for font in fonts: elem04=out.createElement("font") elem03.appendChild(elem04) elem04.setAttribute("id",str(FontId) ) FontId+=1 elem04.setAttribute("name",font) with open(name, 'wb') as f: f.write(out.toxml('utf-8'))