summaryrefslogtreecommitdiff
path: root/cad/src/PM/PM_ElementChooser.py
blob: 032effa9c6409e35ecf6b53531f265e1237cb416 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# Copyright 2006-2007 Nanorex, Inc.  See LICENSE file for details.
"""
PM_ElementChooser.py

@author: Mark Sims
@version: $Id$
@copyright: 2006-2007 Nanorex, Inc.  All rights reserved.

History:

mark 2007-08-03: Created.
"""

from PM.PM_MolecularModelingKit import PM_MolecularModelingKit

from PyQt4.Qt import SIGNAL, QSpacerItem, QSizePolicy
from PM.PM_ToolButtonGrid import PM_ToolButtonGrid

# Elements button list to create elements tool button group.
# Format:
# - button type
# - buttonId (element number),
# - buttonText (element symbol),
# - iconPath
# - tooltip (element name)
# - shortcut
# - column
# - row

ELEMENTS_BUTTON_LIST = [ \
    ( "QToolButton", 1,  "H", "", "Hydrogen (H)",  "H", 4, 0   ),
    ( "QToolButton", 2, "He", "", "Helium",  None,  5, 0   ),
    ( "QToolButton", 5,  "B", "", "Boron (B)",   "B",   0, 1   ),
    ( "QToolButton", 6,  "C", "", "Carbon (C)",  "C",   1, 1   ),
    ( "QToolButton", 7,  "N", "", "Nitrogen (N)", "N",  2, 1   ),
    ( "QToolButton", 8,  "O", "", "Oxygen (O)",  "O",   3, 1   ),
    ( "QToolButton", 9,  "F", "", "Fluorine (F)",  "F", 4, 1   ),
    ( "QToolButton", 10, "Ne", "", "Neon",  None,   5, 1   ),
    ( "QToolButton", 13, "Al", "", "Aluminum (A)", "A", 0, 2   ),
    ( "QToolButton", 14, "Si", "", "Silicon (Q)",  "Q",  1, 2   ),
    ( "QToolButton", 15,  "P", "", "Phosphorus (P)", "P", 2, 2   ),
    ( "QToolButton", 16,  "S", "", "Sulfur (S)",  "S",   3, 2   ),
    ( "QToolButton", 17, "Cl", "", "Chlorine (L)", "L",  4, 2   ),
    ( "QToolButton", 18, "Ar", "", "Argon",   None,  5, 2   ),
    ( "QToolButton", 32, "Ge", "", "Germanium", "G",  1, 3   ),
    ( "QToolButton", 33, "As", "", "Arsenic",  None,   2, 3   ),
    ( "QToolButton", 34, "Se", "", "Selenium", None,  3, 3   ),
    ( "QToolButton", 35, "Br", "", "Bromine" , None,   4, 3   ),
    ( "QToolButton", 36, "Kr", "", "Krypton",  None,  5, 3   )
]

ELEMENT_ATOM_TYPES = { \
    6: ("sp3", "sp2", "sp"                  ),
    7: ("sp3", "sp2", "sp", "sp2(graphitic)"),
    8: ("sp3", "sp2", "sp2(-)", "sp2(-.5)"  ),
   15: ("sp3", "sp3(p)"             ),
   16: ("sp3", "sp2"                        )
}

ATOM_TYPES = ("sp3", "sp2", "sp", "sp2(graphitic)", "sp3(p)", "sp2(-)", "sp2(-.5)")

# Atom types (hybrids) button list to create atom types tool button group.
# Format:
# - buttonId (hybrid number)
# - buttonText (hybrid symbol)
# - iconPath
# - tooltip (full hybrid name)
# - shortcut
# - column
# - row

ATOM_TYPES_BUTTON_LIST = [ \
    ( "QToolButton", 0, "sp3", "", "sp3", None, 0, 0 ),
    ( "QToolButton", 1, "sp2", "", "sp2", None, 1, 0 ),
    ( "QToolButton", 2, "sp",  "", "sp",  None, 2, 0 ),
    ( "QToolButton", 3, "sp2(graphitic)", "ui/actions/Properties Manager/N_graphitic.png",
      "Graphitic", None, 3, 0 ),
    ( "QToolButton", 4, "sp3(p)",  "", "sp3(phosphate)",  None, 4, 0 ),
    ( "QToolButton", 5, "sp2(-)",  "", "sp2(-)",  None, 5, 0 ),
    ( "QToolButton", 6, "sp2(-.5)",  "", "sp2(-.5)",  None, 6, 0 ),
]

# How to add a new hybridization of an element to the UI:

# First, create the hybridization in model/elements_data.py.  See the
# comments there for how to do this.

# Next, add the hybridization to ELEMENT_ATOM_TYPES above.  The
# indices are the element numbers in the ELEMENTS_BUTTON_LIST.

# Next, make sure the hybridization appears in the ATOM_TYPES list and
# the ATOM_TYPES_BUTTON_LIST.  There are two indices that should
# increment by one for each line.  You may wish to add an icon graphic
# if the string does not fit entirely within the button.

class PM_ElementChooser( PM_MolecularModelingKit ):
    """
    The PM_ElementChooser widget provides an Element Chooser widget,
    contained in its own group box, for a Property Manager dialog.

    A PM_ElementChooser is a selection widget that displays all elements,
    including their atom types (atomic hybrids), supported in NE1. Methods
    are provided to set and get the selected element and atom type
    (e.g., L{setElement()}, L{getElement()}, L{getElementNumber()} and
    L{getElementSymbolAndAtomType()}).

    @cvar element: The current element.
    @type element: Elem

    @cvar atomType: The current atom type of the current element.
    @type atomType: str

    @see: B{elements.py}
    """

    def __init__(self,
                 parentWidget,
                 parentPropMgr   = None,
                 title           = "",
                 element         = "Carbon",
                 elementViewer   =  None
                 ):
        """
        Appends a PM_ElementChooser widget to the bottom of I{parentWidget},
        a Property Manager dialog. (or as a sub groupbox for Atom Chooser
        GroupBox.)

        @param parentWidget: The parent PM_Dialog or PM_groupBox containing this
                             widget.
        @type  parentWidget: PM_Dialog or PM_GroupBox

        @param parentPropMgr: The parent Property Manager
        @type  parentPropMgr: PM_Dialog or None

        @param title: The button title on the group box containing the
                      Element Chooser.
        @type  title: str

        @param element: The initially selected element. It can be either an
                        element symbol or name.
        @type  element: str
        """

        PM_MolecularModelingKit.__init__( self,
                                          parentWidget,
                                          parentPropMgr,
                                          title,
                                          element,
                                          elementViewer)


    def _addGroupBoxes(self):
        """
        Add various groupboxes present inside the ElementChooser groupbox
        """
        self._addElementsGroupBox(self)
        self._addAtomTypesGroupBox(self)

    def _addAtomTypesGroupBox(self, inPmGroupBox):
        """
        Creates a row of atom type buttons (i.e. sp3, sp2, sp and graphitic).

        @param inPmGroupBox: The parent group box to contain the atom type
                             buttons.
        @type  inPmGroupBox: PM_GroupBox
        """
        self._atomTypesButtonGroup = \
            PM_ToolButtonGrid( inPmGroupBox,
                               buttonList = self.getAtomTypesButtonList(),
                               label      = "Atomic hybrids:",
                               checkedId  = 0,
                               setAsDefault = True )
        #Increase the button width for atom hybrids so that
        # button texts such as sp3(p), sp2(-), sp2(-.5) fit.
        # This change can be removed once we have icons
        # for the buttons with long text -- Ninad 2008-09-04
        self._atomTypesButtonGroup.setButtonSize(width = 44)

        # Horizontal spacer to keep buttons grouped close together.
        _hSpacer = QSpacerItem( 1, 32,
                                QSizePolicy.Expanding,
                                QSizePolicy.Fixed )

        self._atomTypesButtonGroup.gridLayout.addItem( _hSpacer, 0, 4, 1, 1 )



        self.connect( self._atomTypesButtonGroup.buttonGroup,
                      SIGNAL("buttonClicked(int)"),
                      self._setAtomType )

        self._updateAtomTypesButtons()

    def _updateAtomTypesButtons(self):
        """
        Updates the hybrid buttons based on the currently selected
        element button.
        """
        currentElementNumber = self.getElementNumber()

        if ELEMENT_ATOM_TYPES.has_key(currentElementNumber):
            elementAtomTypes = ELEMENT_ATOM_TYPES[currentElementNumber]
        else:
            # Selected element has no hybrids.
            elementAtomTypes = []
            self.atomType = ""

        for atomType in ATOM_TYPES:
            button = self._atomTypesButtonGroup.getButtonByText(atomType)
            if atomType in elementAtomTypes:
                button.show()
                if atomType == elementAtomTypes[0]:
                    # Select the first atomType button.
                    button.setChecked(True)
                    self.atomType = atomType
            else:
                button.hide()

        self._updateAtomTypesTitle()

    def _updateAtomTypesTitle(self):
        """
        Updates the title for the Atom Types group box.
        """
        title = "Atomic Hybrids for " + self.element.name + ":"
        self._atomTypesButtonGroup.setTitle(title)

    def _setAtomType(self, atomTypeIndex):
        """
        Set the current atom type.

        @param atomTypeIndex: The atom type index, where:
                              0 = sp3,
                              1 = sp2,
                              2 = sp,
                              3 = sp2(graphitic)
        @type  atomTypeIndex: int

        @note: Calling this method does not update the atom type buttons.
        """
        self.atomType = ATOM_TYPES[atomTypeIndex]
        self.updateElementViewer()

    def getElementsButtonList(self):
        """
        Return the list of buttons in the Element chooser.
        @return: List containing information about the element tool buttons
        @rtype:  list
        """
        return ELEMENTS_BUTTON_LIST

    def getAtomTypesButtonList(self):
        """
        Return the list of buttons for the various atom types (hybrids) of the
        selected atom in the    Element  chooser.
        @return: List containing information about the toolbuttons for
                 the atom types (hybrids) of the selected atom  in the element
                 chooser.
        @rtype:  list

        """
        return ATOM_TYPES_BUTTON_LIST