summaryrefslogtreecommitdiff
path: root/cad/src/dna/commands/MakeCrossovers/MakeCrossovers_PropertyManager.py
blob: 401a07c8df3f7488a29209643c501e4333911c6f (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
# Copyright 2008 Nanorex, Inc.  See LICENSE file for details. 
"""
MakeCrossovers_PropertyManager.py

@author: Ninad
@copyright: 2008 Nanorex, Inc.  See LICENSE file for details.
@version:$Id$

History:

TODO:
See MakeCrossovers_Command for details. 
"""
import foundation.env as env


from PM.PM_SelectionListWidget import PM_SelectionListWidget
from PM.PM_GroupBox import PM_GroupBox
from PM.PM_PushButton import PM_PushButton
from PM.PM_Constants     import PM_DONE_BUTTON
from PM.PM_Constants     import PM_WHATS_THIS_BUTTON
from PM.PM_CheckBox      import PM_CheckBox


from PyQt4.Qt import SIGNAL, Qt

from utilities.prefs_constants import assignColorToBrokenDnaStrands_prefs_key
from utilities.prefs_constants import makeCrossoversCommand_crossoverSearch_bet_given_segments_only_prefs_key
from dna.commands.MakeCrossovers.ListWidgetItems_PM_Mixin import ListWidgetItems_PM_Mixin
from utilities import debug_flags
from utilities.debug import print_compact_stack
from utilities.Comparison import same_vals
from widgets.prefs_widgets import connect_checkbox_with_boolean_pref
from ne1_ui.WhatsThisText_for_PropertyManagers import whatsThis_MakeCrossoversPropertyManager
from utilities.Log import orangemsg

from command_support.Command_PropertyManager import Command_PropertyManager

_superclass = Command_PropertyManager
class MakeCrossovers_PropertyManager( Command_PropertyManager, 
                                      ListWidgetItems_PM_Mixin ):
    """
    The MakeCrossovers_PropertyManager class provides a Property Manager 
    for the B{Make Crossovers} command on the flyout toolbar in the 
    Build > Dna mode. 

    @ivar title: The title that appears in the property manager header.
    @type title: str

    @ivar pmName: The name of this property manager. This is used to set
                  the name of the PM_Dialog object via setObjectName().
    @type name: str

    @ivar iconPath: The relative path to the PNG file that contains a
                    22 x 22 icon image that appears in the PM header.
    @type iconPath: str
    """

    title         =  "Make Crossovers"
    pmName        =  title
    iconPath      =  "ui/actions/Command Toolbar/BuildDna/MakeCrossovers.png"


    def __init__( self, command):
        """
        Constructor for the property manager.
        """

            

        self.isAlreadyConnected = False
        self.isAlreadyDisconnected = False

        self._previous_model_changed_params = None

        _superclass.__init__(self, command)

        
        self.showTopRowButtons( PM_DONE_BUTTON | \
                                PM_WHATS_THIS_BUTTON)
        
        self.defaultLogMessage = """Pairs of white cylinders (if any) in the 
        3D workspace indicate potential crossover sites. Clicking on such a 
         cylinder pair will make that crossover."""

        self.updateMessage(self.defaultLogMessage)
        
      
    def connect_or_disconnect_signals(self, isConnect):
        """
        Connect or disconnect widget signals sent to their slot methods.
        This can be overridden in subclasses. By default it does nothing.
        @param isConnect: If True the widget will send the signals to the slot 
                          method. 
        @type  isConnect: boolean
        """
        #TODO: This is a temporary fix for a bug. When you invoke a 
        #temporary mode  entering such a temporary mode keeps the signals of 
        #PM from the previous mode connected (
        #but while exiting that temporary mode and reentering the 
        #previous mode, it atucally reconnects the signal! This gives rise to 
        #lots  of bugs. This needs more general fix in Temporary mode API. 
        # -- Ninad 2008-01-09 (similar comment exists in MovePropertyManager.py

        if isConnect and self.isAlreadyConnected:
            if debug_flags.atom_debug:
                print_compact_stack("warning: attempt to connect widgets"\
                                    "in this PM that are already connected." )
            return 

        if not isConnect and self.isAlreadyDisconnected:
            if debug_flags.atom_debug:
                print_compact_stack("warning: attempt to disconnect widgets"\
                                    "in this PM that are already disconnected.")
            return

        self.isAlreadyConnected = isConnect
        self.isAlreadyDisconnected = not isConnect

        if isConnect:
            change_connect = self.win.connect     
        else:
            change_connect = self.win.disconnect 

        self.segmentListWidget.connect_or_disconnect_signals(isConnect) 
        change_connect(self.addSegmentsToolButton, 
                       SIGNAL("toggled(bool)"), 
                       self.activateAddSegmentsTool)
        change_connect(self.removeSegmentsToolButton, 
                       SIGNAL("toggled(bool)"), 
                       self.activateRemoveSegmentsTool)

        change_connect(self.makeCrossoverPushButton,
                       SIGNAL("clicked()"),
                       self._makeAllCrossovers)
        
        connect_checkbox_with_boolean_pref(
             self.crossoversBetGivenSegmentsOnly_checkBox,
            makeCrossoversCommand_crossoverSearch_bet_given_segments_only_prefs_key)
        
                                                          
    def show(self):
        """
        Overrides the superclass method
        @see: self._deactivateAddRemoveSegmentsTool
        """
        _superclass.show(self)             
        self._deactivateAddRemoveSegmentsTool()
     
    

    def _makeAllCrossovers(self):
        self.command.makeAllCrossovers()


    def _addGroupBoxes( self ):
        """
        Add the Property Manager group boxes.
        """        
        self._pmGroupBox1 = PM_GroupBox( self, title = "Segments for Crossover Search" )
        self._loadGroupBox1( self._pmGroupBox1 )


    def _loadGroupBox1(self, pmGroupBox):
        """
        load widgets in groupbox1
        """

        self._loadSegmentListWidget(pmGroupBox)  
        self.crossoversBetGivenSegmentsOnly_checkBox = PM_CheckBox( 
            pmGroupBox,
            text         = "Between above segments only",
            widgetColumn  = 0,
            setAsDefault = True,
            spanWidth = True,
            )
        
        #If this preferece value is True, the search algotithm will search for
        #the potential crossover sites only *between* the segments in the 
        #segment list widget (thus ignoring other segments not in that list)
        if env.prefs[makeCrossoversCommand_crossoverSearch_bet_given_segments_only_prefs_key]:
            self.crossoversBetGivenSegmentsOnly_checkBox.setCheckState(Qt.Checked) 
        else:
            self.crossoversBetGivenSegmentsOnly_checkBox.setCheckState(Qt.Unchecked)
        
        self.makeCrossoverPushButton = PM_PushButton( 
            pmGroupBox,
            label     = "",
            text      = "Make All Crossovers",
            spanWidth = True )

    def _update_UI_do_updates(self):
        """
        @see: Command_PropertyManager._update_UI_do_updates()
        @see: DnaSegment_EditCommand.command_update_UI()
        @see: DnaSegment_EditCommand.hasResizableStructure()
        @see: self._current_model_changed_params()
        """

        currentParams = self._current_model_changed_params()
        
        #Optimization. Return from the model_changed method if the 
        #params are the same. 
        if same_vals(currentParams, self._previous_model_changed_params):
            return 
        

        number_of_segments, \
                          crossover_search_pref_junk,\
                          bool_valid_segmentList_junk = currentParams
                
        #update the self._previous_model_changed_params with this new param set.
        self._previous_model_changed_params = currentParams       
        #Ensures that there are only PAM3 DNA segments in the commad's tructure 
        #list (command._structList. Call this before updating the list widgets!
        self.command.ensureValidSegmentList()
        self.updateListWidgets()   
        self.command.updateCrossoverSites()

    def _current_model_changed_params(self):
        """
        Returns a tuple containing the parameters that will be compared
        against the previously stored parameters. This provides a quick test
        to determine whether to do more things in self.model_changed()
        @see: self.model_changed() which calls this
        @see: self._previous_model_changed_params attr. 
        """
        params = None

        if self.command:
            #update the list first. 
            self.command.updateSegmentList()
            bool_valid_segmentList = self.command.ensureValidSegmentList()
            number_of_segments = len(self.command.getSegmentList()) 
            crossover_search_pref = \
                                  env.prefs[makeCrossoversCommand_crossoverSearch_bet_given_segments_only_prefs_key]
            params = (number_of_segments, 
                      crossover_search_pref, 
                      bool_valid_segmentList
                  )

        return params

    def _addWhatsThisText( self ):
        """
        What's This text for widgets in the DNA Property Manager.  
        """
        whatsThis_MakeCrossoversPropertyManager(self)

    def _addToolTipText(self):
        """
        Tool Tip text for widgets in the DNA Property Manager.  
        """
        pass