Example #1
0
    def leftDown(self, event):
        """
        When in clipboard mode, set hotspot if a Singlet is highlighted.
        """
        if self.elementMode:
            return

        obj = self.selectedObj
        if isinstance(obj, Atom) and (obj.element is Singlet):
            mol = obj.molecule
            if not mol is self.lastHotspotChunk:
                if self.lastHotspotChunk:  # Unset previous hotspot [bruce 060629 fix bug 1974 -- only if in same part]
                    if mol.part is self.lastHotspotChunk.part and mol.part is not None:
                        # Old and new hotspot chunks are in same part. Unset old hotspot,
                        # so as to encourage there to be only one per Part.
                        #   This should happen when you try to make more than one hotspot in one
                        # library part or clipboard item, using the MMKit to make both.
                        #   It might make more sense for more general code in Part to prevent
                        # more than one hotspot per part... but we have never decided whether
                        # that would be a good feature. (I have long suspected that hotspots
                        # should be replaced by some sort of jig, to give more control....)
                        #   I don't know if this case can ever happen as of now, since multichunk
                        # clipboard items aren't shown in MMKit -- whether it can happen now
                        # depends on whether any multichunk library parts have bondpoints on
                        # more than one chunk. [bruce 060629]
                        if env.debug() and self.lastHotspotChunk.hotspot:  # bruce 060629 re bug 1974
                            print "debug: unsetting hotspot of %r (was %r)" % (
                                self.lastHotspotChunk,
                                self.lastHotspotChunk.hotspot,
                            )
                        self.lastHotspotChunk.set_hotspot(None)
                    else:
                        # Don't unset hotspot in this case (doing so was causing bug 1974).
                        if env.debug() and self.lastHotspotChunk.hotspot:
                            print "debug: NOT unsetting hotspot of %r" % (self.lastHotspotChunk,)
                        pass
                self.lastHotspotChunk = mol
                # [as of 060629, the only purpose of this is to permit the above code to unset it in some cases]

            mol.set_hotspot(obj)

            if 1:
                # bruce 060328 fix gl_update part of bug 1775 (the code looks like that was a bug forever, don't know for sure)
                main_glpane = env.mainwindow().glpane
                if mol.part is main_glpane.part:
                    main_glpane.gl_update()

            self.hotspotAtom = obj
            self.updateGL()
        return
Example #2
0
    def leftDown(self, event):
        """
        When in clipboard mode, set hotspot if a Singlet is highlighted.
        """
        if self.elementMode: return

        obj = self.selectedObj
        if isinstance(obj, Atom) and (obj.element is Singlet):
            mol = obj.molecule
            if not mol is self.lastHotspotChunk:
                if self.lastHotspotChunk:  # Unset previous hotspot [bruce 060629 fix bug 1974 -- only if in same part]
                    if mol.part is self.lastHotspotChunk.part and mol.part is not None:
                        # Old and new hotspot chunks are in same part. Unset old hotspot,
                        # so as to encourage there to be only one per Part.
                        #   This should happen when you try to make more than one hotspot in one
                        # library part or clipboard item, using the MMKit to make both.
                        #   It might make more sense for more general code in Part to prevent
                        # more than one hotspot per part... but we have never decided whether
                        # that would be a good feature. (I have long suspected that hotspots
                        # should be replaced by some sort of jig, to give more control....)
                        #   I don't know if this case can ever happen as of now, since multichunk
                        # clipboard items aren't shown in MMKit -- whether it can happen now
                        # depends on whether any multichunk library parts have bondpoints on
                        # more than one chunk. [bruce 060629]
                        if env.debug(
                        ) and self.lastHotspotChunk.hotspot:  #bruce 060629 re bug 1974
                            print "debug: unsetting hotspot of %r (was %r)" % \
                                  (self.lastHotspotChunk, self.lastHotspotChunk.hotspot)
                        self.lastHotspotChunk.set_hotspot(None)
                    else:
                        # Don't unset hotspot in this case (doing so was causing bug 1974).
                        if env.debug() and self.lastHotspotChunk.hotspot:
                            print "debug: NOT unsetting hotspot of %r" % (
                                self.lastHotspotChunk, )
                        pass
                self.lastHotspotChunk = mol
                # [as of 060629, the only purpose of this is to permit the above code to unset it in some cases]

            mol.set_hotspot(obj)

            if 1:
                #bruce 060328 fix gl_update part of bug 1775 (the code looks like that was a bug forever, don't know for sure)
                main_glpane = env.mainwindow().glpane
                if mol.part is main_glpane.part:
                    main_glpane.gl_update()

            self.hotspotAtom = obj
            self.updateGL()
        return
    def undo_redo_ops(self):
        # copied code below [dup code is in undo_manager_older.py, not in cvs]

        # the following value for warn_when_change_counters_seem_wrong is a kluge
        # (wrong in principle but probably safe, not entirely sure it's correct) [060309]
        # (note, same value was hardcoded inside that method before bruce 071025;
        #  see comment there about when I see the warnings; it's known that it gives
        #  false warnings if we pass True when _AutoCheckpointing_enabled is false):
        ops = self.archive.find_undoredos(
            warn_when_change_counters_seem_wrong=_AutoCheckpointing_enabled)
        # state_version - now held inside UndoArchive.last_cp (might be wrong) ###@@@
        # [what the heck does that comment mean? bruce 071025 Q]
        undos = []
        redos = []
        d1 = {'Undo': undos, 'Redo': redos}
        for op in ops:
            optype = op.optype()
            d1[optype].append(op)  # sort ops by type
        ## done in the subr: redos = filter( lambda redo: not redo.destroyed, redos) #060309 since destroyed ones are not yet unstored
        # remove obsolete redo ops
        if redos:
            lis = [(redo.cps[1].cp_counter, redo) for redo in redos]
            lis.sort()
            only_redo = lis[-1][1]
            redos = [only_redo]
            for obs_redo in lis[:-1]:
                if undo_archive.debug_undo2 or env.debug():
                    #060309 adding 'or env.debug()' since this should never happen once clear_redo_stack() is implemented in archive
                    print "obsolete redo:", obs_redo
                pass  #e discard it permanently? ####@@@@
        return undos, redos
Example #4
0
 def undo_redo_ops(self):
     # copied code below [dup code is in undo_manager_older.py, not in cvs]
     
     # the following value for warn_when_change_indicators_seem_wrong is a kluge
     # (wrong in principle but probably safe, not entirely sure it's correct) [060309]
     # (note, same value was hardcoded inside that method before bruce 071025;
     #  see comment there about when I see the warnings; it's known that it gives
     #  false warnings if we pass True when _AutoCheckpointing_enabled is false):
     ops = self.archive.find_undoredos(
               warn_when_change_indicators_seem_wrong = _AutoCheckpointing_enabled )
         # state_version - now held inside UndoArchive.last_cp (might be wrong) ###@@@
         # [what the heck does that comment mean? bruce 071025 Q]
     undos = []
     redos = []
     d1 = {'Undo':undos, 'Redo':redos}
     for op in ops:
         optype = op.optype()
         d1[optype].append(op) # sort ops by type
     ## done in the subr: redos = filter( lambda redo: not redo.destroyed, redos) #060309 since destroyed ones are not yet unstored
     # remove obsolete redo ops
     if redos:
         lis = [ (redo.cps[1].cp_counter, redo) for redo in redos ]
         lis.sort()
         only_redo = lis[-1][1]
         redos = [only_redo]
         for obs_redo in lis[:-1]:
             if undo_archive.debug_undo2 or env.debug():
                 #060309 adding 'or env.debug()' since this should never happen once clear_redo_stack() is implemented in archive
                 print "obsolete redo:", obs_redo
             pass #e discard it permanently? ####@@@@
     return undos, redos
Example #5
0
def _capitalize_first_word(words):  #bruce 060705
    res = words[0].upper() + words[1:]
    if res == words:
        if env.debug():
            print "debug warning: %r did not change in _capitalize_first_word" % (
                words, )
    return res
Example #6
0
 def update_cond_from_update_data(self,
                                  update_data):  #e could be a static method
     update_number, update_units, update_as_fast_as_possible_data, enable = update_data
     if not enable:
         return False  #e someday we might do this at the end, if the subsequent code is extended to save some prefs
     update_as_fast_as_possible = (update_as_fast_as_possible_data != 1)
     if env.debug():
         print "debug: using update_as_fast_as_possible = %r,  update_number, update_units = %r, %r" % \
               ( update_as_fast_as_possible,  update_number, update_units )
         pass
     if update_as_fast_as_possible:
         # This radiobutton might be misnamed; it really means "use the old code,
         # i.e. not worse than 20% slowdown, with threshholds".
         # It's also ambiguous -- does "fast" mean "fast progress"
         # or "often" (which are opposites)? It sort of means "often".
         update_cond = (lambda simtime, pytime, nframes: simtime >= max(
             0.05, min(pytime * 4, 2.0)))
     elif update_units == 'frames':
         update_cond = (lambda simtime, pytime, nframes, _nframes=
                        update_number: nframes >= _nframes)
     elif update_units == 'seconds':
         update_cond = (lambda simtime, pytime, nframes, _timelimit=
                        update_number: simtime + pytime >= _timelimit)
     elif update_units == 'minutes':
         update_cond = (lambda simtime, pytime, nframes, _timelimit=
                        update_number * 60: simtime + pytime >= _timelimit)
     elif update_units == 'hours':
         update_cond = (
             lambda simtime, pytime, nframes, _timelimit=update_number *
             3600: simtime + pytime >= _timelimit)
     else:
         print "don't know how to set update_cond from (%r, %r)" % (
             update_number, update_units)
         update_cond = None  # some callers can tolerate this, though it's always a reportable error
     return update_cond
 def update_cond_from_update_data(self, update_data):  # e could be a static method
     update_number, update_units, update_as_fast_as_possible_data, enable = update_data
     if not enable:
         return False  # e someday we might do this at the end, if the subsequent code is extended to save some prefs
     update_as_fast_as_possible = update_as_fast_as_possible_data != 1
     if env.debug():
         print "debug: using update_as_fast_as_possible = %r,  update_number, update_units = %r, %r" % (
             update_as_fast_as_possible,
             update_number,
             update_units,
         )
         pass
     if update_as_fast_as_possible:
         # This radiobutton might be misnamed; it really means "use the old code,
         # i.e. not worse than 20% slowdown, with threshholds".
         # It's also ambiguous -- does "fast" mean "fast progress"
         # or "often" (which are opposites)? It sort of means "often".
         update_cond = lambda simtime, pytime, nframes: simtime >= max(0.05, min(pytime * 4, 2.0))
     elif update_units == "frames":
         update_cond = lambda simtime, pytime, nframes, _nframes=update_number: nframes >= _nframes
     elif update_units == "seconds":
         update_cond = lambda simtime, pytime, nframes, _timelimit=update_number: simtime + pytime >= _timelimit
     elif update_units == "minutes":
         update_cond = lambda simtime, pytime, nframes, _timelimit=update_number * 60: simtime + pytime >= _timelimit
     elif update_units == "hours":
         update_cond = (
             lambda simtime, pytime, nframes, _timelimit=update_number * 3600: simtime + pytime >= _timelimit
         )
     else:
         print "don't know how to set update_cond from (%r, %r)" % (update_number, update_units)
         update_cond = None  # some callers can tolerate this, though it's always a reportable error
     return update_cond
Example #8
0
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
Example #9
0
def include_dir_ok(include_dir):
    """
    Is this include_dir acceptable (or maybe acceptable)? Return (0, "") or (errorcode, errortext).
    """
    if env.debug():
        print "debug: include_dir_ok(include_dir = %r)" % (include_dir,)
    if os.path.isdir(include_dir):
        # ok, but warn if transforms.inc is not inside it
        if not os.path.exists(os.path.join(include_dir, "transforms.inc")):
            msg = "Warning: transforms.inc not present in POV include directory [%s]; rendering might not work" % (include_dir,)
            env.history.message(orangemsg(msg))
        if env.debug():
            print "debug: include_dir_ok returns 0 (ok)"
        return 0, "" # ok
    else:
        if env.debug():
            print "debug: include_dir_ok returns 1 (Not found or not a directory)"
        return 1, "POV include directory: Not found or not a directory" #e pathname might be too long for a dialog
    pass
Example #10
0
 def setDisplay_command(self, widget):
     win = env.mainwindow()
     win.setDisplayStyle_of_selection(self.ind)
         #bruce 080910 comment, upon renaming that method from setDisplay:
         # the new name says what it does, but when originally coded
         # this would set global style if nothing was selected
         # (since that method used to act that way).
     if env.debug():
         print "setDisplayStyle_of_selection to %r.ind == %r" % (self, self.ind)
     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
Example #12
0
 def setDisplay_command(self, widget):
     win = env.mainwindow()
     win.setDisplayStyle_of_selection(self.ind)
         #bruce 080910 comment, upon renaming that method from setDisplay:
         # the new name says what it does, but when originally coded
         # this would set global style if nothing was selected
         # (since that method used to act that way).
     if env.debug():
         print "setDisplayStyle_of_selection to %r.ind == %r" % (self, self.ind)
     return
Example #13
0
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
Example #14
0
 def decide(self, sender, signal):
     """
     should we wrap the slot for this signal when it's sent from this sender?
     """
     if 'treeChanged' in str(signal): ###@@@ kluge: knowing this [bruce 060320 quick hack to test-optimize Undo checkpointing]
         if env.debug():
             ###@@@ kluge: assuming what we're used for, in this message text
             print "debug: note: not wrapping this signal for undo checkpointing:", signal
         return False
     return True # try wrapping them all, for simplicity
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
Example #16
0
def include_dir_ok(include_dir):
    """
    Is this include_dir acceptable (or maybe acceptable)? Return (0, "") or (errorcode, errortext).
    """
    if env.debug():
        print "debug: include_dir_ok(include_dir = %r)" % (include_dir, )
    if os.path.isdir(include_dir):
        # ok, but warn if transforms.inc is not inside it
        if not os.path.exists(os.path.join(include_dir, "transforms.inc")):
            msg = "Warning: transforms.inc not present in POV include directory [%s]; rendering might not work" % (
                include_dir, )
            env.history.message(orangemsg(msg))
        if env.debug():
            print "debug: include_dir_ok returns 0 (ok)"
        return 0, ""  # ok
    else:
        if env.debug():
            print "debug: include_dir_ok returns 1 (Not found or not a directory)"
        return 1, "POV include directory: Not found or not a directory"  #e pathname might be too long for a dialog
    pass
Example #17
0
 def cancel_btn_clicked(self):
     """
     Slot for Cancel button
     """
     if env.debug():
         print "cancel"
     # restore values we grabbed on entry.
     for key,val in zip((endRMS_prefs_key, endMax_prefs_key, cutoverRMS_prefs_key, cutoverMax_prefs_key), self.previousParams):
         env.prefs[key] = val
     self.update_widgets(update_seltype = False) #k might not matter since we're about to hide it, but can't hurt
     QDialog.reject(self)
     return
 def decide(self, sender, signal):
     """
     should we wrap the slot for this signal when it's sent from this sender?
     """
     if 'treeChanged' in str(
             signal
     ):  ###@@@ kluge: knowing this [bruce 060320 quick hack to test-optimize Undo checkpointing]
         if env.debug():
             ###@@@ kluge: assuming what we're used for, in this message text
             print "debug: note: not wrapping this signal for undo checkpointing:", signal
         return False
     return True  # try wrapping them all, for simplicity
 def selobj_still_ok(self, glpane):
     res = self.__class__ is ReferenceGeometry
     if res:
         our_selobj = self
         glname = self.glname
         owner = env.obj_with_glselect_name.get(glname, None)
         if owner is not our_selobj:
             res = False
             # Do debug prints [perhaps never seen as of 061121]
             print "%r no longer owns glname %r, instead %r does" % (self, glname, owner)
     if not res and env.debug():
         print "debug: selobj_still_ok is false for %r" % self
     return res
def _run_bond_updater(warn_if_needed=False):  #bruce 080210 split this out

    if not (changed_structure_atoms or changed_bond_types):
        # Note: this will be generalized to:
        # if no changes of any kind, since the last call
        # Note: the dna updater processes changes in other dicts,
        # but we don't need to check those in this function.
        return

    # some changes occurred, so this function needed to be called
    # (even if they turn out to be trivial)
    if warn_if_needed and env.debug():
        # whichever user event handler made these changes forgot to call
        # this function when it was done!
        # [as of 071115 warn_if_needed is never true; see docstring]
        print "atom_debug: _master_model_updater should have been called " \
              "before this call (since the most recent model changes), " \
              "but wasn't!" #e use print_compact_stack??
        pass  # (other than printing this, we handle unreported changes normally)

    # handle and clear all changes since the last call
    # (in the proper order, when there might be more than one kind of change)

    # Note: reloading this module won't work, the way this code is currently
    # structured. If reloading is needed, this routine needs to be
    # unregistered prior to the reload, and reregistered afterwards.
    # Also, note that the module might be reloading itself, so be careful.

    if changed_structure_atoms:
        update_bonds_after_each_event(changed_structure_atoms)
        #bruce 060315 revised following comments:
        # Note: this can modify changed_bond_types (from bond-inference,
        # if we implement that in the future, or from correcting
        # illegal bond types, in the present code).
        # SOMEDAY: I'm not sure if that routine will need to use or change
        # other similar globals in this module; if it does, passing just
        # that one might be a bit silly (so we could pass none, or all
        # affected ones)
        changed_structure_atoms.clear()

    if changed_bond_types:
        # WARNING: this dict may have been modified by the above loop
        # which processes changed_structure_atoms...
        process_changed_bond_types(changed_bond_types)
        # REVIEW: our interface to that function needs review if it can
        # recursively add bonds to this dict -- if so, it should .clear,
        # not us!
        changed_bond_types.clear()

    return  # from _run_bond_updater
 def selobj_still_ok(self, glpane):
     res = self.__class__ is ReferenceGeometry
     if res:
         our_selobj = self
         glname = self.glname
         owner = env.obj_with_glselect_name.get(glname, None)
         if owner is not our_selobj:
             res = False
             # Do debug prints [perhaps never seen as of 061121]
             print "%r no longer owns glname %r, instead %r does" \
                   % (self, glname, owner)
     if not res and env.debug():
         print "debug: selobj_still_ok is false for %r" % self
     return res
def _run_bond_updater(warn_if_needed = False): #bruce 080210 split this out
    
    if not (changed_structure_atoms or changed_bond_types):
        # Note: this will be generalized to:
        # if no changes of any kind, since the last call
        # Note: the dna updater processes changes in other dicts,
        # but we don't need to check those in this function.
        return
    
    # some changes occurred, so this function needed to be called
    # (even if they turn out to be trivial)
    if warn_if_needed and env.debug():
        # whichever user event handler made these changes forgot to call
        # this function when it was done!
        # [as of 071115 warn_if_needed is never true; see docstring]
        print "atom_debug: _master_model_updater should have been called " \
              "before this call (since the most recent model changes), " \
              "but wasn't!" #e use print_compact_stack??
        pass # (other than printing this, we handle unreported changes normally)
    
    # handle and clear all changes since the last call
    # (in the proper order, when there might be more than one kind of change)

    # Note: reloading this module won't work, the way this code is currently
    # structured. If reloading is needed, this routine needs to be
    # unregistered prior to the reload, and reregistered afterwards.
    # Also, note that the module might be reloading itself, so be careful.

    if changed_structure_atoms:
        update_bonds_after_each_event( changed_structure_atoms)
            #bruce 060315 revised following comments:
            # Note: this can modify changed_bond_types (from bond-inference,
            # if we implement that in the future, or from correcting
            # illegal bond types, in the present code).
            # SOMEDAY: I'm not sure if that routine will need to use or change
            # other similar globals in this module; if it does, passing just
            # that one might be a bit silly (so we could pass none, or all
            # affected ones)
        changed_structure_atoms.clear()
    
    if changed_bond_types:
        # WARNING: this dict may have been modified by the above loop
        # which processes changed_structure_atoms...
        process_changed_bond_types( changed_bond_types)
            # REVIEW: our interface to that function needs review if it can
            # recursively add bonds to this dict -- if so, it should .clear,
            # not us!
        changed_bond_types.clear()
    
    return # from _run_bond_updater
Example #23
0
def default_include_dir(
):  #bruce 060710 split out and revised Mark's & Will's code for this in write_povray_ini_file
    """
    The user did not specify an include dir, so guess one from the POV-Ray path (after verifying it's set).
    Return 0, include_dir or errorcode, errortext.
    If not having one is deemed worthy of only a warning, not an error, emit the warning and return 0 [nim].
    """
    # Motivation:
    # If MegaPOV is enabled, the Library_Path option must be added and set to the POV-Ray/include
    # directory in the INI. This is so MegaPOV can find the include file "transforms.inc". Mark 060628.
    # : Povray also needs transforms.inc - wware 060707
    # : : [but when this is povray, it might know where it is on its own (its own include dir)? not sure. bruce 060707]
    # : : [it looks like it would not know that in the Mac GUI version (which NE1 has no way of supporting,
    #       since external programs can't pass it arguments); I don't know about Unix/Linux or Windows. bruce 060710]

    if not this_platform_can_guess_include_dir_from_povray_path():
        # this runs on Mac
        return 1, "Can't guess include dir from POV-Ray executable\npath on this platform; please set it explicitly"

    povray_path = env.prefs[povray_path_prefs_key]
    if not povray_path:
        return 1, "Either the POV include directory or the POV-Ray\nexecutable path must be set (even when using MegaPOV)"
        #e in future, maybe we could use one from POV-Ray, even if it was not enabled, so don't preclude this here

    try:
        # try to guess the include directory (include_dir) from povray_path; exception if you fail
        if sys.platform == 'win32':  # Windows
            povray_bin, povray_exe = os.path.split(povray_path)
            povray_dir, bin = os.path.split(povray_bin)
            include_dir = os.path.normpath(os.path.join(povray_dir, "include"))
        elif sys.platform == 'darwin':  # Mac
            assert 0
        else:  # Linux
            povray_bin = povray_path.split(
                os.path.sep)  # list of pathname components
            assert povray_bin[-2] == 'bin' and povray_bin[
                -1] == 'povray'  # this is the only kind of path we can do this for
            include_dir = os.path.sep.join(povray_bin[:-2] +
                                           ['share', 'povray-3.6', 'include'])
        return 0, include_dir
    except:
        if env.debug(
        ) and this_platform_can_guess_include_dir_from_povray_path():
            print_compact_traceback(
                "debug fyi: this is the exception inside default_include_dir: "
            )
        msg = "Unable to guess POV include directory from\nPOV-Ray executable path; please set it explicitly"
        return 1, msg
    pass
    def set_view_for_Undo(
        self, assy, namedView
    ):  # shares code with NamedView.set_view; might be very similar to some GLPane method, too
        """
        Restore the view (and the current Part) to what was saved by current_view_for_Undo.
        WARNING: present implem of saving current Part (using its index in MT) is not suitable for out-of-order Redo.
        WARNING: might not gl_update, assume caller does so [#k obs warning?]
        """
        ## compare to NamedView.set_view (which passes animate = True) -- not sure if we want to animate in this case [we do, for A8],
        # but if we do, we might have to do that at a higher level in the call chain
        restore_view = env.prefs[undoRestoreView_prefs_key]  #060314
        restore_current_part = True  # always do this no matter what
        ## restore_mode?? nah (not for A7 anyway; unclear what's best in long run)
        if restore_view:
            if type(namedView) == type(""):
                #####@@@@@ code copied from GLPane.__init__, should be shared somehow, or at least comment GLPane and warn it's copied
                #e also might not be the correct view, it's just the hardcoded default view... but i guess it's correct.
                # rotation
                self.quat = Q(1, 0, 0, 0)
                # point of view (i.e. negative of center of view)
                self.pov = V(0.0, 0.0, 0.0)

                # half-height of window in Angstroms (gets reset by certain
                #view-changing operations [bruce 050615 comment])
                #@REVIEW: Should self.scale here should be set from
                #startup_GLPane_scale_prefs_key ??
                self.scale = 10.0
                # zoom factor
                self.zoomFactor = 1.0
            else:
                self.animateToView(namedView.quat,
                                   namedView.scale,
                                   namedView.pov,
                                   namedView.zoomFactor,
                                   animate=False)
                # if we want this to animate, we probably have to move that higher in the call chain and do it after everything else
        if restore_current_part:
            if type(namedView) == type(""):
                if env.debug():
                    print "debug: fyi: cys == '' still happens"  # does it? ###@@@ 060314 remove if seen, or if not seen
                current_selgroup_index = 0
            else:
                current_selgroup_index = namedView.current_selgroup_index
            sg = assy.selgroup_at_index(current_selgroup_index)
            assy.set_current_selgroup(sg)
            #e how might that interact with setting the selection? Hopefully, not much, since selection (if any) should be inside sg.
        #e should we update_parts?
        return
Example #25
0
 def selobj_still_ok(self, glpane):
     res = self.__class__ is DirectionArrow
     if res:
         our_selobj = self
         glname = self.glname
         owner = glpane.assy.object_for_glselect_name(glname)
         if owner is not our_selobj:
             res = False
             # Do debug prints.
             print "%r no longer owns glname %r, instead %r does" \
                   % (self, glname, owner) # [perhaps never seen as of 061121]
             pass
         pass
     if not res and env.debug():
         print "debug: selobj_still_ok is false for %r" % self
     return res
Example #26
0
 def selobj_still_ok(self, glpane):
     # bugfix: compare to correct class [bruce 070924]
     res = self.__class__ is ResizeHandle 
     if res:
         our_selobj = self
         glname     = self.glname
         owner      = env.obj_with_glselect_name.get(glname, None)
         if owner is not our_selobj:
             res = False
             # Do debug prints.
             print "%r no longer owns glname %r, instead %r does" \
                   % (self, glname, owner) #[perhaps never seen as of 061121]
         pass
     if not res and env.debug():
         print "debug: selobj_still_ok is false for %r" % self 
     return res
Example #27
0
 def selobj_still_ok(self, glpane):
     res = self.__class__ is DirectionArrow
     if res:
         our_selobj = self
         glname     = self.glname
         owner      = glpane.assy.object_for_glselect_name(glname)
         if owner is not our_selobj:
             res = False
             # Do debug prints.
             print "%r no longer owns glname %r, instead %r does" \
                   % (self, glname, owner) # [perhaps never seen as of 061121]
             pass
         pass
     if not res and env.debug():
         print "debug: selobj_still_ok is false for %r" % self
     return res
 def selobj_still_ok(self, glpane):
     # bugfix: compare to correct class [bruce 070924]
     res = self.__class__ is ResizeHandle
     if res:
         our_selobj = self
         glname = self.glname
         owner = env.obj_with_glselect_name.get(glname, None)
         if owner is not our_selobj:
             res = False
             # Do debug prints.
             print "%r no longer owns glname %r, instead %r does" \
                   % (self, glname, owner) #[perhaps never seen as of 061121]
         pass
     if not res and env.debug():
         print "debug: selobj_still_ok is false for %r" % self
     return res
Example #29
0
    def set_view_for_Undo(self, assy, namedView):
        """
        Restore the view (and the current Part) to what was saved by
        current_view_for_Undo.

        @warning: present implem of saving current Part (using its index in MT)
                  is not suitable for out-of-order Redo.

        @warning: might not gl_update, assume caller does so [#k obs warning?]
        """
        # shares code with NamedView.set_view; might be very similar to some GLPane method, too
        ## compare to NamedView.set_view (which passes animate = True) -- not sure if we want
        # to animate in this case [we do, for A8],
        # but if we do, we might have to do that at a higher level in the call chain
        restore_view = env.prefs[undoRestoreView_prefs_key]  #060314
        restore_current_part = True  # always do this no matter what
        ## restore_mode?? nah (not for A7 anyway; unclear what's best in long run)
        if restore_view:
            if type(namedView) == type(""):
                self._initialize_view_attributes()
                #bruce 090220 revision to remove copied code; not fully
                # equivalent to prior code (sets scale from prefs rather
                # than to 10.0) but I think that's ok, since I think this
                # functionality (Undo changing the view) is only cosmetic.
            else:
                self.animateToView(namedView.quat,
                                   namedView.scale,
                                   namedView.pov,
                                   namedView.zoomFactor,
                                   animate=False)
                # if we want this to animate, we probably have to move that
                # higher in the call chain and do it after everything else
        if restore_current_part:
            if type(namedView) == type(""):
                if env.debug():
                    print "debug: fyi: cys == '' still happens"
                    # does it? ###@@@ 060314 remove if seen, or if not seen
                current_selgroup_index = 0
            else:
                current_selgroup_index = namedView.current_selgroup_index
            sg = assy.selgroup_at_index(current_selgroup_index)
            assy.set_current_selgroup(sg)
            #e how might that interact with setting the selection?
            # Hopefully, not much, since selection (if any) should be inside sg.
        #e should we update_parts?
        return
    def set_view_for_Undo(
        self, assy, namedView
    ):  # shares code with NamedView.set_view; might be very similar to some GLPane method, too
        """
        Restore the view (and the current Part) to what was saved by current_view_for_Undo.
        WARNING: present implem of saving current Part (using its index in MT) is not suitable for out-of-order Redo.
        WARNING: might not gl_update, assume caller does so [#k obs warning?]
        """
        ## compare to NamedView.set_view (which passes animate = True) -- not sure if we want to animate in this case [we do, for A8],
        # but if we do, we might have to do that at a higher level in the call chain
        restore_view = env.prefs[undoRestoreView_prefs_key]  # 060314
        restore_current_part = True  # always do this no matter what
        ## restore_mode?? nah (not for A7 anyway; unclear what's best in long run)
        if restore_view:
            if type(namedView) == type(""):
                #####@@@@@ code copied from GLPane.__init__, should be shared somehow, or at least comment GLPane and warn it's copied
                # e also might not be the correct view, it's just the hardcoded default view... but i guess it's correct.
                # rotation
                self.quat = Q(1, 0, 0, 0)
                # point of view (i.e. negative of center of view)
                self.pov = V(0.0, 0.0, 0.0)

                # half-height of window in Angstroms (gets reset by certain
                # view-changing operations [bruce 050615 comment])
                # @REVIEW: Should self.scale here should be set from
                # startup_GLPane_scale_prefs_key ??
                self.scale = 10.0
                # zoom factor
                self.zoomFactor = 1.0
            else:
                self.animateToView(namedView.quat, namedView.scale, namedView.pov, namedView.zoomFactor, animate=False)
                # if we want this to animate, we probably have to move that higher in the call chain and do it after everything else
        if restore_current_part:
            if type(namedView) == type(""):
                if env.debug():
                    print "debug: fyi: cys == '' still happens"  # does it? ###@@@ 060314 remove if seen, or if not seen
                current_selgroup_index = 0
            else:
                current_selgroup_index = namedView.current_selgroup_index
            sg = assy.selgroup_at_index(current_selgroup_index)
            assy.set_current_selgroup(sg)
            # e how might that interact with setting the selection? Hopefully, not much, since selection (if any) should be inside sg.
        # e should we update_parts?
        return
Example #31
0
    def set_view_for_Undo(self, assy, namedView):
        """
        Restore the view (and the current Part) to what was saved by
        current_view_for_Undo.

        @warning: present implem of saving current Part (using its index in MT)
                  is not suitable for out-of-order Redo.

        @warning: might not gl_update, assume caller does so [#k obs warning?]
        """
        # shares code with NamedView.set_view; might be very similar to some GLPane method, too
        ## compare to NamedView.set_view (which passes animate = True) -- not sure if we want
        # to animate in this case [we do, for A8],
        # but if we do, we might have to do that at a higher level in the call chain
        restore_view = env.prefs[undoRestoreView_prefs_key] #060314
        restore_current_part = True # always do this no matter what
        ## restore_mode?? nah (not for A7 anyway; unclear what's best in long run)
        if restore_view:
            if type(namedView) == type(""):
                self._initialize_view_attributes()
                    #bruce 090220 revision to remove copied code; not fully
                    # equivalent to prior code (sets scale from prefs rather
                    # than to 10.0) but I think that's ok, since I think this
                    # functionality (Undo changing the view) is only cosmetic.
            else:
                self.animateToView(namedView.quat, namedView.scale, namedView.pov,
                                   namedView.zoomFactor, animate = False)
                    # if we want this to animate, we probably have to move that
                    # higher in the call chain and do it after everything else
        if restore_current_part:
            if type(namedView) == type(""):
                if env.debug():
                    print "debug: fyi: cys == '' still happens"
                        # does it? ###@@@ 060314 remove if seen, or if not seen
                current_selgroup_index = 0
            else:
                current_selgroup_index = namedView.current_selgroup_index
            sg = assy.selgroup_at_index(current_selgroup_index)
            assy.set_current_selgroup(sg)
                #e how might that interact with setting the selection?
                # Hopefully, not much, since selection (if any) should be inside sg.
        #e should we update_parts?
        return
Example #32
0
def _same_Numeric_array_helper(obj1, obj2):
    if obj1.typecode() != obj2.typecode():
        raise _NotTheSame
    if obj1.shape != obj2.shape:
        raise _NotTheSame
    if obj1.typecode() == PyObject:
        if env.debug():
            print "atom_debug: ran _same_Numeric_array_helper, PyObject case" # remove when works once ###@@@
        # assume not multi-dimensional (if we are, this should work [untested] but it will be inefficient)
        for i in xrange(len(obj1)):
            _same_vals_helper(obj1[i], obj2[i]) # two PyObjects (if obj1 is 1-dim) or two lower-dim Numeric arrays
    else:
##        if env.debug():
##            print "atom_debug: ran _same_Numeric_array_helper, non-PyObject case" # remove when works once ###@@@
        if obj1 != obj2:
            # take pointwise !=, then boolean value of that (correct, but is there a more efficient Numeric function?)
            # note: using '==' here (and negating boolean value of result) would NOT be correct
            raise _NotTheSame
    return
Example #33
0
    def ok_btn_clicked(self):
        """
        Slot for OK button
        """
        QDialog.accept(self)
        if env.debug():
            print "ok"
        self.gather_parameters()
        ### kluge: has side effect on env.prefs
        # (should we pass these as arg to Minimize_CommandRun rather than thru env.prefs??)
        if debug_flags.atom_debug:
            print "debug: reloading runSim & sim_commandruns on each use, for development"
            import simulation.runSim as runSim
            reload_once_per_event(runSim)
            # bug: only works some of the times runSim.py is modified,
            # don't know why; might be that sim_commandruns.py
            # also needs to be modified, but touching them both
            # doesn't seem to work consistently either.
            # [bruce 080520]
            import simulation.sim_commandruns as sim_commandruns
            reload_once_per_event(sim_commandruns)
        from simulation.sim_commandruns import Minimize_CommandRun
        # do this in gather?
        if self.minimize_all_rbtn.isChecked():
            self.seltype = 'All'
            seltype_name = "All"
        else:
            self.seltype = 'Sel'
            seltype_name = "Selection"
        self.win.assy.current_command_info(
            cmdname=self.plain_cmdname +
            " (%s)" % seltype_name)  # cmdname for Undo

        update_cond = self.ruc.get_update_cond_from_widgets()
        engine = self.minimize_engine_combobox.currentIndex()
        env.prefs[Minimize_minimizationEngine_prefs_key] = engine
        cmdrun = Minimize_CommandRun(self.win,
                                     self.seltype,
                                     type='Minimize',
                                     update_cond=update_cond,
                                     engine=engine)
        cmdrun.run()
        return
Example #34
0
def default_include_dir(): #bruce 060710 split out and revised Mark's & Will's code for this in write_povray_ini_file
    """
    The user did not specify an include dir, so guess one from the POV-Ray path (after verifying it's set).
    Return 0, include_dir or errorcode, errortext.
    If not having one is deemed worthy of only a warning, not an error, emit the warning and return 0 [nim].
    """
    # Motivation:
    # If MegaPOV is enabled, the Library_Path option must be added and set to the POV-Ray/include
    # directory in the INI. This is so MegaPOV can find the include file "transforms.inc". Mark 060628.
    # : Povray also needs transforms.inc - wware 060707
    # : : [but when this is povray, it might know where it is on its own (its own include dir)? not sure. bruce 060707]
    # : : [it looks like it would not know that in the Mac GUI version (which NE1 has no way of supporting,
    #       since external programs can't pass it arguments); I don't know about Unix/Linux or Windows. bruce 060710]

    if not this_platform_can_guess_include_dir_from_povray_path():
        # this runs on Mac
        return 1, "Can't guess include dir from POV-Ray executable\npath on this platform; please set it explicitly"

    povray_path = env.prefs[povray_path_prefs_key]
    if not povray_path:
        return 1, "Either the POV include directory or the POV-Ray\nexecutable path must be set (even when using MegaPOV)"
        #e in future, maybe we could use one from POV-Ray, even if it was not enabled, so don't preclude this here

    try:
        # try to guess the include directory (include_dir) from povray_path; exception if you fail
        if sys.platform == 'win32':  # Windows
            povray_bin, povray_exe = os.path.split(povray_path)
            povray_dir, bin = os.path.split(povray_bin)
            include_dir = os.path.normpath(os.path.join(povray_dir, "include"))
        elif sys.platform == 'darwin':  # Mac
            assert 0
        else:  # Linux
            povray_bin = povray_path.split(os.path.sep) # list of pathname components
            assert povray_bin[-2] == 'bin' and povray_bin[-1] == 'povray' # this is the only kind of path we can do this for
            include_dir = os.path.sep.join(povray_bin[:-2] + ['share', 'povray-3.6', 'include'])
        return 0, include_dir
    except:
        if env.debug() and this_platform_can_guess_include_dir_from_povray_path():
            print_compact_traceback("debug fyi: this is the exception inside default_include_dir: ")
        msg = "Unable to guess POV include directory from\nPOV-Ray executable path; please set it explicitly"
        return 1, msg
    pass
Example #35
0
    def make_dialog_if_needed(self):
        """
        Create self.dialog if necessary.
        """
        # For developers, remake the dialog from its description file each time that file changes.
        # (The point of only remaking it then is not speed, but to test the code when it doesn't get remade,
        #  since that's what always happens for non-developers.)
        # (Someday, when remaking it, copy its window geometry from the old one. Then put that code into the MMKit too. ###e)
        # For others, only make it the first time.

        if (EndUser.enableDeveloperFeatures() or env.debug()) and self.dialog:
            # For developers, remake the dialog if its description file changed (by zapping the old dialog here).
            zapit = False
            modtime = os.stat(self.param_desc_path).st_mtime
            if modtime != self.param_desc_path_modtime:
                zapit = True
                self.param_desc_path_modtime = modtime
            if zapit:
                #e save geometry?
                self.dialog.hide()
                self.dialog.destroy() ###k
                self.dialog = None
            pass
        if not self.dialog:
            if debug_run():
                print "making dialog from", self.parameter_set_filename
            dialog_env = self
                # KLUGE... it needs to be something with an imagename_to_pixmap function that knows our icon_path.
                # the easiest way to make one is self... in future we want our own env, and to modify it by inserting that path...
            if use_property_pane():
                # experimental, doesn't yet work [060623]
                parent = self.win.vsplitter2 ###@@@ could this parent be wrong? it acted like parent was self.win or so.
                clas = ParameterPane ###@@@ worked internally, buttons printed debug msgs, but didn't have any effects in GBC.
            else:
                # usual case
                parent = self.win
                clas = ParameterDialog
            self.dialog = clas( self.win, self.param_desc_path, env = dialog_env )
                # this parses the description file and makes the dialog,
                # but does not show it and does not connect a controller to it.
            #e set its geometry if that was saved (from above code or maybe in prefs db)
        return
Example #36
0
def _same_Numeric_array_helper(obj1, obj2):
    if obj1.typecode() != obj2.typecode():
        raise _NotTheSame
    if obj1.shape != obj2.shape:
        raise _NotTheSame
    if obj1.typecode() == PyObject:
        if env.debug():
            print "atom_debug: ran _same_Numeric_array_helper, PyObject case"  # remove when works once ###@@@
        # assume not multi-dimensional (if we are, this should work [untested] but it will be inefficient)
        for i in xrange(len(obj1)):
            _same_vals_helper(
                obj1[i], obj2[i]
            )  # two PyObjects (if obj1 is 1-dim) or two lower-dim Numeric arrays
    else:
        ##        if env.debug():
        ##            print "atom_debug: ran _same_Numeric_array_helper, non-PyObject case" # remove when works once ###@@@
        if obj1 != obj2:
            # take pointwise !=, then boolean value of that (correct, but is there a more efficient Numeric function?)
            # note: using '==' here (and negating boolean value of result) would NOT be correct
            raise _NotTheSame
    return
 def _in_event_loop_changed(
         self, beginflag, infodict,
         tracker):  # 060127; 060321 added infodict to API
     "[this bound method will be added to env.command_segment_subscribers so as to be told when ..."
     # infodict is info about the nature of the stack change, passed from the tracker [bruce 060321 for bug 1440 et al]
     # this makes "report all checkpoints" useless -- too many null ones.
     # maybe i should make it only report if state changes or cmdname passed...
     if not self.active:
         self.__begin_retval = False  #k probably doesn't matter
         return True  # unsubscribe
     # print beginflag, len(tracker.stack) # typical: True 1; False 0
     if 1:
         #bruce 060321 for bug 1440: we need to not do checkpoints in some cases. Not sure if this is correct re __begin_retval;
         # if not, either clean it up for that or pass the flag into the checkpoint routine to have it not really do the checkpoint
         # (which might turn out better for other reasons anyway, like tracking proper cmdnames for changes). ##e
         pushed = infodict.get('pushed')
         popped = infodict.get('popped')
         # zero or one of these exists, and is the op_run just pushed or popped from the stack
         if pushed is not None:
             typeflag = pushed.typeflag  # entering this guy
         elif popped is not None:
             typeflag = popped.typeflag  # leaving this guy (entering vs leaving doesn't matter for now)
         else:
             typeflag = ''  # does this ever happen? (probably not)
         want_cp = (typeflag != 'beginrec')
         if not want_cp:
             if 0 and env.debug():
                 print "debug: skipping cp as we enter or leave recursive event processing"
             return  # this might be problematic, see above comment [tho it seems to work for now, for Minimize All anyway];
             # if it ever is, then instead of returning here, we'll pass want_cp to checkpoint routines below
     if beginflag:
         self.__begin_retval = self.undo_checkpoint_before_command()
         ###e grab cmdname guess from top op_run i.e. from begin_op? yes for debugging; doesn't matter in the end though.
     else:
         if self.__begin_retval is None:
             # print "self.__begin_retval is None" # not a bug, will be normal ... happens with file open (as expected)
             self.__begin_retval = self.auto_checkpoint_pref()
         self.undo_checkpoint_after_command(self.__begin_retval)
         self.__begin_retval = False  # should not matter
     return
Example #38
0
 def _in_event_loop_changed(self, beginflag, infodict, tracker): # 060127; 060321 added infodict to API
     "[this bound method will be added to env.command_segment_subscribers so as to be told when ..."
     # infodict is info about the nature of the stack change, passed from the tracker [bruce 060321 for bug 1440 et al]
     # this makes "report all checkpoints" useless -- too many null ones.
     # maybe i should make it only report if state changes or cmdname passed...
     if not self.active:
         self.__begin_retval = False #k probably doesn't matter
         return True # unsubscribe
     # print beginflag, len(tracker.stack) # typical: True 1; False 0
     if 1:
         #bruce 060321 for bug 1440: we need to not do checkpoints in some cases. Not sure if this is correct re __begin_retval;
         # if not, either clean it up for that or pass the flag into the checkpoint routine to have it not really do the checkpoint
         # (which might turn out better for other reasons anyway, like tracking proper cmdnames for changes). ##e
         pushed = infodict.get('pushed')
         popped = infodict.get('popped')
         # zero or one of these exists, and is the op_run just pushed or popped from the stack
         if pushed is not None:
             typeflag = pushed.typeflag # entering this guy
         elif popped is not None:
             typeflag = popped.typeflag # leaving this guy (entering vs leaving doesn't matter for now)
         else:
             typeflag = '' # does this ever happen? (probably not)
         want_cp = (typeflag != 'beginrec')
         if not want_cp:
             if 0 and env.debug():
                 print "debug: skipping cp as we enter or leave recursive event processing"
             return # this might be problematic, see above comment [tho it seems to work for now, for Minimize All anyway];
                 # if it ever is, then instead of returning here, we'll pass want_cp to checkpoint routines below
     if beginflag:
         self.__begin_retval = self.undo_checkpoint_before_command()
             ###e grab cmdname guess from top op_run i.e. from begin_op? yes for debugging; doesn't matter in the end though.
     else:
         if self.__begin_retval is None:
             # print "self.__begin_retval is None" # not a bug, will be normal ... happens with file open (as expected)
             self.__begin_retval = self.auto_checkpoint_pref()
         self.undo_checkpoint_after_command( self.__begin_retval )
         self.__begin_retval = False # should not matter
     return
    def ok_btn_clicked(self):
        """
        Slot for OK button
        """
        QDialog.accept(self)
        if env.debug():
            print "ok"
        self.gather_parameters()
        ### kluge: has side effect on env.prefs
        # (should we pass these as arg to Minimize_CommandRun rather than thru env.prefs??)
        if debug_flags.atom_debug:
            print "debug: reloading runSim & sim_commandruns on each use, for development"
            import simulation.runSim as runSim
            reload_once_per_event(runSim)
                # bug: only works some of the times runSim.py is modified,
                # don't know why; might be that sim_commandruns.py
                # also needs to be modified, but touching them both
                # doesn't seem to work consistently either.
                # [bruce 080520]
            import simulation.sim_commandruns as sim_commandruns
            reload_once_per_event(sim_commandruns)
        from simulation.sim_commandruns import Minimize_CommandRun
        # do this in gather?
        if self.minimize_all_rbtn.isChecked():
            self.seltype = 'All'
            seltype_name = "All"
        else:
            self.seltype = 'Sel'
            seltype_name = "Selection"
        self.win.assy.current_command_info(cmdname = self.plain_cmdname + " (%s)" % seltype_name) # cmdname for Undo

        update_cond = self.ruc.get_update_cond_from_widgets()
        engine = self.minimize_engine_combobox.currentIndex()
        env.prefs[Minimize_minimizationEngine_prefs_key] = engine
        cmdrun = Minimize_CommandRun( self.win, self.seltype, type = 'Minimize', update_cond = update_cond, engine = engine)
        cmdrun.run()
        return
    return mgr.undo_cmds_menuspec(widget)

register_debug_menu_command_maker("undo_cmds", undo_cmds_maker)
# fyi: this runs once when the first assy is being created, but undo_cmds_maker runs every time the debug menu is put up.

# ==

# some global private state (which probably ought to be undo manager instance vars)

try:
    _editAutoCheckpointing_recursing
except:
    _editAutoCheckpointing_recursing = False
    # only if we're not reloading -- otherwise, bug when setChecked calls MWsem slot which reloads
else:
    if _editAutoCheckpointing_recursing and env.debug():
        pass  # print "note: _editAutoCheckpointing_recursing true during reload" # this happens!

try:
    _AutoCheckpointing_enabled  # on reload, use old value unchanged (since we often reload automatically during debugging)
except:
    _AutoCheckpointing_enabled = True  # this might be changed based on env.prefs whenever an undo_manager gets created [060314]
    # older comment about that, not fully obs:
    #e this might be revised to look at env.prefs sometime during app startup,
    # and to call editAutoCheckpointing (or some part of it) with the proper initial state;
    # the current code is designed, internally, for checkpointing to be enabled except
    # for certain intervals, so we might start out True and set this to False when
    # an undo_manager is created... we'll see; maybe it won't even (or mainly or only) be a global? [060309]


def _set_AutoCheckpointing_enabled(enabled):
 def begin(self):
     ##        if 1: # 060121 debug code
     ##            try:
     ##                se = self.sender() # this can only be tried when we inherit from QObject, but it always had this exception.
     ##            except RuntimeError: # underlying C/C++ object has been deleted [common, don't yet know why, but have a guess]
     ##                print "no sender"
     ##                pass
     ##            else:
     ##                print "sender",se
     ## cp_fn = None # None, or a true thing enabling us to call undo_checkpoint_after_command
     if 1:  #060127
         in_event_loop = env._in_event_loop
         mc = env.begin_op(
             "(wr)"
         )  # should always change env._in_event_loop to False (or leave it False)
         assert not env._in_event_loop
     if in_event_loop:  #060121, revised 060127 and cond changed from 1 to in_event_loop
         #e if necessary we could find out whether innermost op_run in changes.py's stack still *wants* a cmdname to be guessed...
         # this would be especially important if it turns out this runs in inner calls and guesses it wrong,
         # overwriting a correct guess from somewhere else...
         # also don't we need to make sure that the cmd_seg we're guessing for is the right one, somehow???
         # doesn't that mean the same as, this begin_op is the one that changed the boundary? (ie call came from event loop?)
         sender = self.__sender
         ##print "sender",sender # or could grab its icon for insertion into history
         from foundation.whatsthis_utilities import map_from_id_QAction_to_featurename
         fn = map_from_id_QAction_to_featurename.get(id(sender))
         # When we used sender rather than id(sender), the UI seemed noticably slower!!
         # Possible problem with using id() is for temporary items -- when they're gone,
         # newly allocated ones with same id might seem to have those featurenames.
         # Perhaps we need to verify the name is still present in the whatsthis text?
         # But we don't have the item itself here! We could keep it in the value, and then
         # it would stick around forever anyway so its id wouldn't be reused,
         # but we'd have a memory leak for dynamic menus. Hmm... maybe we could add our own
         # key attribute to these items? And also somehow remove temporary ones from this dict
         # soon after they go away, or when new temp items are created for same featurename?
         # ... Decision [nim]: use our own key attr, don't bother removing old items from dict,
         # the leak per-cmenu is smaller than others we have per-user-command. ####@@@@ DOIT
         if fn:
             if 1:  #experiment 060121
                 from utilities.debug import print_compact_traceback
                 try:
                     win = env.mainwindow()
                     assert win.initialised  # make sure it's not too early
                     assy = win.assy
                 except:
                     if debug_flags.atom_debug:
                         print_compact_traceback(
                             "atom_debug: fyi: normal exception: ")
                     pass  # this is normal during init... or at least I thought it would be -- I never actually saw it yet.
                 else:
                     ##                        begin_retval = assy.undo_checkpoint_before_command(fn)
                     ##                        cp_fn = fn, begin_retval #e this should include a retval from that method, but must also always be true
                     if 1:  #060127
                         # note, ideally this assy and the one that subscribes to command_segment changes
                         # should be found in the same way (ie that one should sub to this too) -- could this just iterate over
                         # same list and call it differently, with a different flag?? ##e
                         assy.current_command_info(
                             cmdname=fn
                         )  #e cmdname might be set more precisely by the slot we're wrapping
             if 0:
                 print " featurename =", fn
                 # This works! prints correct names for toolbuttons and main menu items.
                 # Doesn't work for glpane cmenu items, but I bet it will when we fix them to have proper WhatsThis text.
                 # Hmm, how will we do that? There is presently no formal connection between them and the usual qactions
                 # or toolbuttons or whatsthis features for the main UI for the same method. We might have to detect the
                 # identity of the bound method they call as a slot! Not sure if this is possible. If not, we have to set
                 # command names from inside the methods that implement them (not the end of the world), or grab them from
                 # history text (doable).
         else:
             #060320 debug code; note, this shows signals that might not need undo cp's, but for almost all signals,
             # they might in theory need them in the future for some recipients, so it's not usually safe to exclude them.
             # Instead, someday we'll optimize this more when no changes actually occurred (e.g. detect that above).
             if 0 and env.debug():
                 print "debug: wrappedslot found no featurename, signal = %r, sender = %r" % (
                     self.__signal, sender)
     ## return cp_fn, mc  #060123 revised retval
     return mc
Example #42
0
 def set_defaults(self, dict1):
     if env.debug():
         print "debug: set_defaults is nim" ####k is it even sensible w/o a controller being involved??
     return
 def setDisplay_command(self, widget):
     win = env.mainwindow()
     win.setDisplay(self.ind)
     if env.debug():
         print "setDisplay to %r.ind == %r" % (self, self.ind)
     return
Example #44
0
    def doMinimize(self, mtype = 1, simaspect = None):
        #bruce 051115 renamed method from makeMinMovie
        #bruce 051115 revised docstring to fit current code #e should clean it up more
        """
        Minimize self.part (if simaspect is None -- no longer used)
        or its given simaspect (simulatable aspect) (used for both Minimize Selection and Minimize All),
        generating and showing a movie (no longer asked for) or generating and applying to part an xyz file.

        The mtype flag means:
        1 = tell writemovie() to create a single-frame XYZ file.
        2 = tell writemovie() to create a multi-frame DPB moviefile.
            [###@@@ not presently used, might not work anymore]
        """
        assert mtype == 1 #bruce 051115
        assert simaspect is not None #bruce 051115
        #bruce 050324 made this from the Part method makeMinMovie.
        suffix = self.part.movie_suffix()
        if suffix is None: #bruce 050316 temporary kluge; as of circa 050326 this is not used anymore
            msg = "%s is not yet implemented for clipboard items." % self.word_Minimize
            env.history.message( redmsg( msg))
            return
        #e use suffix below? maybe no need since it's ok if the same filename is reused for this.

        # bruce 050325 change: don't use or modify self.assy.current_movie,
        # since we're not making a movie and don't want to prevent replaying
        # the one already stored from some sim run.
        # [this is for mtype == 1 (always true now) and might affect writemovie ###@@@ #k.]

        # NOTE: the movie object is used to hold params and results from minimize,
        # even if it makes an xyz file rather than a movie file.
        # And at the moment it never makes a movie file when called from this code.
        # [bruce 051115 comment about months-old situation]

        movie = Movie(self.assy)
            # do this in writemovie? no, the other call of it needs it passed in
            # from the dialog... #k
            # note that Movie class is misnamed since it's really a
            # SimRunnerAndResultsUser... which might use .xyz or .dpb results...
            # maybe rename it SimRun? ###e also, it needs subclasses for the
            # different kinds of sim runs and their results... or maybe it needs
            # a subobject which has such subclasses -- not yet sure. [bruce 050329]

        self._movie = movie
            #bruce 050415 kluge; note that class SimRun does the same thing.
            # Probably it means that this class, SimRun, and this way of using
            # class Movie should all be the same, or at least have more links
            # than they do now. ###@@@

        # Set update_cond for controlling realtime update settings for watching
        # this "movie" (an ongoing sim). There are three possible ways
        # (soon after A8 only the first one will be used) [bruce 060705]:
        # - caller specified it.
        # - if it didn't, use new common code to get it from General Prefs page.
        # - if that fails, use older code for that.
        #
        # WARNING: it turns out this happens whether or not the checkbox pref
        # says it should -- that is checked separately elsewhere! That's a bug,
        # since we need to use a different checkbox depending on the command.
        # let's see if we can consolidate the "enabling flag" into
        # update_cond itself? so it is None or False if we won't update.
        # this is now attempted...
        if env.debug():
            print "debug fyi: runSim/sim_commandruns watch_motion update_cond computed here " \
                  "(even if not watching motion)" #bruce 060705
        try:
            # Only the client code knows where to find the correct realtime
            # update settings widgets (or someday, knows whether these values
            # come from widgets at all, vs from a script).
            # It should figure out the update_cond
            # (False if we should not watch motion),
            # and tell us in self.kws['update_cond'].
            update_cond = self.kws['update_cond']
            assert update_cond or (update_cond is False) # a callable or False [remove when works]
            # WARNING: as of 080321, this apparently fails routinely
            # for Adjust All, and then the first fallback in the
            # except clause also fails (userPrefs.watch_motion_buttongroup
            # attributeerror), and then its fallback finally works.
            # Cleanup is severely needed. [bruce 080321 comment]
        except:
            ## print_compact_traceback("bug ...: ")
            if env.debug():
                print "debug: fyi: sim_commandruns grabbing userPrefs data"
            # For A8, this is normal, since only (at most) Minimize Energy sets self.kws['update_cond'] itself.
            # This will be used routinely in A8 by Adjust All and Adjust Selection, and maybe Adjust Atoms (not sure).
            #
            # Just get the values from the "Adjust" prefs page.
            # But at least try to do that using new common code.
            try:
                from widgets.widget_controllers import realtime_update_controller
                userPrefs = env.mainwindow().userPrefs
                from utilities.prefs_constants import Adjust_watchRealtimeMinimization_prefs_key
                    ###@@@ should depend on command, or be in movie...
                ruc = realtime_update_controller(
                    ( userPrefs.watch_motion_buttongroup,
                          # Note: watch_motion_buttongroup exists in MinimizeEnergyProp.py
                          # and in SimSetup.py and now its back in Preferences.py,
                          # so this is no longer a bug (for "Adjust All"). [mark 2008-06-04]
                      userPrefs.update_number_spinbox,
                      userPrefs.update_units_combobox ),
                    None, # checkbox ###@@@ maybe not needed, since UserPrefs sets up the connection #k
                    Adjust_watchRealtimeMinimization_prefs_key )
                update_cond = ruc.get_update_cond_from_widgets()
                # note, if those widgets are connected to env.prefs, that's not handled here or in ruc;
                # I'm not sure if they are. Ideally we'd tell ruc the prefs_keys and have it handle that too,
                # perhaps making it a long-lived object (though that might not be necessary).
                assert update_cond or (update_cond is False) # a callable or False
            except:
                # even that didn't work. Complain, then fall back to otherwise-obsolete old code.
                msg = "bug using realtime_update_controller in sim_commandruns, will use older code instead: "
                print_compact_traceback(msg)
                # This code works (except for always using the widgets from the General Prefs page,
                # even for Minimize Energy), but I'll try to replace it with calls to common code.
                # [bruce 060705]
                # This code for setting update_cond is duplicated (inexactly)
                # in SimSetup.createMoviePressed() in SimSetup.py.
                userPrefs = env.mainwindow().userPrefs
                update_units = userPrefs.update_units_combobox.currentText()
                update_number = userPrefs.update_number_spinbox.value()
                if userPrefs.update_asap_rbtn.isChecked():
                    update_cond = ( lambda simtime, pytime, nframes:
                                    simtime >= max(0.05, min(pytime * 4, 2.0)) )
                elif update_units == 'frames':
                    update_cond = ( lambda simtime, pytime, nframes, _nframes = update_number:  nframes >= _nframes )
                elif update_units == 'seconds':
                    update_cond = ( lambda simtime, pytime, nframes, _timelimit = update_number:  simtime + pytime >= _timelimit )
                elif update_units == 'minutes':
                    update_cond = ( lambda simtime, pytime, nframes, _timelimit = update_number * 60:  simtime + pytime >= _timelimit )
                elif update_units == 'hours':
                    update_cond = ( lambda simtime, pytime, nframes, _timelimit = update_number * 3600:  simtime + pytime >= _timelimit )
                else:
                    print "don't know how to set update_cond from (%r, %r)" % (update_number, update_units)
                    update_cond = None
                # new as of 060705, in this old code
                if not env.prefs[Adjust_watchRealtimeMinimization_prefs_key]:
                    update_cond = False
            pass
        # now do this with update_cond, however it was computed
        movie.update_cond = update_cond

        # semi-obs comment, might still be useful [as of 050406]:
        # Minimize Selection [bruce 050330] (ought to be a distinct
        # command subclass...) this will use the spawning code in writemovie
        # but has its own way of writing the mmp file.
        # To make this clean, we need to turn writemovie into more than one
        # method of a class with more than one subclass, so we can override
        # one of them (writing mmp file) and another one (finding atom list).
        # But to get it working I might just kluge it
        # by passing it some specialized options... ###@@@ not sure

        movie._cmdname = self.cmdname
            #bruce 050415 kluge so writemovie knows proper progress bar caption to use
            # (not really wrong -- appropriate for only one of several
            # classes Movie should be split into, i.e. one for the way we're using it here,
            # to know how to run the sim, which is perhaps really self (a SimRunner),
            # once the code is fully cleaned up.
            # [review: is that the same SimRunner which is by 080321
            #  a real class in runSim?]

        # write input for sim, and run sim
        # this also sets movie.alist from simaspect
        r = writemovie(self.part,
                       movie,
                       mtype,
                       simaspect = simaspect,
                       print_sim_warnings = True,
                       cmdname = self.cmdname,
                       cmd_type = self.cmd_type,
                       useGromacs = self.useGromacs,
                       background = self.background)
        if r:
            # We had a problem writing the minimize file.
            # Simply return (error message already emitted by writemovie). ###k
            return

        if mtype == 1:  # Load single-frame XYZ file.
            if (self.useGromacs):
                if (self.background):
                    return
                tracefileProcessor = movie._simrun.tracefileProcessor
                newPositions = readGromacsCoordinates(movie.filename + "-out.gro", movie.alist, tracefileProcessor)
            else:
                newPositions = readxyz( movie.filename, movie.alist )
                    # movie.alist is now created in writemovie [bruce 050325]
            # retval is either a list of atom posns or an error message string.
            assert type(newPositions) in [type([]),type("")]
            if type(newPositions) == type([]):
                #bruce 060102 note: following code is approximately duplicated somewhere else in this file.
                movie.moveAtoms(newPositions)
                # bruce 050311 hand-merged mark's 1-line bugfix in assembly.py (rev 1.135):
                self.part.changed() # Mark - bugfix 386
                self.part.gl_update()
            else:
                #bruce 050404: print error message to history
                env.history.message(redmsg( newPositions))
        else: # Play multi-frame DPB movie file.
            ###@@@ bruce 050324 comment: can this still happen? [no] is it correct [probably not]
            # (what about changing mode to movieMode, does it ever do that?) [don't know]
            # I have not reviewed this and it's obviously not cleaned up (since it modifies private movie attrs).
            # But I will have this change the current movie, which would be correct in theory, i think, and might be needed
            # before trying to play it (or might be a side effect of playing it, this is not reviewed either).
            ###e bruce 050428 comment: if self.assy.current_movie exists, should do something like close or destroy it... need to review
            self.assy.current_movie = movie
            # If cueMovie() returns a non-zero value, something went wrong loading the movie.
            if movie.cueMovie():
                return
            movie._play()
            movie._close()
        return
Example #45
0
 def set_defaults(self, dict1):
     if env.debug():
         print "debug: set_defaults is nim"  ####k is it even sensible w/o a controller being involved??
     return
 def dismissed(self):
     if env.debug():
         print "debug fyi: dismissed -- should we tell owner to destroy us? is it even still there?" ####@@@@
     self.destroy() # let's just take the initiative ourselves, though it might cause bugs, maybe we should do it later...
Example #47
0
    def doMinimize(self, mtype=1, simaspect=None):
        #bruce 051115 renamed method from makeMinMovie
        #bruce 051115 revised docstring to fit current code #e should clean it up more
        """
        Minimize self.part (if simaspect is None -- no longer used)
        or its given simaspect (simulatable aspect) (used for both Minimize Selection and Minimize All),
        generating and showing a movie (no longer asked for) or generating and applying to part an xyz file.

        The mtype flag means:
        1 = tell writemovie() to create a single-frame XYZ file.
        2 = tell writemovie() to create a multi-frame DPB moviefile.
            [###@@@ not presently used, might not work anymore]
        """
        assert mtype == 1  #bruce 051115
        assert simaspect is not None  #bruce 051115
        #bruce 050324 made this from the Part method makeMinMovie.
        suffix = self.part.movie_suffix()
        if suffix is None:  #bruce 050316 temporary kluge; as of circa 050326 this is not used anymore
            msg = "%s is not yet implemented for clipboard items." % self.word_Minimize
            env.history.message(redmsg(msg))
            return
        #e use suffix below? maybe no need since it's ok if the same filename is reused for this.

        # bruce 050325 change: don't use or modify self.assy.current_movie,
        # since we're not making a movie and don't want to prevent replaying
        # the one already stored from some sim run.
        # [this is for mtype == 1 (always true now) and might affect writemovie ###@@@ #k.]

        # NOTE: the movie object is used to hold params and results from minimize,
        # even if it makes an xyz file rather than a movie file.
        # And at the moment it never makes a movie file when called from this code.
        # [bruce 051115 comment about months-old situation]

        movie = Movie(self.assy)
        # do this in writemovie? no, the other call of it needs it passed in
        # from the dialog... #k
        # note that Movie class is misnamed since it's really a
        # SimRunnerAndResultsUser... which might use .xyz or .dpb results...
        # maybe rename it SimRun? ###e also, it needs subclasses for the
        # different kinds of sim runs and their results... or maybe it needs
        # a subobject which has such subclasses -- not yet sure. [bruce 050329]

        self._movie = movie
        #bruce 050415 kluge; note that class SimRun does the same thing.
        # Probably it means that this class, SimRun, and this way of using
        # class Movie should all be the same, or at least have more links
        # than they do now. ###@@@

        # Set update_cond for controlling realtime update settings for watching
        # this "movie" (an ongoing sim). There are three possible ways
        # (soon after A8 only the first one will be used) [bruce 060705]:
        # - caller specified it.
        # - if it didn't, use new common code to get it from General Prefs page.
        # - if that fails, use older code for that.
        #
        # WARNING: it turns out this happens whether or not the checkbox pref
        # says it should -- that is checked separately elsewhere! That's a bug,
        # since we need to use a different checkbox depending on the command.
        # let's see if we can consolidate the "enabling flag" into
        # update_cond itself? so it is None or False if we won't update.
        # this is now attempted...
        if env.debug():
            print "debug fyi: runSim/sim_commandruns watch_motion update_cond computed here " \
                  "(even if not watching motion)" #bruce 060705
        try:
            # Only the client code knows where to find the correct realtime
            # update settings widgets (or someday, knows whether these values
            # come from widgets at all, vs from a script).
            # It should figure out the update_cond
            # (False if we should not watch motion),
            # and tell us in self.kws['update_cond'].
            update_cond = self.kws['update_cond']
            assert update_cond or (update_cond is False
                                   )  # a callable or False [remove when works]
            # WARNING: as of 080321, this apparently fails routinely
            # for Adjust All, and then the first fallback in the
            # except clause also fails (userPrefs.watch_motion_buttongroup
            # attributeerror), and then its fallback finally works.
            # Cleanup is severely needed. [bruce 080321 comment]
        except:
            ## print_compact_traceback("bug ...: ")
            if env.debug():
                print "debug: fyi: sim_commandruns grabbing userPrefs data"
            # For A8, this is normal, since only (at most) Minimize Energy sets self.kws['update_cond'] itself.
            # This will be used routinely in A8 by Adjust All and Adjust Selection, and maybe Adjust Atoms (not sure).
            #
            # Just get the values from the "Adjust" prefs page.
            # But at least try to do that using new common code.
            try:
                from widgets.widget_controllers import realtime_update_controller
                userPrefs = env.mainwindow().userPrefs
                from utilities.prefs_constants import Adjust_watchRealtimeMinimization_prefs_key
                ###@@@ should depend on command, or be in movie...
                ruc = realtime_update_controller(
                    (
                        userPrefs.watch_motion_buttongroup,
                        # Note: watch_motion_buttongroup exists in MinimizeEnergyProp.py
                        # and in SimSetup.py and now its back in Preferences.py,
                        # so this is no longer a bug (for "Adjust All"). [mark 2008-06-04]
                        userPrefs.update_number_spinbox,
                        userPrefs.update_units_combobox),
                    None,  # checkbox ###@@@ maybe not needed, since UserPrefs sets up the connection #k
                    Adjust_watchRealtimeMinimization_prefs_key)
                update_cond = ruc.get_update_cond_from_widgets()
                # note, if those widgets are connected to env.prefs, that's not handled here or in ruc;
                # I'm not sure if they are. Ideally we'd tell ruc the prefs_keys and have it handle that too,
                # perhaps making it a long-lived object (though that might not be necessary).
                assert update_cond or (update_cond is False
                                       )  # a callable or False
            except:
                # even that didn't work. Complain, then fall back to otherwise-obsolete old code.
                msg = "bug using realtime_update_controller in sim_commandruns, will use older code instead: "
                print_compact_traceback(msg)
                # This code works (except for always using the widgets from the General Prefs page,
                # even for Minimize Energy), but I'll try to replace it with calls to common code.
                # [bruce 060705]
                # This code for setting update_cond is duplicated (inexactly)
                # in SimSetup.createMoviePressed() in SimSetup.py.
                userPrefs = env.mainwindow().userPrefs
                update_units = userPrefs.update_units_combobox.currentText()
                update_number = userPrefs.update_number_spinbox.value()
                if userPrefs.update_asap_rbtn.isChecked():
                    update_cond = (lambda simtime, pytime, nframes: simtime >=
                                   max(0.05, min(pytime * 4, 2.0)))
                elif update_units == 'frames':
                    update_cond = (lambda simtime, pytime, nframes, _nframes=
                                   update_number: nframes >= _nframes)
                elif update_units == 'seconds':
                    update_cond = (
                        lambda simtime, pytime, nframes, _timelimit=
                        update_number: simtime + pytime >= _timelimit)
                elif update_units == 'minutes':
                    update_cond = (
                        lambda simtime, pytime, nframes, _timelimit=
                        update_number * 60: simtime + pytime >= _timelimit)
                elif update_units == 'hours':
                    update_cond = (
                        lambda simtime, pytime, nframes, _timelimit=
                        update_number * 3600: simtime + pytime >= _timelimit)
                else:
                    print "don't know how to set update_cond from (%r, %r)" % (
                        update_number, update_units)
                    update_cond = None
                # new as of 060705, in this old code
                if not env.prefs[Adjust_watchRealtimeMinimization_prefs_key]:
                    update_cond = False
            pass
        # now do this with update_cond, however it was computed
        movie.update_cond = update_cond

        # semi-obs comment, might still be useful [as of 050406]:
        # Minimize Selection [bruce 050330] (ought to be a distinct
        # command subclass...) this will use the spawning code in writemovie
        # but has its own way of writing the mmp file.
        # To make this clean, we need to turn writemovie into more than one
        # method of a class with more than one subclass, so we can override
        # one of them (writing mmp file) and another one (finding atom list).
        # But to get it working I might just kluge it
        # by passing it some specialized options... ###@@@ not sure

        movie._cmdname = self.cmdname
        #bruce 050415 kluge so writemovie knows proper progress bar caption to use
        # (not really wrong -- appropriate for only one of several
        # classes Movie should be split into, i.e. one for the way we're using it here,
        # to know how to run the sim, which is perhaps really self (a SimRunner),
        # once the code is fully cleaned up.
        # [review: is that the same SimRunner which is by 080321
        #  a real class in runSim?]

        # write input for sim, and run sim
        # this also sets movie.alist from simaspect
        r = writemovie(self.part,
                       movie,
                       mtype,
                       simaspect=simaspect,
                       print_sim_warnings=True,
                       cmdname=self.cmdname,
                       cmd_type=self.cmd_type,
                       useGromacs=self.useGromacs,
                       background=self.background)
        if r:
            # We had a problem writing the minimize file.
            # Simply return (error message already emitted by writemovie). ###k
            return

        if mtype == 1:  # Load single-frame XYZ file.
            if (self.useGromacs):
                if (self.background):
                    return
                tracefileProcessor = movie._simrun.tracefileProcessor
                newPositions = readGromacsCoordinates(
                    movie.filename + "-out.gro", movie.alist,
                    tracefileProcessor)
            else:
                newPositions = readxyz(movie.filename, movie.alist)
                # movie.alist is now created in writemovie [bruce 050325]
            # retval is either a list of atom posns or an error message string.
            assert type(newPositions) in [type([]), type("")]
            if type(newPositions) == type([]):
                #bruce 060102 note: following code is approximately duplicated somewhere else in this file.
                movie.moveAtoms(newPositions)
                # bruce 050311 hand-merged mark's 1-line bugfix in assembly.py (rev 1.135):
                self.part.changed()  # Mark - bugfix 386
                self.part.gl_update()
            else:
                #bruce 050404: print error message to history
                env.history.message(redmsg(newPositions))
        else:  # Play multi-frame DPB movie file.
            ###@@@ bruce 050324 comment: can this still happen? [no] is it correct [probably not]
            # (what about changing mode to movieMode, does it ever do that?) [don't know]
            # I have not reviewed this and it's obviously not cleaned up (since it modifies private movie attrs).
            # But I will have this change the current movie, which would be correct in theory, i think, and might be needed
            # before trying to play it (or might be a side effect of playing it, this is not reviewed either).
            ###e bruce 050428 comment: if self.assy.current_movie exists, should do something like close or destroy it... need to review
            self.assy.current_movie = movie
            # If cueMovie() returns a non-zero value, something went wrong loading the movie.
            if movie.cueMovie():
                return
            movie._play()
            movie._close()
        return
Example #48
0
    def createMoviePressed(self):
        """
        Creates a DPB (movie) file of the current part.
        [Actually only saves the params and filename which should be used
         by the client code (in writemovie?) to create that file.]
        The part does not have to be saved as an MMP file first, as it used to.
        """
        ###@@@ bruce 050324 comment: Not sure if/when user can rename the file.
        QDialog.accept(self)

        if self.simulation_engine_combobox.currentIndex() == 1:
            # GROMACS was selected as the simulation engine.
            #
            # NOTE: This code is just for demo and prototyping purposes - the
            # real approach will be architected and utilize plugins.
            #
            # Brian Helfrich 2007-04-06
            #
            from simulation.GROMACS.GROMACS import GROMACS
            gmx = GROMACS(self.assy.part)
            gmx.run("md")

        else:
            # NanoDynamics-1 was selected as the simulation engine
            #
            errorcode, partdir = self.assy.find_or_make_part_files_directory()

            self.movie.cancelled = False # This is the only way caller can tell we succeeded.
            self.movie.totalFramesRequested = self.totalFramesSpinBox.value()
            self.movie.temp = self.temperatureSpinBox.value()
            self.movie.stepsper = self.stepsPerFrameDoubleSpinBox.value() * 10.0
            self.movie.print_energy = self.potential_energy_checkbox.isChecked()
    #        self.movie.timestep = self.timestepSB.value() # Not supported in Alpha
            #self.movie.create_movie_file = self.create_movie_file_checkbox.isChecked()
                # removed for A7 (bug 1729). mark 060321
            self.movie.create_movie_file = True

            # compute update_data and update_cond, using new or old code
            try:
                # try new common code for this, bruce 060705
                ruc = self.ruc
                update_cond = ruc.get_update_cond_from_widgets()
                assert update_cond or (update_cond is False) ###@@@ remove when works, and all the others like this
                # note, if those widgets are connected to env.prefs, that's not handled here or in ruc;
                # I'm not sure if they are. Ideally we'd tell ruc the prefs_keys and have it handle that too,
                # perhaps making it a long-lived object (though that might not be necessary).
                update_data = ruc.get_update_data_from_widgets() # redundant, but we can remove it when ruc handles prefs
            except:
                print_compact_traceback("bug using realtime_update_controller in SimSetup, will use older code instead: ")
                    # this older code can be removed after A8 if we don't see that message
                #bruce 060530 use new watch_motion rate parameters
                self.movie.watch_motion = self.watch_motion_groupbox.isChecked() # [deprecated for setattr as of 060705]
                if env.debug():
                    print "debug fyi: sim setup watch_motion = %r" % (self.movie.watch_motion,)
                # This code works, but I'll try to replace it with calls to common code (above). [bruce 060705]
                # first grab them from the UI
                update_as_fast_as_possible_data = self.watch_motion_groupbox.selectedId() # 0 means yes, 1 means no (for now)
                    # ( or -1 means neither, but that's prevented by how the button group is set up, at least when it's enabled)
                update_as_fast_as_possible = (update_as_fast_as_possible_data != 1)
                update_number = self.update_number_spinbox.value() # 1, 2, etc (or perhaps 0??)
                update_units = str(self.update_units_combobox.currentText()) # 'frames', 'seconds', 'minutes', 'hours'
                # for sake of propogating them to the next sim run:
                update_data = update_number, update_units, update_as_fast_as_possible_data, self.movie.watch_motion
    ##                if env.debug():
    ##                    print "stored _update_data %r into movie %r" % (self.movie._update_data, self.movie)
    ##                    print "debug: self.watch_motion_groupbox.selectedId() = %r" % (update_as_fast_as_possible_data,)
    ##                    print "debug: self.update_number_spinbox.value() is %r" % self.update_number_spinbox.value() # e.g. 1
    ##                    print "debug: combox text is %r" % str(self.update_units_combobox.currentText()) # e.g. 'frames'
                # Now figure out what these user settings mean our realtime updating algorithm should be,
                # as a function to be used for deciding whether to update the 3D view when each new frame is received,
                # which takes as arguments the time since the last update finished (simtime), the time that update took (pytime),
                # and the number of frames since then (nframes, 1 or more), and returns a boolean for whether to draw this new frame.
                # Notes:
                # - The Qt progress update will be done independently of this, at most once per second (in runSim.py).
                # - The last frame we expect to receive will always be drawn. (This func may be called anyway in case it wants
                #   to do something else with the info like store it somewhere, or it may not (check runSim.py for details #k),
                #   but its return value will be ignored if it's called for the last frame.)
                # The details of these functions (and the UI feeding them) might be revised.

                # This code for setting update_cond is duplicated (inexactly) in Minimize_CommandRun.doMinimize()
                if update_as_fast_as_possible:
                    # This radiobutton might be misnamed; it really means "use the old code,
                    # i.e. not worse than 20% slowdown, with threshholds".
                    # It's also ambiguous -- does "fast" mean "fast progress"
                    # or "often" (which are opposites)? It sort of means "often".
                    update_cond = ( lambda simtime, pytime, nframes:
                                    simtime >= max(0.05, min(pytime * 4, 2.0)) )
                elif update_units == 'frames':
                    update_cond = ( lambda simtime, pytime, nframes, _nframes = update_number:  nframes >= _nframes )
                elif update_units == 'seconds':
                    update_cond = ( lambda simtime, pytime, nframes, _timelimit = update_number:  simtime + pytime >= _timelimit )
                elif update_units == 'minutes':
                    update_cond = ( lambda simtime, pytime, nframes, _timelimit = update_number * 60:  simtime + pytime >= _timelimit )
                elif update_units == 'hours':
                    update_cond = ( lambda simtime, pytime, nframes, _timelimit = update_number * 3600:  simtime + pytime >= _timelimit )
                else:
                    print "don't know how to set update_cond from (%r, %r)" % (update_number, update_units)
                    update_cond = None
                # revision in this old code, 060705:
                if not self.movie.watch_motion:
                    update_cond = False
                del self.movie.watch_motion # let getattr do it
            # now do this, however we got update_data and update_cond:
            self.movie._update_data = update_data # for propogating them to the next sim run
            self.movie.update_cond = update_cond # used this time
            # end of 060705 changes

            suffix = self.suffix
            tStamp = timeStamp()
            if self.assy.filename and not errorcode: # filename could be an MMP or PDB file.
                import shutil
                dir, fil = os.path.split(self.assy.filename)
                fil, ext = os.path.splitext(fil)
                self.movie.filename = os.path.join(partdir, fil + '.' + tStamp + suffix + '.dpb')
                self.movie.origfile = os.path.join(partdir, fil + '.' + tStamp + '.orig' + ext)
                shutil.copy(self.assy.filename, self.movie.origfile)
            else:
                self.movie.filename = os.path.join(self.assy.w.tmpFilePath, "Untitled.%s%s.dpb" % (tStamp, suffix))
                # Untitled parts usually do not have a filename
            #bruce 060601 fix bug 1840, also make params sticky across opening of new files
            global _stickyParams
            _stickyParams = FakeMovie(self.movie) # these will be used as default params next time, whether or not this gets aborted
            return
Example #49
0
    def raytrace_scene(self, tmpscene = False):
        """
        Render scene. 
        If tmpscene is False, the INI and pov files are written to the 'POV-Ray Scene Files' directory.
        If tmpscene is True, the INI and pov files are written to a temporary directory (~/Nanorex/POV-Ray).
        Callers should set <tmpscene> = True when they want to render the scene but don't need to 
        save the files and create a POV-Ray Scene node in the MT (i.e. 'View > POV-Ray').
        The caller is responsible for adding the POV-Ray Scene node (self) to the model tree, if desired.
        Prints any necessary error messages to history; returns nothing.
        """
        #bruce 060710 corrected inaccuracies in docstring
        cmd = greenmsg("POV-Ray: ")
        if env.debug():
            #bruce 060707 (after Windows A8, before Linux/Mac A8)
            # compromise with what's best, so it can be ok for A8 even if only on some platforms
            env.history.message(_graymsg("POV-Ray: "))
            env.history.h_update()
            env.history.widget.update() ###@@@ will this help? is it safe? should h_update do it?
        
        ini, pov, out = self.get_povfile_trio(tmpscene)
        
        if not ini:
            ## return 1, "Problem getting POV-Ray filename trio."
            # [bruce 060710 replaced the above with the following, since it no longer matches the other return statements, or any calls]
            env.history.message(cmd + redmsg("Problem getting POV-Ray filename trio."))
                ###e should fix this to improve the message, by including errortext from get_povfile_trio retval (which is nim)
            return

        if tmpscene or not os.path.isfile(self.povrayscene_file):
            # write a new .pov file and save its name in self
            #
            #bruce 060711 comment (about a bug, not yet reported): ###@@@
            #   If an existing pov file has unexpectedly gone missing,
            # this code (I think) rerenders the current model, without even informing the user of the apparent error.
            #   That is extremely bad behavior, IMHO. What it ought to do is put up a dialog to inform the
            # user that the file is missing, and allow one of three actions: cancel, rerender current model,
            # or browse for the file to try to find it. If that browse is cancelled, it should offer the other
            # options, or if that finds the file but it's external, it should offer to copy it or make an
            # external link (or cancel), and then to continue or do no more. All this is desirable for any kind
            # of file node, not just PovrayScene. As it is, this won't be fixed for Mac A8; don't know about 8.1.
            self.povrayscene_file = pov
            writepovfile(self.assy.part, self.assy.o, self.povrayscene_file)
                # bruce 060711 question (possible bug): what sets self.width, self.height,  self.output_type in this case,
                # if the ones used by writepovfile differ from last time they were set in this node?
                # Guess: nothing does (bug, not yet reported). ###@@@

        # figure out renderer to use (POV-Ray or MegaPOV), its path, and its include_dir
        # (note: this contains most of the error checks that used to be inside launch_povray_or_megapov)
        # [bruce 060711 for Mac A8]
        win = self.assy.w
        ask_for_help = True # give user the chance to fix problems in the prefs dialog
        errorcode, errortext_or_info = decode_povray_prefs(win, ask_for_help, greencmd = cmd)
        if errorcode:
            errortext = errortext_or_info
            env.history.message(cmd + redmsg(errortext)) # redmsg in Mac A8, orangemsg in Windows A8 [bruce 060711]
            return
        info = errortext_or_info
        (program_nickname, program_path, include_dir) = info

        pov = self.povrayscene_file ###k btw, is this already true?

        #k is out equal to whatever in self might store it, if anything? maybe it's not stored in self.

        write_povray_ini_file(ini, pov, out, info, self.width, self.height, self.output_type)
        
        if tmpscene:
            msg = "Rendering scene. Please wait..."
        else:
            msg = "Rendering raytrace image from POV-Ray Scene file. Please wait..."
        env.history.message(cmd + msg)
        env.history.h_update() #bruce 060707 (after Windows A8, before Linux/Mac A8): try to make this message visible sooner
            # (doesn't work well enough, at least on Mac -- do we need to emit it before write_povray_ini_file?)
        env.history.widget.update() ###@@@ will this help? is it safe? should h_update do it?
        ###e these history widget updates fail to get it to print. Guess: we'd need qapp process events. Fix after Mac A8.
        # besides, we need this just before the launch call, not here.

        if os.path.exists(out): #bruce 060711 in Mac A8 not Windows A8 (probably all of Mac A8 code will also be in Linux A8)
            #e should perhaps first try moving the file to a constant name, so user could recover it manually if they wanted to
            #e (better yet, we should also try to avoid this situation when choosing the filename)
            msg = "Warning: image file already exists; removing it first [%s]" % out
            env.history.message(cmd + orangemsg(msg))
            try:
                os.remove(out)
            except:
                # this code was tested with a fake exception [060712 1041am]
                msg1 = "Problem removing old image file"
                msg2a = " [%s]" % out
                msg2b = "-- will try to overwrite it, "\
                      "but undetected rendering errors might leave it unchanged [%s]" % out
                print_compact_traceback("%s: " % (msg1 + msg2a))
                msg = redmsg(msg1) + msg2b
                #e should report the exception text in the history, too
                env.history.message(msg)
            pass
        
        # Launch raytrace program (POV-Ray or MegaPOV)
        errorcode, errortext = launch_povray_or_megapov(win, info, ini)
        
        if errorcode:
            env.history.message(cmd + redmsg(errortext)) # redmsg in Mac A8, orangemsg in Windows A8 [bruce 060711]
            return
        
        #bruce 060707 (after Windows A8, before Linux/Mac A8): make sure the image file exists.
        # (On Mac, on that date [not anymore, 060710], we get this far (no error return, or maybe another bug hid one),
        # but the file is not there.)
        if not os.path.exists(out):
            msg = "Error: %s program finished, but failed to produce expected image file [%s]" % (program_nickname, out)
            env.history.message(cmd + redmsg(msg))
            return
        
        env.history.message(cmd + "Rendered image: " + out)
        
        # Display image in a window.
        imageviewer = ImageViewer(out, win)
            #bruce 060707 comment: if the file named <out> doesn't exist, on Mac,
            # this produces a visible and draggable tiny window, about 3 pixels wide and maybe 30 pixels high.
        imageviewer.display()
        
        return # from raytrace_scene out
    def raytrace_scene(self, tmpscene=False):
        """
        Render scene. 
        If tmpscene is False, the INI and pov files are written to the 'POV-Ray Scene Files' directory.
        If tmpscene is True, the INI and pov files are written to a temporary directory (~/Nanorex/POV-Ray).
        Callers should set <tmpscene> = True when they want to render the scene but don't need to 
        save the files and create a POV-Ray Scene node in the MT (i.e. 'View > POV-Ray').
        The caller is responsible for adding the POV-Ray Scene node (self) to the model tree, if desired.
        Prints any necessary error messages to history; returns nothing.
        """
        #bruce 060710 corrected inaccuracies in docstring
        cmd = greenmsg("POV-Ray: ")
        if env.debug():
            #bruce 060707 (after Windows A8, before Linux/Mac A8)
            # compromise with what's best, so it can be ok for A8 even if only on some platforms
            env.history.message(_graymsg("POV-Ray: "))
            env.history.h_update()
            env.history.widget.update(
            )  ###@@@ will this help? is it safe? should h_update do it?

        ini, pov, out = self.get_povfile_trio(tmpscene)

        if not ini:
            ## return 1, "Problem getting POV-Ray filename trio."
            # [bruce 060710 replaced the above with the following, since it no longer matches the other return statements, or any calls]
            env.history.message(
                cmd + redmsg("Problem getting POV-Ray filename trio."))
            ###e should fix this to improve the message, by including errortext from get_povfile_trio retval (which is nim)
            return

        if tmpscene or not os.path.isfile(self.povrayscene_file):
            # write a new .pov file and save its name in self
            #
            #bruce 060711 comment (about a bug, not yet reported): ###@@@
            #   If an existing pov file has unexpectedly gone missing,
            # this code (I think) rerenders the current model, without even informing the user of the apparent error.
            #   That is extremely bad behavior, IMHO. What it ought to do is put up a dialog to inform the
            # user that the file is missing, and allow one of three actions: cancel, rerender current model,
            # or browse for the file to try to find it. If that browse is cancelled, it should offer the other
            # options, or if that finds the file but it's external, it should offer to copy it or make an
            # external link (or cancel), and then to continue or do no more. All this is desirable for any kind
            # of file node, not just PovrayScene. As it is, this won't be fixed for Mac A8; don't know about 8.1.
            self.povrayscene_file = pov
            writepovfile(self.assy.part, self.assy.o, self.povrayscene_file)
            # bruce 060711 question (possible bug): what sets self.width, self.height,  self.output_type in this case,
            # if the ones used by writepovfile differ from last time they were set in this node?
            # Guess: nothing does (bug, not yet reported). ###@@@

        # figure out renderer to use (POV-Ray or MegaPOV), its path, and its include_dir
        # (note: this contains most of the error checks that used to be inside launch_povray_or_megapov)
        # [bruce 060711 for Mac A8]
        win = self.assy.w
        ask_for_help = True  # give user the chance to fix problems in the prefs dialog
        errorcode, errortext_or_info = decode_povray_prefs(win,
                                                           ask_for_help,
                                                           greencmd=cmd)
        if errorcode:
            errortext = errortext_or_info
            env.history.message(
                cmd + redmsg(errortext)
            )  # redmsg in Mac A8, orangemsg in Windows A8 [bruce 060711]
            return
        info = errortext_or_info
        (program_nickname, program_path, include_dir) = info

        pov = self.povrayscene_file  ###k btw, is this already true?

        #k is out equal to whatever in self might store it, if anything? maybe it's not stored in self.

        write_povray_ini_file(ini, pov, out, info, self.width, self.height,
                              self.output_type)

        if tmpscene:
            msg = "Rendering scene. Please wait..."
        else:
            msg = "Rendering raytrace image from POV-Ray Scene file. Please wait..."
        env.history.message(cmd + msg)
        env.history.h_update(
        )  #bruce 060707 (after Windows A8, before Linux/Mac A8): try to make this message visible sooner
        # (doesn't work well enough, at least on Mac -- do we need to emit it before write_povray_ini_file?)
        env.history.widget.update(
        )  ###@@@ will this help? is it safe? should h_update do it?
        ###e these history widget updates fail to get it to print. Guess: we'd need qapp process events. Fix after Mac A8.
        # besides, we need this just before the launch call, not here.

        if os.path.exists(
                out
        ):  #bruce 060711 in Mac A8 not Windows A8 (probably all of Mac A8 code will also be in Linux A8)
            #e should perhaps first try moving the file to a constant name, so user could recover it manually if they wanted to
            #e (better yet, we should also try to avoid this situation when choosing the filename)
            msg = "Warning: image file already exists; removing it first [%s]" % out
            env.history.message(cmd + orangemsg(msg))
            try:
                os.remove(out)
            except:
                # this code was tested with a fake exception [060712 1041am]
                msg1 = "Problem removing old image file"
                msg2a = " [%s]" % out
                msg2b = "-- will try to overwrite it, "\
                      "but undetected rendering errors might leave it unchanged [%s]" % out
                print_compact_traceback("%s: " % (msg1 + msg2a))
                msg = redmsg(msg1) + msg2b
                #e should report the exception text in the history, too
                env.history.message(msg)
            pass

        # Launch raytrace program (POV-Ray or MegaPOV)
        errorcode, errortext = launch_povray_or_megapov(win, info, ini)

        if errorcode:
            env.history.message(
                cmd + redmsg(errortext)
            )  # redmsg in Mac A8, orangemsg in Windows A8 [bruce 060711]
            return

        #bruce 060707 (after Windows A8, before Linux/Mac A8): make sure the image file exists.
        # (On Mac, on that date [not anymore, 060710], we get this far (no error return, or maybe another bug hid one),
        # but the file is not there.)
        if not os.path.exists(out):
            msg = "Error: %s program finished, but failed to produce expected image file [%s]" % (
                program_nickname, out)
            env.history.message(cmd + redmsg(msg))
            return

        env.history.message(cmd + "Rendered image: " + out)

        # Display image in a window.
        imageviewer = ImageViewer(out, win)
        #bruce 060707 comment: if the file named <out> doesn't exist, on Mac,
        # this produces a visible and draggable tiny window, about 3 pixels wide and maybe 30 pixels high.
        imageviewer.display()

        return  # from raytrace_scene out
Example #51
0
    def begin(self):
##        if 1: # 060121 debug code
##            try:
##                se = self.sender() # this can only be tried when we inherit from QObject, but it always had this exception.
##            except RuntimeError: # underlying C/C++ object has been deleted [common, don't yet know why, but have a guess]
##                print "no sender"
##                pass
##            else:
##                print "sender",se
        ## cp_fn = None # None, or a true thing enabling us to call undo_checkpoint_after_command
        if 1: #060127
            in_event_loop = env._in_event_loop
            mc = env.begin_op("(wr)") # should always change env._in_event_loop to False (or leave it False)
            assert not env._in_event_loop
        if in_event_loop: #060121, revised 060127 and cond changed from 1 to in_event_loop
            #e if necessary we could find out whether innermost op_run in changes.py's stack still *wants* a cmdname to be guessed...
            # this would be especially important if it turns out this runs in inner calls and guesses it wrong,
            # overwriting a correct guess from somewhere else...
            # also don't we need to make sure that the cmd_seg we're guessing for is the right one, somehow???
            # doesn't that mean the same as, this begin_op is the one that changed the boundary? (ie call came from event loop?)
            sender = self.__sender
            ##print "sender",sender # or could grab its icon for insertion into history
            from foundation.whatsthis_utilities import map_from_id_QAction_to_featurename
            fn = map_from_id_QAction_to_featurename.get(id(sender))
                # When we used sender rather than id(sender), the UI seemed noticably slower!!
                # Possible problem with using id() is for temporary items -- when they're gone,
                # newly allocated ones with same id might seem to have those featurenames.
                # Perhaps we need to verify the name is still present in the whatsthis text?
                # But we don't have the item itself here! We could keep it in the value, and then
                # it would stick around forever anyway so its id wouldn't be reused,
                # but we'd have a memory leak for dynamic menus. Hmm... maybe we could add our own
                # key attribute to these items? And also somehow remove temporary ones from this dict
                # soon after they go away, or when new temp items are created for same featurename?
                # ... Decision [nim]: use our own key attr, don't bother removing old items from dict,
                # the leak per-cmenu is smaller than others we have per-user-command. ####@@@@ DOIT
            if fn:
                if 1: #experiment 060121
                    from utilities.debug import print_compact_traceback
                    try:
                        win = env.mainwindow()
                        assert win.initialised # make sure it's not too early
                        assy = win.assy
                    except:
                        if debug_flags.atom_debug:
                            print_compact_traceback("atom_debug: fyi: normal exception: ")
                        pass # this is normal during init... or at least I thought it would be -- I never actually saw it yet.
                    else:
##                        begin_retval = assy.undo_checkpoint_before_command(fn)
##                        cp_fn = fn, begin_retval #e this should include a retval from that method, but must also always be true
                        if 1: #060127
                            # note, ideally this assy and the one that subscribes to command_segment changes
                            # should be found in the same way (ie that one should sub to this too) -- could this just iterate over
                            # same list and call it differently, with a different flag?? ##e
                            assy.current_command_info(cmdname = fn) #e cmdname might be set more precisely by the slot we're wrapping
                if 0:
                    print " featurename =", fn
                    # This works! prints correct names for toolbuttons and main menu items.
                    # Doesn't work for glpane cmenu items, but I bet it will when we fix them to have proper WhatsThis text.
                    # Hmm, how will we do that? There is presently no formal connection between them and the usual qactions
                    # or toolbuttons or whatsthis features for the main UI for the same method. We might have to detect the
                    # identity of the bound method they call as a slot! Not sure if this is possible. If not, we have to set
                    # command names from inside the methods that implement them (not the end of the world), or grab them from
                    # history text (doable).
            else:
                #060320 debug code; note, this shows signals that might not need undo cp's, but for almost all signals,
                # they might in theory need them in the future for some recipients, so it's not usually safe to exclude them.
                # Instead, someday we'll optimize this more when no changes actually occurred (e.g. detect that above).
                if 0 and env.debug():
                    print "debug: wrappedslot found no featurename, signal = %r, sender = %r" % (self.__signal, sender)
        ## return cp_fn, mc  #060123 revised retval
        return mc
Example #52
0
    sys.path.append("./experimental/pyrex-opengl")

binPath = os.path.normpath(os.path.dirname(os.path.abspath(sys.argv[0]))
                           + '/../bin')
if binPath not in sys.path:
    sys.path.append(binPath)

quux_module_import_succeeded = False

try:
    import quux # can't be toplevel
    quux_module_import_succeeded = True
    if "experimental" in os.path.dirname(quux.__file__):
        # Should never happen for end users, but if it does we want to print the
        # warning.
        if env.debug() or not EndUser.enableDeveloperFeatures():
            print "debug: fyi:", \
                  "Loaded experimental version of C rendering code:", \
                  quux.__file__
except:
    quux = None
    quux_module_import_succeeded = False
    if env.debug(): #bruce 060323 added condition
        print "WARNING: unable to import C rendering code (quux module).", \
              "Only Python rendering will be available."
    pass

# ==

class ShapeList_inplace:
    """
Example #53
0
def _capitalize_first_word(words): #bruce 060705
    res = words[0].upper() + words[1:]
    if res == words:
        if env.debug():
            print "debug warning: %r did not change in _capitalize_first_word" % (words,)
    return res
Example #54
0
 def dismissed(self):
     if env.debug():
         print "debug fyi: dismissed -- should we tell owner to destroy us? is it even still there?"  ####@@@@
     self.destroy(
     )  # let's just take the initiative ourselves, though it might cause bugs, maybe we should do it later...
Example #55
0
    return mgr.undo_cmds_menuspec(widget)

register_debug_menu_command_maker( "undo_cmds", undo_cmds_maker)
    # fyi: this runs once when the first assy is being created, but undo_cmds_maker runs every time the debug menu is put up.

# ==

# some global private state (which probably ought to be undo manager instance vars)

try:
    _editAutoCheckpointing_recursing
except:
    _editAutoCheckpointing_recursing = False
        # only if we're not reloading -- otherwise, bug when setChecked calls MWsem slot which reloads
else:
    if _editAutoCheckpointing_recursing and env.debug():
        pass # print "note: _editAutoCheckpointing_recursing true during reload" # this happens!

try:
    _AutoCheckpointing_enabled # on reload, use old value unchanged (since we often reload automatically during debugging)
except:
    _AutoCheckpointing_enabled = True # this might be changed based on env.prefs whenever an undo_manager gets created [060314]
        # older comment about that, not fully obs:
        #e this might be revised to look at env.prefs sometime during app startup,
        # and to call editAutoCheckpointing (or some part of it) with the proper initial state;
        # the current code is designed, internally, for checkpointing to be enabled except
        # for certain intervals, so we might start out True and set this to False when
        # an undo_manager is created... we'll see; maybe it won't even (or mainly or only) be a global? [060309]

def _set_AutoCheckpointing_enabled( enabled):
    global _AutoCheckpointing_enabled
Example #56
0
    sys.path.append("./experimental/pyrex-opengl")

binPath = os.path.normpath(
    os.path.dirname(os.path.abspath(sys.argv[0])) + '/../bin')
if binPath not in sys.path:
    sys.path.append(binPath)

quux_module_import_succeeded = False

try:
    import quux  # can't be toplevel
    quux_module_import_succeeded = True
    if "experimental" in os.path.dirname(quux.__file__):
        # Should never happen for end users, but if it does we want to print the
        # warning.
        if env.debug() or not EndUser.enableDeveloperFeatures():
            print "debug: fyi:", \
                  "Loaded experimental version of C rendering code:", \
                  quux.__file__
except:
    quux = None
    quux_module_import_succeeded = False
    if env.debug():  #bruce 060323 added condition
        print "WARNING: unable to import C rendering code (quux module).", \
              "Only Python rendering will be available."
    pass

# ==


class ShapeList_inplace: