def stateAfter(self): try: return self._qt_event.stateAfter() except: print_compact_stack( "bug: event.stateAfter() not available in Qt4, returning -1: ") return -1 ### BUG; need to fix in some better way [070811]
def get_unit_length(phi, psi): """ Calculate a length of single amino acid in particular secondary conformation. """ # All unit length values obtained via measurements by me. # Fixes bug 2959. --Mark 2008-12-23 if phi == -57.0 and psi == -47.0: unit_length = 1.5 # Alpha helix elif phi == -135.0 and psi == 135.0: unit_length = 3.4 # Beta strand elif phi == -55.0 and psi == -70.0: unit_length = 1.05 # Pi helix elif phi == -49.0 and psi == -26.0: unit_length = 1.95 # 3_10 helix elif phi == -75.0 and psi == 150.0: unit_length = 3.14 # Polyproline-II helix elif phi == -180.0 and psi == 180.0: unit_length = 3.6 # Fully extended else: # User chose "Custom" conformation option in the Insert Peptide PM # which lets the user set any phi-psi angle values. # We need a formula to estimate the proper unit_length given the # conformational angles phi and psi. It would also be a good idea # to check these values to confirm they are an allowed combination. # For more info, do a google search for "Ramachandran plot". # For now, I'm setting the unit length to 1.5. --Mark 2008-12-23 unit_length = 1.5 msg = "\nUser selected custom conformational angles: "\ "phi=%.2f, psi=%.2f.\nSetting unit_length=%.2f\n" % \ (phi, psi, unit_length) print_compact_stack(msg) return unit_length
def careful_widget_setter(self, value): # Note: for some time we used self.widget_setter rather than this method, # by mistake, and it apparently worked fine. We'll still use this method # as a precaution; also it might be truly needed if the widget quantizes # the value, unless the widget refrains from sending signals when # programmatically set. [bruce 070815] if self.debug: print "\n_changes__debug_print: %r setting %r to %r using %r" % \ ( self, self.widget, value, self.widget_setter ) self.disconnect() # avoid possible recursion try: self.widget_setter(value) except: print_compact_traceback("bug: ignoring exception setting value of %r to %r: " % (self, value)) print_compact_stack(" fyi: prior exception came from: ") self.destroy() #bruce 080930 # this seems to be safe, but debug output implies it fails to stop formula # from continuing to call setter! but that seems unlikely... nevermind for now. # Review: do we want subsequent use of self # to be silently ok, smaller message, or error? If this destroy worked # then I think it should be silently ok, but might not be now, # depending on how refs to self continue to be used. pass else: self.connect() ### WARNING: .connect is slow, since it runs our Python code to set up an undo wrapper # around the slot! We should revise this to tell Qt to block the signals instead. # [We can use: bool QObject::blockSignals ( bool block ) ==> returns prior value of signalsBlocked, # now used in a helper function setValue_with_signals_blocked] # This will matter for performance when this is used for state which changes during a drag. # Note: avoiding the slot call is needed not only for recursion, but to avoid the # Undo checkpoint in the wrapper. # [bruce comments 071015; see also bug 2564 in other code] return
def getStrands(self): """ Returns a list of strands inside a DnaGroup object @return: A list containing all the strand objects within self. @rtype: list @see: B{BuildDna_PropertyManager.updateStrandListWidget()} @see: B{BuildDna_PropertyManager._currentSelectionParams} """ #TO BE REVISED. As of 2008-01-17, it uses isinstance check for #Chunk and some additional things to find out a list of strands inside # a DnaGroup -- Ninad 2008-01-17 if self.assy is None: #This is to avoid possible bugs if group gets deleted. But print #traceback so that we know about this bug. This could happen due to #insufficient command sequencer stack. Temporary fix for bug 2699 print_compact_stack("bug: self.assy is None for DnaGroup %s."%self) return () strandList = [] def filterStrands(node): if isinstance(node, self.assy.DnaStrand) and not node.isEmpty(): strandList.append(node) elif isinstance(node, self.assy.Chunk) and node.isStrandChunk(): if node.parent_node_of_class(self.assy.DnaStrand) is None: strandList.append(node) self.apply2all(filterStrands) return strandList
def getAxisChunks(self): """ Returns a list of Axis chunks inside a DnaGroup object @return: A list containing all the axis chunks within self. @rtype: list """ if self.assy is None: #This is to avoid possible bugs if group gets deleted. But print #traceback so that we know about this bug. This could happen due to #insufficient command sequencer stack. Temporary fix for bug 2699 print_compact_stack("bug: self.assy is None for DnaGroup %s."%self) return () #TO BE REVISED. It uses isinstance check for #Chunk and some additional things to find out a list of strands inside # a DnaGroup -- Ninad 2008-02-02 axisChunkList = [] def filterAxisChunks(node): if isinstance(node, self.assy.Chunk) and node.isAxisChunk(): axisChunkList.append(node) self.apply2all(filterAxisChunks) return axisChunkList
def _e_eval(self, env, ipath): assert env the_expr = self._e_args[0] res = the_expr._e_eval(env, ipath) print_compact_stack("debug_evals_of_Expr(%r) evals it to %r at: " % (the_expr, res)) # this works return res
def contentsDragEnterEvent( self, event ): # the dup ones can't be told apart by any method i know of except lack of move/drop/leave. print_compact_stack("dragEnterEvent stack (fyi): ") # nothing on stack except this code-line and app.exec_() [not even a call of this method] try: event.bruce_saw_me except: event.bruce_saw_me = 1 else: event.bruce_saw_me = event.bruce_saw_me + 1 self.oldevent = event ###@@@ ok = QTextDrag.canDecode(event) or QImageDrag.canDecode( event) or QUriDrag.canDecode(event) print "drag enter %r, pos.x = %r, ok = %r (determines our acceptance)" % ( event, event.pos().x(), ok) print "event.bruce_saw_me", event.bruce_saw_me ## try doing this later: event.accept(ok) canvas = self.canvas() i = QCanvasText(canvas) i.setText("drag action type %r, %r" % (event.action(), time.asctime())) self.dragevent_item = i i.show( ) # would removing this fix the dup enter? no, but it makes the text invisible! self.dragevent_item_move_to_event(event) event.accept( ok) # try doing this here, does it remove that duplicate enter?
def get_image_path(name, print_errors = True): """ Return the full path given an image/icon path name. @param name: The image path name provided by the user. The path should start with 'ui/' directory inside the src directory. @type name: str @param print_errors: whether to report errors for missing icon files when atom_debug is set. True by default. @type print_errors: boolean @return: full path of the image. @rtype: str """ root, ext = os.path.splitext(name) if not ext: if name: # 'name' can be an empty string. See docstring for details. msg = "Warning: No '.png' extension passed to get_image_path for [%s]. " \ "\nPlease add the .png suffix in the source code to remove this warning.\n" % name print_compact_stack(msg) name = name + '.png' iconPath = os.path.join(image_directory(), name) iconPath = os.path.normpath(iconPath) if not os.path.exists(iconPath): if debug_flags.atom_debug and print_errors: print "icon path %s doesn't exist." % (iconPath,) return iconPath
def _get_mode(self): """ Old code is trying to get self.mode, which it might want for either the Command API (self.currentCommand) or GraphicsMode API (self.graphicsMode). We don't know which it wants. (TODO, if worthwhile: deduce which, print a map of code line vs which one of these to change it to.) This can only be supported if the currentCommand is also old, so that it handles both APIs. Print a warning if not (or assert 0?), and return the currentCommand in either case (but don't wrap it with an API enforcer). """ # Note: when we think there are not many uses of this left, # we'll make every use print_compact_stack to aid in finding the rest # and replacing them with one or the other of currentCommand and # graphicsMode. Or we might print a once-per-line-number message when # it's called... ### TODO # # hmm, this is true now! [bruce 071011] print_compact_stack("fyi: this old code still accesses glpane.mode " \ "by that deprecated name: ") raw_currentCommand = self._raw_currentCommand graphicsMode = self._raw_currentCommand.graphicsMode if raw_currentCommand is not graphicsMode: print "old code warning: %r is not %r and we don't know " \ "which one %r.mode should return" % \ (raw_currentCommand, graphicsMode, self) # TODO: print_compact_stack? return raw_currentCommand
def getAxisChunks(self): """ Returns a list of Axis chunks inside a DnaGroup object @return: A list containing all the axis chunks within self. @rtype: list """ if self.assy is None: #This is to avoid possible bugs if group gets deleted. But print #traceback so that we know about this bug. This could happen due to #insufficient command sequencer stack. Temporary fix for bug 2699 print_compact_stack("bug: self.assy is None for DnaGroup %s." % self) return () #TO BE REVISED. It uses isinstance check for #Chunk and some additional things to find out a list of strands inside # a DnaGroup -- Ninad 2008-02-02 axisChunkList = [] def filterAxisChunks(node): if isinstance(node, self.assy.Chunk) and node.isAxisChunk(): axisChunkList.append(node) self.apply2all(filterAxisChunks) return axisChunkList
def get_image_path(name, print_errors=True): """ Return the full path given an image/icon path name. @param name: The image path name provided by the user. The path should start with 'ui/' directory inside the src directory. @type name: str @param print_errors: whether to report errors for missing icon files when atom_debug is set. True by default. @type print_errors: boolean @return: full path of the image. @rtype: str """ root, ext = os.path.splitext(name) if not ext: if name: # 'name' can be an empty string. See docstring for details. msg = "Warning: No '.png' extension passed to get_image_path for [%s]. " \ "\nPlease add the .png suffix in the source code to remove this warning.\n" % name print_compact_stack(msg) name = name + '.png' iconPath = os.path.join(image_directory(), name) iconPath = os.path.normpath(iconPath) if not os.path.exists(iconPath): if debug_flags.atom_debug and print_errors: print "icon path %s doesn't exist." % (iconPath, ) return iconPath
def _leftDown_preparation_for_dragging(self, objectUnderMouse, event): """ Handle left down event. Preparation for rotation and/or selection This method is called inside of self.leftDown. @param event: The mouse left down event. @type event: QMouseEvent instance @see: self.leftDown @see: self.leftDragRotation Overrides _superclass._leftDown_preparation_for_dragging """ _superclass._leftDown_preparation_for_dragging(self, objectUnderMouse, event) self.o.SaveMouse(event) self.picking = True self.dragdist = 0.0 # delta for constrained rotations. self.rotDelta = 0 if self.rotateOption == "ROTATEDEFAULT": self.o.trackball.start(self.o.MousePos[0], self.o.MousePos[1]) else: if self.rotateOption == "ROTATEX": ma = V(1, 0, 0) # X Axis self.axis = "X" elif self.rotateOption == "ROTATEY": ma = V(0, 1, 0) # Y Axis self.axis = "Y" elif self.rotateOption == "ROTATEZ": ma = V(0, 0, 1) # Z Axis self.axis = "Z" elif self.rotateOption == "ROT_TRANS_ALONG_AXIS": # The method 'self._leftDown_preparation_for_dragging should # never be reached if self.rotateOption is 'ROT_TRANS_ALONG_AXIS' # If this code is reached, it indicates a bug. So fail gracefully # by calling self.leftADown() if debug_flags.atom_debug: print_compact_stack( "bug: _leftDown_preparation_for_dragging" " called for rotate option" "'ROT_TRANS_ALONG_AXIS'" ) self.leftADown(objectUnderMouse, event) return else: print "Move_Command: Error - unknown rotateOption value =", self.rotateOption return ma = norm(V(dot(ma, self.o.right), dot(ma, self.o.up))) # When in the front view, right = 1,0,0 and up = 0,1,0, so ma will # be computed as 0,0.This creates a special case problem when the # user wants to constrain rotation around the Z axis because Zmat # will be zero. So we have to test for this case (ma = 0,0) and # fix ma to -1,0. This was needed to fix bug 537. Mark 050420 if ma[0] == 0.0 and ma[1] == 0.0: ma = [-1.0, 0.0] self.Zmat = A([ma, [-ma[1], ma[0]]]) self.leftDownType = "ROTATE" return
def connect_or_disconnect_signals(self, isConnect): """ Connect or disconnect widget signals sent to their slot methods. @param isConnect: If True the widget will send the signals to the slot method. @type isConnect: boolean @see: L{BuildAtoms_Command.connect_or_disconnect_signals} where this is called """ 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.w.connect else: change_connect = self.w.disconnect change_connect(self.atomChooserComboBox, SIGNAL("currentIndexChanged(int)"), self._updateAtomChooserGroupBoxes) change_connect(self.selectionFilterCheckBox, SIGNAL("stateChanged(int)"), self.set_selection_filter) change_connect(self.showSelectedAtomInfoCheckBox, SIGNAL("stateChanged(int)"), self.toggle_selectedAtomPosGroupBox) change_connect(self.xCoordOfSelectedAtom, SIGNAL("valueChanged(double)"), self._moveSelectedAtom) change_connect(self.yCoordOfSelectedAtom, SIGNAL("valueChanged(double)"), self._moveSelectedAtom) change_connect(self.zCoordOfSelectedAtom, SIGNAL("valueChanged(double)"), self._moveSelectedAtom) connect_checkbox_with_boolean_pref(self.waterCheckBox, buildModeWaterEnabled_prefs_key) connect_checkbox_with_boolean_pref(self.highlightingCheckBox, buildModeHighlightingEnabled_prefs_key)
def _master_model_updater(warn_if_needed=False): """ This should be called at the end of every user event which might have changed anything in any loaded model which defers some updates to this function. This can also be called at the beginning of user events, such as redraws or saves, which want to protect themselves from event-processors which should have called this at the end, but forgot to. Those callers should pass warn_if_needed = True, to cause a debug-only warning to be emitted if the call was necessary. (This function is designed to be very fast when called more times than necessary.) This should also be called before taking Undo checkpoints, to make sure they correspond to legal structures, and so this function's side effects (and the effect of assy.changed, done by this function as of 060126(?)) are treated as part of the same undoable operation as the changes that required them to be made. As of 060127 this is done by those checkpoints calling update_parts, which indirectly calls this function. In practice, as of 071115, we have not yet tried to put in calls to this function at the end of user event handlers, so we rely on the other calls mentioned above, and none of them pass warn_if_needed. """ # 0. Don't run while mmp file is being read [###FIX, use one global flag] if 1: # KLUGE; the changedicts and updater should really be per-assy... # this is a temporary scheme for detecting the unanticipated # running of this in the middle of loading an mmp file, and for # preventing errors from that, # but it only works for the main assy -- not e.g. for a partlib # assy. I don't yet know if this is needed. [bruce 080117] #update 080319: just in case, I'm fixing the mmpread code # to also use the global assy to store this. kluge_main_assy = env.mainwindow().assy if not kluge_main_assy.assy_valid: global_model_changedicts.status_of_last_dna_updater_run = LAST_RUN_DIDNT_HAPPEN msg = "deferring _master_model_updater(warn_if_needed = %r) " \ "since not %r.assy_valid" % (warn_if_needed, kluge_main_assy) print_compact_stack(msg + ": ") # soon change to print... return pass env.history.emit_all_deferred_summary_messages() #bruce 080212 (3 places) _run_dna_updater() env.history.emit_all_deferred_summary_messages() _run_bond_updater(warn_if_needed=warn_if_needed) env.history.emit_all_deferred_summary_messages() _autodelete_empty_groups(kluge_main_assy) env.history.emit_all_deferred_summary_messages() return # from _master_model_updater
def _master_model_updater( warn_if_needed = False ): """ This should be called at the end of every user event which might have changed anything in any loaded model which defers some updates to this function. This can also be called at the beginning of user events, such as redraws or saves, which want to protect themselves from event-processors which should have called this at the end, but forgot to. Those callers should pass warn_if_needed = True, to cause a debug-only warning to be emitted if the call was necessary. (This function is designed to be very fast when called more times than necessary.) This should also be called before taking Undo checkpoints, to make sure they correspond to legal structures, and so this function's side effects (and the effect of assy.changed, done by this function as of 060126(?)) are treated as part of the same undoable operation as the changes that required them to be made. As of 060127 this is done by those checkpoints calling update_parts, which indirectly calls this function. In practice, as of 071115, we have not yet tried to put in calls to this function at the end of user event handlers, so we rely on the other calls mentioned above, and none of them pass warn_if_needed. """ # 0. Don't run while mmp file is being read [###FIX, use one global flag] if 1: # KLUGE; the changedicts and updater should really be per-assy... # this is a temporary scheme for detecting the unanticipated # running of this in the middle of loading an mmp file, and for # preventing errors from that, # but it only works for the main assy -- not e.g. for a partlib # assy. I don't yet know if this is needed. [bruce 080117] #update 080319: just in case, I'm fixing the mmpread code # to also use the global assy to store this. kluge_main_assy = env.mainwindow().assy if not kluge_main_assy.assy_valid: global_model_changedicts.status_of_last_dna_updater_run = LAST_RUN_DIDNT_HAPPEN msg = "deferring _master_model_updater(warn_if_needed = %r) " \ "since not %r.assy_valid" % (warn_if_needed, kluge_main_assy) print_compact_stack(msg + ": ") # soon change to print... return pass env.history.emit_all_deferred_summary_messages() #bruce 080212 (3 places) _run_dna_updater() env.history.emit_all_deferred_summary_messages() _run_bond_updater( warn_if_needed = warn_if_needed) env.history.emit_all_deferred_summary_messages() _autodelete_empty_groups(kluge_main_assy) env.history.emit_all_deferred_summary_messages() return # from _master_model_updater
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 """ #@see: BuildDna_PropertyManager.connect_or_disconnect_signals #for a comment about these flags. 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 change_connect(self.loadSequenceButton, SIGNAL("clicked()"), self.openStrandSequenceFile) change_connect(self.saveSequenceButton, SIGNAL("clicked()"), self.saveStrandSequence) change_connect(self.baseDirectionChoiceComboBox, SIGNAL('currentIndexChanged(int)'), self._reverseSequence) change_connect(self.sequenceTextEdit, SIGNAL("textChanged()"), self.sequenceChanged) change_connect(self.sequenceTextEdit, SIGNAL("cursorPositionChanged()"), self.cursorPosChanged) change_connect(self.findLineEdit, SIGNAL("textEdited(const QString&)"), self.findLineEdit_textEdited) change_connect(self.findNextToolButton, SIGNAL("clicked()"), self.findNext) change_connect(self.findPreviousToolButton, SIGNAL("clicked()"), self.findPrevious) change_connect(self.replacePushButton, SIGNAL("clicked()"), self.replace)
def ascii(self): try: return filter_key( self._qt_event.ascii()) #k (does filter_key matter here?) except: print_compact_stack( "bug: event.ascii() not available in Qt4, returning -1: ") return -1 ### BUG: need to fix in some better way [070811]
def _e_eval_lval(self, env, ipath): # 070119 also print _e_eval_lval calls [maybe untested] assert env the_expr = self._e_args[0] res = the_expr._e_eval_lval(env, ipath) print_compact_stack( "debug_evals_of_Expr(%r) eval-lvals it to %r at: " % (the_expr, res) ) # k does this ever happen? return res
def _i_grabarg(self, attr, argpos, dflt_expr, _arglist=False): """ #doc, especially the special values for some of these args """ debug = False ## _arglist if debug: print_compact_stack( "_i_grabarg called with ( self %r, attr %r, argpos %r, dflt_expr %r, _arglist %r): " % \ (self, attr, argpos, dflt_expr, _arglist) ) print " and the data it grabs from is _e_kws = %r, _e_args = %r" % ( self._e_kws, self._e_args) #k below should not _e_eval or canon_expr without review -- should return an arg expr or dflt expr, not its value # (tho for now it also can return None on error -- probably causing bugs in callers) assert is_pure_expr( dflt_expr), "_i_grabarg dflt_expr should be an expr, not %r" % ( dflt_expr, ) #061105 - or use canon_expr? assert self._e_is_instance if not self._e_has_args: print "warning: possible bug: not self._e_has_args in _i_grabarg%r in %r" % ( (attr, argpos), self) assert attr is None or isinstance(attr, str) assert argpos is None or (isinstance(argpos, int) and argpos >= 0) assert _arglist in (False, True) external_flag, res0 = self._i_grabarg_0(attr, argpos, dflt_expr, _arglist=_arglist) if external_flag: # flag and this condition added 061116 443p to try to fix '_self dflt_expr bug'; seems to work in testexpr_9a; # I'm guessing type_expr doesn't have a similar bug since it's applied outside this call. #k index = attr or argpos #k I guess, for now [070105 stub -- not always equal to index in ipath, esp for ArgOrOption] env_for_arg = self.env_for_arg(index) # revised 070105 if debug070120: print "grabarg %r in %r is wrapping %r with %r containing _self %r" % \ ((attr, argpos), self, res0, env_for_arg, getattr(env_for_arg,'_self','<none>')) res = lexenv_Expr( env_for_arg, res0 ) ##k lexenv_Expr is guess, 061110 late, seems confirmed; env_for_args 061114 #e possible good optim: use self.env instead, unless res0 contains a use of _this; # or we could get a similar effect (slower when this runs, but better when the arg instance is used) by simplifying res, # so that only the used parts of the env provided by lexenv_Expr remained (better due to other effects of simplify) else: res = res0 #k (I *think* it's right to not even add self.env here, tho I recall I had lexenv_Expr(self.env, res0) at first -- # because the self.env was for changing _self, which we want to avoid here, and the _for_args is for supporting _this.) # Note: there was a '_self dflt_expr bug' in the above, until i added 'if external_flag:'] [diagnosed & fixed 061116]: # it's wrong for the parts of this expr res0 that came from our class, i.e. dflt_expr and type_expr. # That is hard to fix here, since they're mixed into other parts of the same expr, # but nontrivial to fix where we supply them, since when we do, the specific env needed is not known -- # we'd have to save it up or push it here, then access it there (or just say "escape from the most local lexenv_Expr" # if that's well-defined & possible & safe -- maybe the most local one of a certain type is better). # We also want whatever we do to be robust, and to not make it too hard to someday simplify the expr. # So why not fix it by wrapping only the parts that actually come from _e_args and _e_kws, right when we access them? # I guess that is done inside _i_grabarg_0... ok, it's easy to add external_flag to its retval to tell us what to do. [done] ###k ARE THERE any other accesses of _e_args or _e_kws that need similar protection? Worry about this if I add # support for iterating specific args (tho that might just end up calling _i_grabarg and being fine). if debug: print "_i_grabarg returns %r" % (res, ) return res
def _reverse_neighbor_baseatoms(self): self.neighbor_baseatoms = list(self.neighbor_baseatoms) self.neighbor_baseatoms.reverse() if DEBUG_NEIGHBOR_BASEATOMS: if self.neighbor_baseatoms[0] != -1 or \ self.neighbor_baseatoms[1] != -1: msg = "reversed %r.neighbor_baseatoms to get %r" % (self, self.neighbor_baseatoms) print_compact_stack( "\n" + msg + ": ") return
def _modifyStructure_NEW_SEGMENT_RESIZE(self, params): #@ NOT FIXED """ This resizes without recreating whole nanotube Overrides EditCommand._modifystructure. @attention: is not implemented. """ #@TODO: - rename this method from _modifyStructure_NEW_SEGMENT_RESIZE #to self._modifyStructure, after more testing #This method is used for debug prefence: #'Nanotube Segment: resize without recreating whole nanotube' #see also self.modifyStructure_NEW_SEGMENT_RESIZE assert self.struct from utilities.debug import print_compact_stack print_compact_stack("_modifyStructure_NEW_SEGMENT_RESIZE() not fixed!" ) print "Params =", params self.nanotube = params #@ length_diff = self._determine_how_to_change_length() #@ if length_diff == 0: print_compact_stack("BUG: length_diff is always ZERO." ) return elif length_diff > 0: print "Nanotube longer by ", length_diff, ", angstroms." else: print "Nanotube shorter by ", length_diff, ", angstroms." return if numberOfBasePairsToAddOrRemove != 0: #@@@@ Not reached. resizeEnd_final_position = self._get_resizeEnd_final_position( ladderEndAxisAtom, abs(numberOfBasePairsToAddOrRemove), nanotubeRise ) self.nanotube.modify(self.struct, length_diff, ladderEndAxisAtom.posn(), resizeEnd_final_position) #Find new end points of structure parameters after modification #and set these values in the propMgr. new_end1 , new_end2 = self.struct.nanotube.getEndPoints() #@ params_to_set_in_propMgr = (new_end1, new_end2) #TODO: Need to set these params in the PM #and then self.previousParams = params_to_set_in_propMgr self.previousParams = params return
def _do_whycode_reenable( reasons_list_val, whycode): """ [private helper function for maintaining whycode,whymsg lists] """ res = filter( lambda (code, msg): code != whycode , reasons_list_val ) # zap items with same whycode if len(res) == len(reasons_list_val) and env.debug(): print_compact_stack("debug fyi: redundant call of _do_whycode_reenable, whycode %r, remaining reasons %r" % \ ( whycode, res ) ) return res
def __init__(self): print_compact_stack( "warning: fake_Part_drawing_frame is being instantiated: " ) # done in superclass: self.repeated_bonds_dict = None # This is necessary to remove any chance of self surviving # for more than one draw of one object (since using an actual # dict then would make bonds sometimes fail to be drawn). # Client code must tolerate this value. return
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 """ 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 change_connect(self.loadSequenceButton, SIGNAL("clicked()"), self._open_FASTA_File) change_connect(self.saveSequenceButton, SIGNAL("clicked()"), self._savePeptideSequence) change_connect(self.sequenceTextEdit, SIGNAL("textChanged()"), self._sequenceChanged) change_connect(self.sequenceTextEdit, SIGNAL("editingFinished()"), self._assignPeptideSequence) change_connect(self.sequenceTextEdit, SIGNAL("cursorPositionChanged()"), self._cursorPosChanged) change_connect(self.findLineEdit, SIGNAL("textEdited(const QString&)"), self.findLineEdit_textEdited) change_connect(self.findNextToolButton, SIGNAL("clicked()"), self.findNext) change_connect(self.findPreviousToolButton, SIGNAL("clicked()"), self.findPrevious) change_connect(self.replacePushButton, SIGNAL("clicked()"), self.replace) return
def rotateAboutPoint(self): """ Rotates the selected entities along the specified vector, about the specified pivot point (pivot point it the starting point of the drawn vector. """ if len(self.mouseClickPoints) != self.mouseClickLimit: print_compact_stack("Rotate about point bug: mouseclick points != mouseclicklimit: ") return pivotPoint = self.mouseClickPoints[0] ref_vec_endPoint = self.mouseClickPoints[1] rot_vec_endPoint = self.mouseClickPoints[2] reference_vec = norm(ref_vec_endPoint - pivotPoint) lineVector = norm(rot_vec_endPoint - pivotPoint) #lineVector = endPoint - startPoint quat1 = Q(lineVector, reference_vec) #DEBUG Disabled temporarily . will not be used if dot(lineVector, reference_vec) < 0: theta = math.pi - quat1.angle else: theta = quat1.angle #TEST_DEBUG-- Works fine theta = quat1.angle rot_axis = cross(lineVector, reference_vec) if dot(lineVector, reference_vec) < 0: rot_axis = - rot_axis cross_prod_1 = norm(cross(reference_vec, rot_axis)) cross_prod_2 = norm(cross(lineVector, rot_axis)) if dot(cross_prod_1, cross_prod_2) < 0: quat2 = Q(rot_axis, theta) else: quat2 = Q(rot_axis, - theta) movables = self.graphicsMode.getMovablesForLeftDragging() self.assy.rotateSpecifiedMovables( quat2, movables = movables, commonCenter = pivotPoint) self.glpane.gl_update() return
def insertSeparator(self): """ This method overrides QToolBar's method. It does nothing since the normal behavior will screw things up. @note: If you need this method, please code it! Mark 2008-02-29. """ print_compact_stack("insertSeparator() not supported. " \ "Use addSeparator() instead or implement insertSeparator()") return
def _e_eval_lval( self, env, ipath): #070119 also print _e_eval_lval calls [maybe untested] assert env the_expr = self._e_args[0] res = the_expr._e_eval_lval(env, ipath) print_compact_stack( "debug_evals_of_Expr(%r) eval-lvals it to %r at: " % (the_expr, res)) #k does this ever happen? return res
def atom_ok(self, atom): # note: this can include Pl atoms in PAM5, # but the wrapper class filters them out of # the atom list it stores. if not atom.molecule: print_compact_stack( "bug: strand_bond_chain_analyzer skipping %r with no .molecule: " % atom) return False if atom._dna_updater__error: return False return atom.element.role == 'strand' and not atom.molecule.in_a_valid_ladder()
def _do_whycode_disable( reasons_list_val, whycode, whymsg): """ [private helper function for maintaining whycode,whymsg lists] """ res = filter( lambda (code, msg): code != whycode , reasons_list_val ) # zap items with same whycode if len(res) < len(reasons_list_val) and env.debug(): print_compact_stack("debug fyi: redundant call of _do_whycode_disable, whycode %r msg %r, preserved reasons %r" % \ ( whycode, whymsg, res ) ) res.append( (whycode, whymsg) ) # put the changed one at the end (#k good??) return res
def _do_whycode_reenable(reasons_list_val, whycode): """ [private helper function for maintaining whycode,whymsg lists] """ res = filter(lambda (code, msg): code != whycode, reasons_list_val) # zap items with same whycode if len(res) == len(reasons_list_val) and env.debug(): print_compact_stack("debug fyi: redundant call of _do_whycode_reenable, whycode %r, remaining reasons %r" % \ ( whycode, res ) ) return res
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 if self.sequenceEditor: self.sequenceEditor.connect_or_disconnect_signals(isConnect) _superclass.connect_or_disconnect_signals(self, isConnect) change_connect(self.disableStructHighlightingCheckbox, SIGNAL('stateChanged(int)'), self.change_struct_highlightPolicy) change_connect(self.showCursorTextCheckBox, SIGNAL('stateChanged(int)'), self._update_state_of_cursorTextGroupBox) change_connect(self.nameLineEdit, SIGNAL("editingFinished()"), self._nameChanged) return
def rotateAboutPoint(self): """ Rotates the selected entities along the specified vector, about the specified pivot point (pivot point it the starting point of the drawn vector. """ if len(self.mouseClickPoints) != self.mouseClickLimit: print_compact_stack( "Rotate about point bug: mouseclick points != mouseclicklimit: " ) return pivotPoint = self.mouseClickPoints[0] ref_vec_endPoint = self.mouseClickPoints[1] rot_vec_endPoint = self.mouseClickPoints[2] reference_vec = norm(ref_vec_endPoint - pivotPoint) lineVector = norm(rot_vec_endPoint - pivotPoint) #lineVector = endPoint - startPoint quat1 = Q(lineVector, reference_vec) #DEBUG Disabled temporarily . will not be used if dot(lineVector, reference_vec) < 0: theta = math.pi - quat1.angle else: theta = quat1.angle #TEST_DEBUG-- Works fine theta = quat1.angle rot_axis = cross(lineVector, reference_vec) if dot(lineVector, reference_vec) < 0: rot_axis = -rot_axis cross_prod_1 = norm(cross(reference_vec, rot_axis)) cross_prod_2 = norm(cross(lineVector, rot_axis)) if dot(cross_prod_1, cross_prod_2) < 0: quat2 = Q(rot_axis, theta) else: quat2 = Q(rot_axis, -theta) movables = self.graphicsMode.getMovablesForLeftDragging() self.assy.rotateSpecifiedMovables(quat2, movables=movables, commonCenter=pivotPoint) self.glpane.gl_update() return
def _loadServerList(self): """Return the list of servers available, otherwise, create a default one. """ if os.path.isfile(self.serverFile): try: file = open(self.serverFile, "rb") return pickle.load(file) except: print_compact_stack("Unpickle exception.") return [SimServer()] else: return [SimServer()]
def connect_or_disconnect_signals(self, isConnect): """ Connect or disconnect widget signals sent to their slot methods. @param isConnect: If True the widget will send the signals to the slot method. @type isConnect: boolean @see: L{BuildAtoms_Command.connect_or_disconnect_signals} where this is called """ 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.w.connect else: change_connect = self.w.disconnect change_connect(self.atomChooserComboBox, SIGNAL("currentIndexChanged(int)"), self._updateAtomChooserGroupBoxes) change_connect(self.selectionFilterCheckBox, SIGNAL("stateChanged(int)"), self.set_selection_filter) change_connect(self.showSelectedAtomInfoCheckBox, SIGNAL("stateChanged(int)"), self.toggle_selectedAtomPosGroupBox) change_connect(self.xCoordOfSelectedAtom, SIGNAL("valueChanged(double)"), self._moveSelectedAtom) change_connect(self.yCoordOfSelectedAtom, SIGNAL("valueChanged(double)"), self._moveSelectedAtom) change_connect(self.zCoordOfSelectedAtom, SIGNAL("valueChanged(double)"), self._moveSelectedAtom) connect_checkbox_with_boolean_pref(self.waterCheckBox, buildModeWaterEnabled_prefs_key) connect_checkbox_with_boolean_pref( self.highlightingCheckBox, buildModeHighlightingEnabled_prefs_key)
def _do_whycode_disable(reasons_list_val, whycode, whymsg): """ [private helper function for maintaining whycode,whymsg lists] """ res = filter(lambda (code, msg): code != whycode, reasons_list_val) # zap items with same whycode if len(res) < len(reasons_list_val) and env.debug(): print_compact_stack("debug fyi: redundant call of _do_whycode_disable, whycode %r msg %r, preserved reasons %r" % \ ( whycode, whymsg, res ) ) res.append((whycode, whymsg)) # put the changed one at the end (#k good??) return res
def _set_mode(self, new_mode): """ Old code is trying to set self.mode. Assume it wants to set _raw_currentCommand, and do that, after complaining. Soon, this will be illegal. """ # TODO: a search for 'self.mode =' reveals no remaining calls, # so make it an assert 0 soon print_compact_stack("bug: old code is trying to set glpane.mode directly: ") self._raw_currentCommand = new_mode return
def atom_ok(self, atom): if not atom.molecule: # I've seen this after Undo, presumably since it's buggy [080122] # (To repeat: make a duplex, delete some atoms, Undo, Redo. # [bruce 080226 comment]) print_compact_stack( "bug: axis_bond_chain_analyzer skipping %r " \ "with no .molecule (killed = %r, _f_assy = %r): " \ % (atom, atom.killed(), atom._f_assy) ) return False if atom._dna_updater__error: return False return atom.element.role == 'axis' and not atom.molecule.in_a_valid_ladder()
def _set_mode(self, new_mode): """ Old code is trying to set self.mode. Assume it wants to set _raw_currentCommand, and do that, after complaining. Soon, this will be illegal. """ # TODO: a search for 'self.mode =' reveals no remaining calls, # so make it an assert 0 soon print_compact_stack( "bug: old code is trying to set glpane.mode directly: ") self._raw_currentCommand = new_mode return
def _postProcess(self, baseList): """ Final tweaks on the DNA chunk, including: - Transmute Ax3 atoms on each end into Ae3. - Adjust open bond singlets. @param baseList: List of basepair chunks that make up the duplex. @type baseList: list @note: baseList must contain at least two base-pair chunks. """ if len(baseList) < 1: print_compact_stack("bug? (ignoring) DnaDuplex._postProcess called but "\ "baseList is empty. Maybe dna_updater was "\ "run?: ") return start_basepair_atoms = baseList[0].atoms.values() end_basepair_atoms = baseList[-1].atoms.values() Ax_caps = filter( lambda atom: atom.element.symbol in ('Ax3'), start_basepair_atoms) Ax_caps += filter( lambda atom: atom.element.symbol in ('Ax3'), end_basepair_atoms) # Transmute Ax3 caps to Ae3 atoms. # Note: this leaves two "killed singlets" hanging around, # one from each Ax3 cap. # # REVIEW: is it safe to simply not do this when dna_updater_is_enabled()? # [bruce 080320 question] for atom in Ax_caps: atom.Transmute(Element_Ae3) # X_List will contain 6 singlets, 2 of which are killed (non-bonded). # The other 4 are the 2 pair of strand open bond singlets. X_List = filter( lambda atom: atom.element.symbol in ('X'), start_basepair_atoms) X_List += filter( lambda atom: atom.element.symbol in ('X'), end_basepair_atoms) # Adjust the 4 open bond singlets. for singlet in X_List: if singlet.killed(): # Skip the 2 killed singlets. continue adjustSinglet(singlet) return
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.strandListWidget.connect_or_disconnect_signals(isConnect) self.segmentListWidget.connect_or_disconnect_signals(isConnect) change_connect(self.editStrandPropertiesButton, SIGNAL("clicked()"), self._editDnaStrand) change_connect(self.editSegmentPropertiesButton, SIGNAL("clicked()"), self._editDnaSegment) change_connect(self.searchForCrossoversButton, SIGNAL("clicked()"), self._enterMakeCrossoversCommand) self._baseNumberLabelGroupBox.connect_or_disconnect_signals(isConnect)
def atom_ok(self, atom): # note: this can include Pl atoms in PAM5, # but the wrapper class filters them out of # the atom list it stores. if not atom.molecule: print_compact_stack( "bug: strand_bond_chain_analyzer skipping %r with no .molecule: " % atom) return False if atom._dna_updater__error: return False return atom.element.role == 'strand' and not atom.molecule.in_a_valid_ladder( )
def atom_ok(self, atom): if not atom.molecule: # I've seen this after Undo, presumably since it's buggy [080122] # (To repeat: make a duplex, delete some atoms, Undo, Redo. # [bruce 080226 comment]) print_compact_stack( "bug: axis_bond_chain_analyzer skipping %r " \ "with no .molecule (killed = %r, _f_assy = %r): " \ % (atom, atom.killed(), atom._f_assy) ) return False if atom._dna_updater__error: return False return atom.element.role == 'axis' and not atom.molecule.in_a_valid_ladder( )
def _postProcess(self, baseList): """ Final tweaks on the DNA chunk, including: - Transmute Ax3 atoms on each end into Ae3. - Adjust open bond singlets. @param baseList: List of basepair chunks that make up the duplex. @type baseList: list @note: baseList must contain at least two base-pair chunks. """ if len(baseList) < 1: print_compact_stack("bug? (ignoring) DnaDuplex._postProcess called but "\ "baseList is empty. Maybe dna_updater was "\ "run?: ") return start_basepair_atoms = baseList[0].atoms.values() end_basepair_atoms = baseList[-1].atoms.values() Ax_caps = filter(lambda atom: atom.element.symbol in ('Ax3'), start_basepair_atoms) Ax_caps += filter(lambda atom: atom.element.symbol in ('Ax3'), end_basepair_atoms) # Transmute Ax3 caps to Ae3 atoms. # Note: this leaves two "killed singlets" hanging around, # one from each Ax3 cap. # # REVIEW: is it safe to simply not do this when dna_updater_is_enabled()? # [bruce 080320 question] for atom in Ax_caps: atom.Transmute(Element_Ae3) # X_List will contain 6 singlets, 2 of which are killed (non-bonded). # The other 4 are the 2 pair of strand open bond singlets. X_List = filter(lambda atom: atom.element.symbol in ('X'), start_basepair_atoms) X_List += filter(lambda atom: atom.element.symbol in ('X'), end_basepair_atoms) # Adjust the 4 open bond singlets. for singlet in X_List: if singlet.killed(): # Skip the 2 killed singlets. continue adjustSinglet(singlet) return
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 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.strandListWidget.connect_or_disconnect_signals(isConnect) self.segmentListWidget.connect_or_disconnect_signals(isConnect) change_connect(self.editStrandPropertiesButton, SIGNAL("clicked()"), self._editDnaStrand) change_connect(self.editSegmentPropertiesButton, SIGNAL("clicked()"), self._editDnaSegment) change_connect(self.searchForCrossoversButton, SIGNAL("clicked()"), self._enterMakeCrossoversCommand)
def closeEvent(self, event): """ This is the closeEvent handler, it's called when press 'X' button on the title bar or 'Esc' key or 'Exit' button in the dialog """ try: self._applyChange() self._saveServerList() except: print_compact_stack("Sim-server pickle exception.") self.accept() self.accept() return
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 _superclass.connect_or_disconnect_signals(self, isConnect = isConnect) if DEBUG_BREAK_OPTIONS_FEATURE: self._dnaStrandChooserGroupBox.connect_or_disconnect_signals(isConnect = isConnect) change_connect(self.breakAllStrandsButton, SIGNAL("clicked()"), self.command.breakStrandBonds) change_connect(self.basesBeforeNextBreakSpinBox, SIGNAL("valueChanged(int)"), self.valueChanged_basesBeforeNextBreak)
def _modifyStructure(self, params): """ Modify the structure based on the parameters specified. Overrides EditCommand._modifystructure. This method removes the old structure and creates a new one using self._createStructure. This was needed for the structures like this (Dna, Nanotube etc) . . See more comments in the method. """ if self.currentStruct is None: print_compact_stack("bug: self.currentStruct doesn't exist"\ "exiting self._modifyStructure") return assert isinstance(self.currentStruct , self.win.assy.DnaSegment) self.dna = B_Dna_PAM3_Generator() duplexRise = self.currentStruct.getDuplexRise() basesPerTurn = self.currentStruct.getBasesPerTurn() numberOfBasePairsToAddOrRemove = self._determine_numberOfBasePairs_to_change() ladderEndAxisAtom = self.get_axisEndAtom_at_resize_end() if ladderEndAxisAtom is None: print_compact_stack("bug: unable to resize the DnaSegment"\ "%r, end axis ato not found"%self.currentStruct) return if numberOfBasePairsToAddOrRemove != 0: resizeEnd_final_position = self._get_resizeEnd_final_position( ladderEndAxisAtom, abs(numberOfBasePairsToAddOrRemove), duplexRise ) self.dna.modify(self.currentStruct, ladderEndAxisAtom, numberOfBasePairsToAddOrRemove, basesPerTurn, duplexRise, ladderEndAxisAtom.posn(), resizeEnd_final_position) self.previousParams = params return
def _i_grabarg( self, attr, argpos, dflt_expr, _arglist = False): """ #doc, especially the special values for some of these args """ debug = False ## _arglist if debug: print_compact_stack( "_i_grabarg called with ( self %r, attr %r, argpos %r, dflt_expr %r, _arglist %r): " % \ (self, attr, argpos, dflt_expr, _arglist) ) print " and the data it grabs from is _e_kws = %r, _e_args = %r" % (self._e_kws, self._e_args) #k below should not _e_eval or canon_expr without review -- should return an arg expr or dflt expr, not its value # (tho for now it also can return None on error -- probably causing bugs in callers) assert is_pure_expr(dflt_expr), "_i_grabarg dflt_expr should be an expr, not %r" % (dflt_expr,) #061105 - or use canon_expr? assert self._e_is_instance if not self._e_has_args: print "warning: possible bug: not self._e_has_args in _i_grabarg%r in %r" % ((attr, argpos), self) assert attr is None or isinstance(attr, str) assert argpos is None or (isinstance(argpos, int) and argpos >= 0) assert _arglist in (False, True) external_flag, res0 = self._i_grabarg_0(attr, argpos, dflt_expr, _arglist = _arglist) if external_flag: # flag and this condition added 061116 443p to try to fix '_self dflt_expr bug'; seems to work in testexpr_9a; # I'm guessing type_expr doesn't have a similar bug since it's applied outside this call. #k index = attr or argpos #k I guess, for now [070105 stub -- not always equal to index in ipath, esp for ArgOrOption] env_for_arg = self.env_for_arg(index) # revised 070105 if debug070120: print "grabarg %r in %r is wrapping %r with %r containing _self %r" % \ ((attr, argpos), self, res0, env_for_arg, getattr(env_for_arg,'_self','<none>')) res = lexenv_Expr(env_for_arg, res0) ##k lexenv_Expr is guess, 061110 late, seems confirmed; env_for_args 061114 #e possible good optim: use self.env instead, unless res0 contains a use of _this; # or we could get a similar effect (slower when this runs, but better when the arg instance is used) by simplifying res, # so that only the used parts of the env provided by lexenv_Expr remained (better due to other effects of simplify) else: res = res0 #k (I *think* it's right to not even add self.env here, tho I recall I had lexenv_Expr(self.env, res0) at first -- # because the self.env was for changing _self, which we want to avoid here, and the _for_args is for supporting _this.) # Note: there was a '_self dflt_expr bug' in the above, until i added 'if external_flag:'] [diagnosed & fixed 061116]: # it's wrong for the parts of this expr res0 that came from our class, i.e. dflt_expr and type_expr. # That is hard to fix here, since they're mixed into other parts of the same expr, # but nontrivial to fix where we supply them, since when we do, the specific env needed is not known -- # we'd have to save it up or push it here, then access it there (or just say "escape from the most local lexenv_Expr" # if that's well-defined & possible & safe -- maybe the most local one of a certain type is better). # We also want whatever we do to be robust, and to not make it too hard to someday simplify the expr. # So why not fix it by wrapping only the parts that actually come from _e_args and _e_kws, right when we access them? # I guess that is done inside _i_grabarg_0... ok, it's easy to add external_flag to its retval to tell us what to do. [done] ###k ARE THERE any other accesses of _e_args or _e_kws that need similar protection? Worry about this if I add # support for iterating specific args (tho that might just end up calling _i_grabarg and being fine). if debug: print "_i_grabarg returns %r" % (res,) return res
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 geticon(name, print_errors = True): """ Return the QIcon for the given image path name. @param name: The image path name provided by the user. The path should start with 'ui/' directory inside the src directory. If name is an empty string, a null icon is returned. @type name: str @param print_errors: whether to report errors for missing icon files when atom_debug is set. True by default. @type print_errors: boolean @return: QIcon object for the given image path. @rtype: QIcon object. """ root, ext = os.path.splitext(name) if not ext: if name: # 'name' can be an empty string. See docstring for details. msg = "Warning: No '.png' extension provided for [%s]. " \ "\nPlease add the .png suffix to remove this warning.\n" % name print_compact_stack(msg) name = name + '.png' iconPath = os.path.join(_iconprefix, name) iconPath = os.path.normpath(iconPath) if not os.path.exists(iconPath): if debug_flags.atom_debug and print_errors: print "icon path %s doesn't exist." % (iconPath,) # Always set the icon with the 'iconPath'. Don't set it as an empty string # like done in getPixmap. This is done on purpose. Right now there is an # apparent bug in Qt in the text alignment for a push button with style sheet. # @see L{PM_GroupBox._getTitleButton} which sets a non-existant # 'Ghost Icon' for this button using 'geticon method' # By setting such an icon, the button text left-aligns! If you create an icon # with iconPath = empty string (when the user supplied path doesn't exist) # the text in that title button center-aligns. So lets just always use the # 'iconPath' even when the path doesn't exist. -- ninad 2007-08-22 icon = QtGui.QIcon(iconPath) return icon