示例#1
0
    def do(self):
        edit_config = FieldsDialogSimple(
            "Zeobuilder configuration",
            context.application.configuration.create_main_field(),
            ((gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL), (gtk.STOCK_OK, gtk.RESPONSE_OK))
        )

        class Settings(object):
            pass
        settings = Settings()
        settings.__dict__ = context.application.configuration.settings
        edit_config.run(settings)
        context.application.configuration.settings = settings.__dict__
示例#2
0
    def do(self):
        edit_config = FieldsDialogSimple(
            "Zeobuilder configuration",
            context.application.configuration.create_main_field(),
            ((gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
             (gtk.STOCK_OK, gtk.RESPONSE_OK)))

        class Settings(object):
            pass

        settings = Settings()
        settings.__dict__ = context.application.configuration.settings
        edit_config.run(settings)
        context.application.configuration.settings = settings.__dict__
示例#3
0
    def on_set_parameters(self, menu, cell):
        from zeobuilder.gui.fields_dialogs import FieldsDialogSimple

        dialog = FieldsDialogSimple(
            "Set the cell parameters",
            CellParameters(
                attribute_name="cell",
                show_popup=False,
            ),
            ((gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL), (gtk.STOCK_OK, gtk.RESPONSE_OK)),
        )

        parameters = Parameters()
        parameters.cell = cell
        if dialog.run(parameters) == gtk.RESPONSE_OK:
            self.field.write_to_widget(self.field.convert_to_representation(parameters.cell))
示例#4
0
    def run(self, max_shell_size, rows, graph):
        self.graph = graph
        self.max_shell_size = max_shell_size

        self.list_store = gtk.ListStore(int, int, *([str]*(max_shell_size+2)))
        for index, row in enumerate(rows):
            row += [""]*(max_shell_size-(len(row)-4))
            self.list_store.append(row)

        response = FieldsDialogSimple.run(self, self)

        self.list_view.set_model(None)
        for column in self.list_view.get_columns():
            self.list_view.remove_column(column)
        del self.graph
        del self.max_shell_size

        return response
示例#5
0
    def on_set_parameters(self, menu, cell):
        from zeobuilder.gui.fields_dialogs import FieldsDialogSimple

        dialog = FieldsDialogSimple(
            "Set the cell parameters",
            CellParameters(
                attribute_name="cell",
                show_popup=False,
            ),
            ((gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
             (gtk.STOCK_OK, gtk.RESPONSE_OK)),
        )

        parameters = Parameters()
        parameters.cell = cell
        if dialog.run(parameters) == gtk.RESPONSE_OK:
            self.field.write_to_widget(
                self.field.convert_to_representation(parameters.cell))
示例#6
0
    def run(self, max_shell_size, rows, graph):
        self.graph = graph
        self.max_shell_size = max_shell_size

        self.list_store = gtk.ListStore(int, int,
                                        *([str] * (max_shell_size + 2)))
        for index, row in enumerate(rows):
            row += [""] * (max_shell_size - (len(row) - 4))
            self.list_store.append(row)

        response = FieldsDialogSimple.run(self, self)

        self.list_view.set_model(None)
        for column in self.list_view.get_columns():
            self.list_view.remove_column(column)
        del self.graph
        del self.max_shell_size

        return response
示例#7
0
class SketchOptions(GladeWrapper):

    edit_erase_filter = FieldsDialogSimple(
        "Edit the Erase filter",
        fields.faulty.Expression(
            label_text="Erase filter expression",
            attribute_name="erase_filter",
            show_popup=True,
            history_name="filter",
        ), ((gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
            (gtk.STOCK_OK, gtk.RESPONSE_OK)))

    def __init__(self):
        GladeWrapper.__init__(self, "plugins/molecular/gui.glade", "wi_sketch",
                              "window")
        self.window.hide()
        self.init_callbacks(self.__class__)
        self.init_proxies([
            "cb_object", "cb_vector", "cb_erase_filter",
            "bu_edit_erase_filter", "la_current", "bu_set_atom", "cb_bondtype",
            "hbox_atoms", "hbox_quickpicks", "hbox_fragments", "la_fragment",
            "cb_fragment"
        ])

        self.erase_filter = Expression("True")
        #Initialize atom number - this can be changed anytime with the edit_atom_number dialog
        self.atom_number = 6

        # Initialize the GUI
        #  1) common parts of the comboboxes
        def render_icon(column, cell, model, iter):
            if model.get_value(iter, 0) == "Fragment":
                cell.set_property(
                    "pixbuf",
                    context.application.plugins.get_node("Atom").icon)
            else:
                cell.set_property(
                    "pixbuf",
                    context.application.plugins.get_node(
                        model.get_value(iter, 0)).icon)

        #  2) fill the objects combo box
        self.object_store = gtk.ListStore(str)
        self.object_store.append(["Atom"])
        self.object_store.append(["Fragment"])
        self.object_store.append(["Point"])
        self.object_store.append(["Sphere"])
        self.object_store.append(["Box"])
        self.cb_object.set_model(self.object_store)

        renderer_pixbuf = gtk.CellRendererPixbuf()
        self.cb_object.pack_start(renderer_pixbuf, expand=False)
        self.cb_object.set_cell_data_func(renderer_pixbuf, render_icon)
        renderer_text = gtk.CellRendererText()
        self.cb_object.pack_start(renderer_text, expand=True)
        self.cb_object.add_attribute(renderer_text, "text", 0)

        self.cb_object.set_active(0)

        #  3) fill the vector combo box
        self.vector_store = gtk.ListStore(str)
        self.vector_store.append(["Bond"])
        self.vector_store.append(["Arrow"])
        self.vector_store.append(["Spring"])
        self.cb_vector.set_model(self.vector_store)

        renderer_pixbuf = gtk.CellRendererPixbuf()
        self.cb_vector.pack_start(renderer_pixbuf, expand=False)
        self.cb_vector.set_cell_data_func(renderer_pixbuf, render_icon)
        renderer_text = gtk.CellRendererText()
        self.cb_vector.pack_start(renderer_text, expand=True)
        self.cb_vector.add_attribute(renderer_text, "text", 0)

        self.cb_vector.set_active(0)

        # 4) fill the bond type combo box
        self.bondtype_store = gtk.ListStore(str, int)
        self.bondtype_store.append(["Single bond", BOND_SINGLE])
        self.bondtype_store.append(["Double bond", BOND_DOUBLE])
        self.bondtype_store.append(["Triple bond", BOND_TRIPLE])
        self.bondtype_store.append(["Hybrid bond", BOND_HYBRID])
        self.bondtype_store.append(["Hydrogen bond", BOND_HYDROGEN])
        self.cb_bondtype.set_model(self.bondtype_store)

        #no icons like the others, just text here
        renderer_text = gtk.CellRendererText()
        self.cb_bondtype.pack_start(renderer_text, expand=True)
        self.cb_bondtype.add_attribute(renderer_text, "text", 0)

        self.cb_bondtype.set_active(0)

        # register quick pick config setting
        config = context.application.configuration
        config.register_setting(
            "sketch_quickpicks",
            [6, 7, 8, 9, 10, 11],
            DialogFieldInfo(
                "Sketch tool", (0, 2),
                fields.faulty.IntegerList(
                    label_text="Quick pick atoms (applies after restart)",
                    attribute_name="sketch_quickpicks",
                )),
        )

        # 5)create the "quick pick" atom buttons
        for index in xrange(len(config.sketch_quickpicks)):
            atomnumber = config.sketch_quickpicks[index]
            bu_element = gtk.Button("")
            bu_element.set_label("%s" % periodic[atomnumber].symbol)
            bu_element.connect("clicked", self.on_bu_element_clicked, index)
            # add to hbox
            self.hbox_quickpicks.pack_start(bu_element)
            bu_element.show()

        # 6)fill the fragment combo box with filenames from share/fragments
        fragment_dir = context.get_share_filename('fragments')
        self.fragment_store = gtk.ListStore(str)
        for filename in sorted(os.listdir(fragment_dir)):
            # Ignore subfolders and files with extension other than cml
            if os.path.isdir(os.path.join(fragment_dir,
                                          filename)) or filename[-3:] != 'cml':
                continue
            self.fragment_store.append([filename[:-4]])
        self.cb_fragment.set_model(self.fragment_store)

        renderer_text = gtk.CellRendererText()
        self.cb_fragment.pack_start(renderer_text, expand=True)
        self.cb_fragment.add_attribute(renderer_text, "text", 0)
        self.cb_fragment.set_active(0)

    @property
    def current_object(self):
        return self.object_store.get_value(self.cb_object.get_active_iter(), 0)

    @property
    def current_fragment(self):
        return self.fragment_store.get_value(
            self.cb_fragment.get_active_iter(), 0)

    def on_window_delete_event(self, window, event):
        self.window.hide()
        return True

    def on_bu_edit_erase_filter_clicked(self, button):
        self.edit_erase_filter.run(self)

    def on_bu_set_atom_clicked(self, button):
        self.edit_atom_number = FieldsDialogSimple(
            "Select atom number",
            fields.edit.Element(attribute_name="atom_number"),
            ((gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
             (gtk.STOCK_OK, gtk.RESPONSE_OK)))
        self.edit_atom_number.run(self)
        atom_symbol = periodic[self.atom_number].symbol
        self.la_current.set_label("Current: %s " % str(atom_symbol))

    def on_cb_object_changed(self, combo):
        self.hbox_atoms.hide()
        self.la_current.hide()
        self.hbox_fragments.hide()
        if (self.current_object == "Atom"):
            self.hbox_atoms.show()
            self.la_current.show()
        if (self.current_object == "Fragment"):
            self.cb_fragment.show()
            self.hbox_fragments.show()

    def on_bu_element_clicked(self, widget, index):
        self.atom_number = context.application.configuration.sketch_quickpicks[
            index]
        atom_symbol = periodic[self.atom_number].symbol
        self.la_current.set_label("Current: %s" % str(atom_symbol))

    def on_cb_vector_changed(self, combo):
        # When the selected object is an atom, show the extra button.
        if (self.vector_store.get_value(self.cb_vector.get_active_iter(),
                                        0) == "Bond"):
            self.cb_bondtype.show()
        else:
            self.cb_bondtype.hide()

    def get_new(self, position):
        if self.current_object == "Fragment":
            filename = context.get_share_filename('fragments/%s.cml' %
                                                  self.current_fragment)
            molecule = load_cml(filename)[0]

            Frame = context.application.plugins.get_node("Frame")
            new = Frame(name=self.current_fragment)

            load_filter = context.application.plugins.get_load_filter('cml')
            load_filter.load_molecule(new, molecule)
        else:
            NewClass = context.application.plugins.get_node(
                self.current_object)
            new = NewClass()
            if self.current_object == "Atom":
                new.set_number(self.atom_number)
                new.set_name(periodic[self.atom_number].symbol)

        translation = Translation(position)
        primitive.Transform(new, translation)
        return new

    def add_new(self, position, parent):
        new = self.get_new(position)

        if self.current_object == "Fragment":
            result = new.children[1]
            primitive.Add(new, parent)
            UnframeAbsolute = context.application.plugins.get_action(
                "UnframeAbsolute")
            UnframeAbsolute([new])
            #return result
        else:
            primitive.Add(new, parent)
            return new

    def replace(self, gl_object):
        if not gl_object.get_fixed():
            new = self.get_new(gl_object.transformation.t)

            # select a target object, i.e. the one the will be connected with
            # the bonds/vectors/... of the replaced object
            if (self.current_object == "Fragment"):
                # fragments are inserted as frames
                # take atom with index 1 as target
                target_object = new.children[1]
            else:
                target_object = new
            # check if all connections to the replaced object are applicable
            # to the new object. if not, then do not perform the replacement
            # and return early.
            for reference in gl_object.references[::-1]:
                if not reference.check_target(target_object):
                    return
            # add the new object
            parent = gl_object.parent
            primitive.Add(new, parent)

            if (self.current_object == "Fragment"):
                # Fix the rotation and translation of the molecular fragment.
                # Rotation
                Bond = context.application.plugins.get_node("Bond")
                if len(gl_object.references) == 1 and isinstance(
                        gl_object.references[0].parent, Bond):
                    bond1 = gl_object.references[0].parent
                    direction1 = bond1.shortest_vector_relative_to(parent)
                    if bond1.children[0].target != gl_object:
                        direction1 *= -1
                    bond2 = new.children[0].references[0].parent
                    direction2 = bond2.shortest_vector_relative_to(parent)
                    if bond2.children[0].target != target_object:
                        direction2 *= -1
                    axis = numpy.cross(direction2, direction1)
                    if numpy.linalg.norm(axis) < 1e-8:
                        axis = random_orthonormal(direction1)
                    angle = compute_angle(direction1, direction2)
                    rotation = Rotation.from_properties(angle, axis, False)
                    primitive.Transform(new, rotation)
                else:
                    bond1 = None
                # Tranlsation
                pos_old = new.children[1].get_frame_relative_to(parent).t
                pos_new = gl_object.transformation.t
                translation = Translation(pos_new - pos_old)
                primitive.Transform(new, translation)
                if bond1 != None:
                    # bond length
                    old_length = numpy.linalg.norm(direction1)
                    new_length = bonds.get_length(
                        new.children[1].number,
                        bond1.get_neighbor(gl_object).number)
                    translation = Translation(-direction1 / old_length *
                                              (new_length - old_length))
                    primitive.Transform(new, translation)

            # let the references to the replaced object point to the new object
            for reference in gl_object.references[::-1]:
                try:
                    primitive.SetTarget(reference, target_object)
                except primitive.PrimitiveError:
                    primitive.Delete(reference.parent)
            # delete the replaced object
            primitive.Delete(gl_object)
            if (self.current_object == "Fragment"):
                # Delete the first atom in the fragment
                primitive.Delete(new.children[0])
                # Unframe the fragment
                UnframeAbsolute = context.application.plugins.get_action(
                    "UnframeAbsolute")
                UnframeAbsolute([new])

    def connect(self, gl_object1, gl_object2):
        try:
            new = context.application.plugins.get_node(
                self.vector_store.get_value(
                    self.cb_vector.get_active_iter(),
                    0))(targets=[gl_object1, gl_object2])
        except TargetError:
            return

        if (self.vector_store.get_value(self.cb_vector.get_active_iter(),
                                        0) == "Bond"):
            new.set_bond_type(
                self.bondtype_store.get_value(
                    self.cb_bondtype.get_active_iter(), 1))

        primitive.Add(new,
                      common_parent([gl_object1.parent, gl_object2.parent]))

    def erase_at(self, p, parent):
        for node in context.application.main.drawing_area.iter_hits(
            (p[0] - 2, p[1] - 2, p[0] + 2, p[1] + 2)):
            try:
                match = (node is not None and node != parent
                         and node.is_indirect_child_of(parent)
                         and node.model == context.application.model
                         and (not self.cb_erase_filter.get_active()
                              or self.erase_filter(node)))
            except Exception:
                raise UserError(
                    "An exception occured while evaluating the erase filter expression."
                )
            if match:
                primitive.Delete(node)

    def tool_draw(self, p1, p2):
        drawing_area = context.application.main.drawing_area
        r1 = drawing_area.screen_to_camera(p1)
        r2 = drawing_area.screen_to_camera(p2)
        context.application.vis_backend.tool("line", r1, r2)

    def tool_special(self, p1, p2):
        pass

    def move_special(self, gl_object1, gl_object2, p1, p2):
        pass

    def click_special(self, gl_object):
        pass
示例#8
0
class SketchOptions(GladeWrapper):

    edit_erase_filter = FieldsDialogSimple(
        "Edit the Erase filter",
        fields.faulty.Expression(
            label_text="Erase filter expression",
            attribute_name="erase_filter",
            show_popup=True,
            history_name="filter",
        ),
        ((gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL), (gtk.STOCK_OK, gtk.RESPONSE_OK))
    )

    def __init__(self):
        GladeWrapper.__init__(self, "plugins/molecular/gui.glade", "wi_sketch", "window")
        self.window.hide()
        self.init_callbacks(self.__class__)
        self.init_proxies([
            "cb_object",
            "cb_vector",
            "cb_erase_filter",
            "bu_edit_erase_filter",
            "la_current",
            "bu_set_atom",
            "cb_bondtype",
            "hbox_atoms",
            "hbox_quickpicks",
            "hbox_fragments",
            "la_fragment",
            "cb_fragment"
        ])

        self.erase_filter = Expression("True")
        #Initialize atom number - this can be changed anytime with the edit_atom_number dialog
        self.atom_number = 6;

        # Initialize the GUI
        #  1) common parts of the comboboxes
        def render_icon(column, cell, model, iter):
            if model.get_value(iter, 0) == "Fragment":
                cell.set_property(
                "pixbuf",
                context.application.plugins.get_node("Atom").icon
                )
            else:
                cell.set_property(
                    "pixbuf",
                    context.application.plugins.get_node(model.get_value(iter, 0)).icon
                )

        #  2) fill the objects combo box
        self.object_store = gtk.ListStore(str)
        self.object_store.append(["Atom"])
        self.object_store.append(["Fragment"])
        self.object_store.append(["Point"])
        self.object_store.append(["Sphere"])
        self.object_store.append(["Box"])
        self.cb_object.set_model(self.object_store)

        renderer_pixbuf = gtk.CellRendererPixbuf()
        self.cb_object.pack_start(renderer_pixbuf, expand=False)
        self.cb_object.set_cell_data_func(renderer_pixbuf, render_icon)
        renderer_text = gtk.CellRendererText()
        self.cb_object.pack_start(renderer_text, expand=True)
        self.cb_object.add_attribute(renderer_text, "text", 0)

        self.cb_object.set_active(0)

        #  3) fill the vector combo box
        self.vector_store = gtk.ListStore(str)
        self.vector_store.append(["Bond"])
        self.vector_store.append(["Arrow"])
        self.vector_store.append(["Spring"])
        self.cb_vector.set_model(self.vector_store)

        renderer_pixbuf = gtk.CellRendererPixbuf()
        self.cb_vector.pack_start(renderer_pixbuf, expand=False)
        self.cb_vector.set_cell_data_func(renderer_pixbuf, render_icon)
        renderer_text = gtk.CellRendererText()
        self.cb_vector.pack_start(renderer_text, expand=True)
        self.cb_vector.add_attribute(renderer_text, "text", 0)

        self.cb_vector.set_active(0)

        # 4) fill the bond type combo box
        self.bondtype_store = gtk.ListStore(str,int)
        self.bondtype_store.append(["Single bond",BOND_SINGLE])
        self.bondtype_store.append(["Double bond",BOND_DOUBLE])
        self.bondtype_store.append(["Triple bond",BOND_TRIPLE])
        self.bondtype_store.append(["Hybrid bond",BOND_HYBRID])
        self.bondtype_store.append(["Hydrogen bond",BOND_HYDROGEN])
        self.cb_bondtype.set_model(self.bondtype_store)

        #no icons like the others, just text here
        renderer_text = gtk.CellRendererText()
        self.cb_bondtype.pack_start(renderer_text, expand=True)
        self.cb_bondtype.add_attribute(renderer_text, "text", 0)

        self.cb_bondtype.set_active(0)

        # register quick pick config setting
        config = context.application.configuration
        config.register_setting(
            "sketch_quickpicks",
            [6,7,8,9,10,11],
            DialogFieldInfo("Sketch tool", (0,2), fields.faulty.IntegerList(
                label_text="Quick pick atoms (applies after restart)",
                attribute_name="sketch_quickpicks",
            )),
        )

        # 5)create the "quick pick" atom buttons
        for index in xrange(len(config.sketch_quickpicks)):
            atomnumber = config.sketch_quickpicks[index]
            bu_element = gtk.Button("")
            bu_element.set_label("%s" % periodic[atomnumber].symbol)
            bu_element.connect("clicked", self.on_bu_element_clicked, index)
            # add to hbox
            self.hbox_quickpicks.pack_start(bu_element)
            bu_element.show()

        # 6)fill the fragment combo box with filenames from share/fragments
        fragment_dir = context.get_share_filename('fragments')
        self.fragment_store = gtk.ListStore(str)
        for filename in sorted(os.listdir(fragment_dir)):
            # Ignore subfolders and files with extension other than cml
            if os.path.isdir (os.path.join (fragment_dir, filename)) or filename[-3:] != 'cml':
                continue
            self.fragment_store.append([filename[:-4]])
        self.cb_fragment.set_model(self.fragment_store)

        renderer_text = gtk.CellRendererText()
        self.cb_fragment.pack_start(renderer_text, expand=True)
        self.cb_fragment.add_attribute(renderer_text, "text", 0)
        self.cb_fragment.set_active(0)

    @property
    def current_object(self):
       return self.object_store.get_value(self.cb_object.get_active_iter(),0)

    @property
    def current_fragment(self):
       return self.fragment_store.get_value(self.cb_fragment.get_active_iter(), 0)

    def on_window_delete_event(self, window, event):
        self.window.hide()
        return True

    def on_bu_edit_erase_filter_clicked(self, button):
        self.edit_erase_filter.run(self)

    def on_bu_set_atom_clicked(self, button):
        self.edit_atom_number = FieldsDialogSimple(
            "Select atom number",
            fields.edit.Element(attribute_name="atom_number"),
            ((gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL), (gtk.STOCK_OK, gtk.RESPONSE_OK))
        )
        self.edit_atom_number.run(self)
        atom_symbol = periodic[self.atom_number].symbol
        self.la_current.set_label("Current: %s " % str(atom_symbol))

    def on_cb_object_changed(self, combo):
        self.hbox_atoms.hide()
        self.la_current.hide()
        self.hbox_fragments.hide()
        if(self.current_object=="Atom"):
            self.hbox_atoms.show()
            self.la_current.show()
        if(self.current_object=="Fragment"):
            self.cb_fragment.show()
            self.hbox_fragments.show()

    def on_bu_element_clicked(self, widget, index):
        self.atom_number = context.application.configuration.sketch_quickpicks[index]
        atom_symbol = periodic[self.atom_number].symbol
        self.la_current.set_label("Current: %s" % str(atom_symbol))

    def on_cb_vector_changed(self, combo):
        # When the selected object is an atom, show the extra button.
        if (self.vector_store.get_value(self.cb_vector.get_active_iter(),0)=="Bond"):
            self.cb_bondtype.show()
        else:
            self.cb_bondtype.hide()

    def get_new(self, position):
        if self.current_object == "Fragment":
            filename = context.get_share_filename('fragments/%s.cml' % self.current_fragment)
            molecule = load_cml(filename)[0]

            Frame = context.application.plugins.get_node("Frame")
            new = Frame(name=self.current_fragment)

            load_filter = context.application.plugins.get_load_filter('cml')
            load_filter.load_molecule(new, molecule)
        else:
            NewClass = context.application.plugins.get_node(self.current_object)
            new = NewClass()
            if self.current_object == "Atom":
                new.set_number(self.atom_number)
                new.set_name(periodic[self.atom_number].symbol)

        translation = Translation(position)
        primitive.Transform(new, translation)
        return new

    def add_new(self, position, parent):
        new = self.get_new(position)

        if self.current_object == "Fragment":
            result = new.children[1]
            primitive.Add(new, parent)
            UnframeAbsolute = context.application.plugins.get_action("UnframeAbsolute")
            UnframeAbsolute([new])
            #return result
        else:
            primitive.Add(new, parent)
            return new

    def replace(self, gl_object):
        if not gl_object.get_fixed():
            new = self.get_new(gl_object.transformation.t)

            # select a target object, i.e. the one the will be connected with
            # the bonds/vectors/... of the replaced object
            if(self.current_object == "Fragment"):
                # fragments are inserted as frames
                # take atom with index 1 as target
                target_object = new.children[1]
            else:
                target_object = new
            # check if all connections to the replaced object are applicable
            # to the new object. if not, then do not perform the replacement
            # and return early.
            for reference in gl_object.references[::-1]:
                if not reference.check_target(target_object):
                    return
            # add the new object
            parent = gl_object.parent
            primitive.Add(new, parent)

            if(self.current_object == "Fragment"):
                # Fix the rotation and translation of the molecular fragment.
                # Rotation
                Bond = context.application.plugins.get_node("Bond")
                if len(gl_object.references) == 1 and isinstance(gl_object.references[0].parent, Bond):
                    bond1 = gl_object.references[0].parent
                    direction1 = bond1.shortest_vector_relative_to(parent)
                    if bond1.children[0].target != gl_object:
                        direction1 *= -1
                    bond2 = new.children[0].references[0].parent
                    direction2 = bond2.shortest_vector_relative_to(parent)
                    if bond2.children[0].target != target_object:
                        direction2 *= -1
                    axis = numpy.cross(direction2, direction1)
                    if numpy.linalg.norm(axis) < 1e-8:
                        axis = random_orthonormal(direction1)
                    angle = compute_angle(direction1, direction2)
                    rotation = Rotation.from_properties(angle, axis, False)
                    primitive.Transform(new, rotation)
                else:
                    bond1 = None
                # Tranlsation
                pos_old = new.children[1].get_frame_relative_to(parent).t
                pos_new = gl_object.transformation.t
                translation = Translation(pos_new - pos_old)
                primitive.Transform(new, translation)
                if bond1 != None:
                    # bond length
                    old_length = numpy.linalg.norm(direction1)
                    new_length = bonds.get_length(new.children[1].number, bond1.get_neighbor(gl_object).number)
                    translation = Translation(-direction1/old_length*(new_length-old_length))
                    primitive.Transform(new, translation)

            # let the references to the replaced object point to the new object
            for reference in gl_object.references[::-1]:
                try:
                    primitive.SetTarget(reference, target_object)
                except primitive.PrimitiveError:
                    primitive.Delete(reference.parent)
            # delete the replaced object
            primitive.Delete(gl_object)
            if(self.current_object == "Fragment"):
                # Delete the first atom in the fragment
                primitive.Delete(new.children[0])
                # Unframe the fragment
                UnframeAbsolute = context.application.plugins.get_action("UnframeAbsolute")
                UnframeAbsolute([new])

    def connect(self, gl_object1, gl_object2):
        try:
            new = context.application.plugins.get_node(
                self.vector_store.get_value(self.cb_vector.get_active_iter(), 0)
            )(targets=[gl_object1, gl_object2])
        except TargetError:
            return

        if(self.vector_store.get_value(self.cb_vector.get_active_iter(), 0)=="Bond"):
            new.set_bond_type(self.bondtype_store.get_value(self.cb_bondtype.get_active_iter(),1))

        primitive.Add(new, common_parent([gl_object1.parent, gl_object2.parent]))

    def erase_at(self, p, parent):
        for node in context.application.main.drawing_area.iter_hits((p[0]-2, p[1]-2, p[0]+2, p[1]+2)):
            try:
                match = (
                    node is not None and node != parent and
                    node.is_indirect_child_of(parent) and
                    node.model == context.application.model and (
                        not self.cb_erase_filter.get_active() or
                        self.erase_filter(node)
                    )
                )
            except Exception:
                raise UserError("An exception occured while evaluating the erase filter expression.")
            if match:
                primitive.Delete(node)

    def tool_draw(self, p1, p2):
        drawing_area = context.application.main.drawing_area
        r1 = drawing_area.screen_to_camera(p1)
        r2 = drawing_area.screen_to_camera(p2)
        context.application.vis_backend.tool("line", r1, r2)

    def tool_special(self, p1, p2):
        pass

    def move_special(self, gl_object1, gl_object2, p1, p2):
        pass

    def click_special(self, gl_object):
        pass
示例#9
0
class SketchOptions(GladeWrapper):

    edit_erase_filter = FieldsDialogSimple(
        "Edit the Erase filter",
        fields.faulty.Expression(
            label_text="Erase filter expression",
            attribute_name="erase_filter",
            show_popup=True,
            history_name="filter",
        ),
        ((gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL), (gtk.STOCK_OK, gtk.RESPONSE_OK))
    )

    def __init__(self):
        GladeWrapper.__init__(self, "plugins/molecular/gui.glade", "wi_sketch", "window")
        self.window.hide()
        self.init_callbacks(self.__class__)
        self.init_proxies([
            "cb_object",
            "cb_vector",
            "cb_erase_filter",
            "bu_edit_erase_filter",
            "la_current",
            "bu_set_atom",
            "cb_bondtype",
            "hbox_atoms",
            "hbox_quickpicks",
            "hbox_fragments",
            "la_fragment",
            "cb_fragment"
        ])

        self.erase_filter = Expression("True")
        #Initialize atom number - this can be changed anytime with the edit_atom_number dialog
        self.atom_number = 6;

        # Initialize the GUI
        #  1) common parts of the comboboxes
        def render_icon(column, cell, model, iter):
            cell.set_property(
                "pixbuf",
                context.application.plugins.get_node(model.get_value(iter, 0)).icon
            )

        #  2) fill the objects combo box
        self.object_store = gtk.ListStore(str)
        self.object_store.append(["Atom"])
        self.object_store.append(["Fragment"])
        self.object_store.append(["Point"])
        self.object_store.append(["Sphere"])
        self.object_store.append(["Box"])
        self.cb_object.set_model(self.object_store)

        renderer_pixbuf = gtk.CellRendererPixbuf()
        self.cb_object.pack_start(renderer_pixbuf, expand=False)
        self.cb_object.set_cell_data_func(renderer_pixbuf, render_icon)
        renderer_text = gtk.CellRendererText()
        self.cb_object.pack_start(renderer_text, expand=True)
        self.cb_object.add_attribute(renderer_text, "text", 0)

        self.cb_object.set_active(0)

        #  3) fill the vector combo box
        self.vector_store = gtk.ListStore(str)
        self.vector_store.append(["Bond"])
        self.vector_store.append(["Arrow"])
        self.vector_store.append(["Spring"])
        self.cb_vector.set_model(self.vector_store)

        renderer_pixbuf = gtk.CellRendererPixbuf()
        self.cb_vector.pack_start(renderer_pixbuf, expand=False)
        self.cb_vector.set_cell_data_func(renderer_pixbuf, render_icon)
        renderer_text = gtk.CellRendererText()
        self.cb_vector.pack_start(renderer_text, expand=True)
        self.cb_vector.add_attribute(renderer_text, "text", 0)

        self.cb_vector.set_active(0)

        # 4) fill the bond type combo box
        self.bondtype_store = gtk.ListStore(str,int)
        self.bondtype_store.append(["Single bond",BOND_SINGLE])
        self.bondtype_store.append(["Double bond",BOND_DOUBLE])
        self.bondtype_store.append(["Triple bond",BOND_TRIPLE])
        self.bondtype_store.append(["Hybrid bond",BOND_HYBRID])
        self.bondtype_store.append(["Hydrogen bond",BOND_HYDROGEN])
        self.cb_bondtype.set_model(self.bondtype_store)

        #no icons like the others, just text here
        renderer_text = gtk.CellRendererText()
        self.cb_bondtype.pack_start(renderer_text, expand=True)
        self.cb_bondtype.add_attribute(renderer_text, "text", 0)

        self.cb_bondtype.set_active(0)

        # register quick pick config setting
        config = context.application.configuration
        config.register_setting(
            "sketch_quickpicks",
            [6,7,8,9,10,11],
        )
        #WOUTER I messed up this setting and now Zeobuilder keeps crashing cause it was set to empty
        config.sketch_quickpicks = [6,7,8,9,10,11]

        # 5)create the "quick pick" atom buttons
        for index in xrange(len(config.sketch_quickpicks)):
            atomnumber = config.sketch_quickpicks[index]
            bu_element = gtk.Button("")
            bu_element.set_label("%s" % periodic[atomnumber].symbol)
            bu_element.connect("clicked", self.on_bu_element_clicked, index)
            # add to hbox
            self.hbox_quickpicks.pack_start(bu_element)
            bu_element.show()

        # 6)fill the fragment combo box with filenames from share/fragments
        fragmentdir = context.get_share_filename('fragments')
        self.fragment_store = gtk.ListStore(str)
        for filename in os.listdir (fragmentdir):
            # Ignore subfolders and files with extension other than cml
            if os.path.isdir (os.path.join (fragmentdir, filename)) or filename[-3:] != 'cml':
                continue
            self.fragment_store.append([filename[:-4]])
        self.cb_fragment.set_model(self.fragment_store)

        renderer_text = gtk.CellRendererText()
        self.cb_fragment.pack_start(renderer_text, expand=True)
        self.cb_fragment.add_attribute(renderer_text, "text", 0)
        self.cb_fragment.set_active(0)

        self.doing_fragment = False #at init we do atoms :)

    def on_window_delete_event(self, window, event):
        return True

    def on_bu_edit_erase_filter_clicked(self, button):
        self.edit_erase_filter.run(self)

    def on_bu_set_atom_clicked(self, button):
        self.edit_atom_number = FieldsDialogSimple(
            "Select atom number",
            fields.edit.Element(attribute_name="atom_number"),
            ((gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL), (gtk.STOCK_OK, gtk.RESPONSE_OK))
        )
        self.edit_atom_number.run(self)
        atom_symbol = periodic[self.atom_number].symbol
        self.la_current.set_label("Current: %s " % str(atom_symbol))

    def on_cb_object_changed(self, combo):
        # When the selected object is an atom, show the extra button.
        self.hbox_atoms.hide()
        self.la_current.hide()
        self.hbox_fragments.hide()
        self.doing_fragment = False
        if(self.object_store.get_value(self.cb_object.get_active_iter(),0)=="Atom"):
            self.hbox_atoms.show()
            self.la_current.show()
        if(self.object_store.get_value(self.cb_object.get_active_iter(),0)=="Fragment"):
            self.doing_fragment = True
            self.cb_fragment.show()
            #self.la_fragment.show()
            self.hbox_fragments.show()

    def on_bu_element_clicked(self, widget, index):
        self.atom_number = context.application.configuration.sketch_quickpicks[index]
        atom_symbol = periodic[self.atom_number].symbol
        self.la_current.set_label("Current: %s" % str(atom_symbol))

    def on_cb_vector_changed(self, combo):
        # When the selected object is an atom, show the extra button.
        if (self.vector_store.get_value(self.cb_vector.get_active_iter(),0)=="Bond"):
            self.cb_bondtype.show()
        else:
            self.cb_bondtype.hide()

    def get_new(self,position):
        object_type = self.object_store.get_value(self.cb_object.get_active_iter(), 0)
        print object_type
        if object_type == "Fragment":   #if it's a 'Fragment', set fragment name to current item in combo box
            fragment = context.application.plugins.get_node("Fragment")(self.fragment_store.get_value(self.cb_fragment.get_active_iter(),0))
            fragment.set_name(self.fragment_store.get_value(self.cb_fragment.get_active_iter(),0))
            new = fragment.get_in_frame(position)

        else:
            new = context.application.plugins.get_node(object_type)()

            if object_type == "Atom":  #if it's an 'Atom', set the atom number to the current atom number?
                new.set_number(self.atom_number)
                new.set_name(periodic[self.atom_number].symbol)

            new.transformation.t[:] = position

        return new

    def add_new(self, position, parent):
        print "position:"
        print position

        new = self.get_new(position)
        print new
        primitive.Add(new, parent)


    def replace(self, gl_object):
        print gl_object

        if not gl_object.get_fixed():
            if self.doing_fragment:
                print "replacing atom with fragment"
                position = gl_object.transformation.t
                parent = gl_object.parent
                new = self.get_new(position)
                new.addToModel(position,parent)
                primitive.Delete(gl_object)
            else:
                new = self.get_new(gl_object.transformation.t)
                # old way: new.transformation.t[:] =
                for reference in gl_object.references[::-1]:
                    if not reference.check_target(new):
                        return
                parent = gl_object.parent
                primitive.Add(new, parent)
                for reference in gl_object.references[::-1]:
                    reference.set_target(new)
                primitive.Delete(gl_object)

    def connect(self, gl_object1, gl_object2):
        print "connecting:"
        print gl_object1,gl_object2
        try:
            new = context.application.plugins.get_node(
                self.vector_store.get_value(self.cb_vector.get_active_iter(), 0)
            )(targets=[gl_object1, gl_object2])
        except TargetError:
            return

        if(self.vector_store.get_value(self.cb_vector.get_active_iter(), 0)=="Bond"):
            new.set_bond_type(self.bondtype_store.get_value(self.cb_bondtype.get_active_iter(),1))

        primitive.Add(new, common_parent([gl_object1.parent, gl_object2.parent]))

    def erase_at(self, p, parent):
        for node in context.application.main.drawing_area.yield_hits((p[0]-2, p[1]-2, p[0]+2, p[1]+2)):
            try:
                match = (
                    node is not None and node != parent and
                    node.is_indirect_child_of(parent) and
                    node.model == context.application.model and (
                        not self.cb_erase_filter.get_active() or
                        self.erase_filter(node)
                    )
                )
            except Exception:
                raise UserError("An exception occured while evaluating the erase filter expression.")
            if match:
                primitive.Delete(node)

    def tool_draw(self, p1, p2):
        drawing_area = context.application.main.drawing_area
        r1 = drawing_area.screen_to_camera(p1)
        r2 = drawing_area.screen_to_camera(p2)
        context.application.vis_backend.tool("line", r1, r2)

    def tool_special(self, p1, p2):
        pass

    def move_special(self, gl_object1, gl_object2, p1, p2):
        pass

    def click_special(self, gl_object):
        pass