1#A* -------------------------------------------------------------------
2#B* This file contains source code for the PyMOL computer program
3#C* Copyright (c) Schrodinger, LLC.
4#D* -------------------------------------------------------------------
5#E* It is unlawful to modify or remove this copyright notice.
6#F* -------------------------------------------------------------------
7#G* Please see the accompanying LICENSE file for further information.
8#H* -------------------------------------------------------------------
9#I* Additional authors of this source file include:
10#-*
11#-*
12#-*
13#Z* -------------------------------------------------------------------
14
15from __future__ import print_function
16
17if True:
18
19    import pymol
20    import sys
21    cmd = __import__("sys").modules["pymol.cmd"]
22    from .cmd import _cmd,lock,unlock,Shortcut,QuietException,_raising, \
23          _feedback,fb_module,fb_mask, \
24          DEFAULT_ERROR, DEFAULT_SUCCESS, _raising, is_ok, is_error
25
26    try:
27        import cPickle
28    except ImportError:
29        import pickle as cPickle
30    import traceback
31
32    class WizardError(Exception):
33        pass
34
35    def _wizard(name,arg,kwd,replace,_self=cmd):
36        r = DEFAULT_ERROR
37        from . import wizard
38        try:
39            full_name = 'pymol.wizard.'+name
40            __import__(full_name)
41        except ImportError:
42            print("Error: Sorry, couldn't import the '"+name+"' wizard.")
43        else:
44            mod_obj = sys.modules[full_name]
45            if mod_obj:
46                oname = name.capitalize()
47                r = DEFAULT_SUCCESS
48                if hasattr(mod_obj,oname):
49                    kwd['_self']=_self
50                    try:
51                        wiz = getattr(mod_obj,oname)(*arg, **kwd)
52                    except WizardError as e:
53                        from pymol.wizard.message import Message
54                        wiz = Message("Error: %s" % str(e), _self=_self)
55                    if wiz:
56                        _self.set_wizard(wiz,replace)
57                        _self.do("_ refresh_wizard")
58                else:
59                    print("Error: Sorry, couldn't find the '"+oname+"' class.")
60            else:
61                print("Error: Sorry, couldn't import the '"+name+"' wizard.")
62        return r
63
64    def wizard(name=None,*arg,**kwd):
65        '''
66DESCRIPTION
67
68    "wizard" launches on of the built-in wizards.  There are special
69    Python scripts which work with PyMOL in order to obtain direct user
70    interaction and easily peform complicated tasks.
71
72USAGE
73
74    wizard name
75
76PYMOL API
77
78    cmd.wizard(string name)
79
80EXAMPLE
81
82    wizard distance  # launches the distance measurement wizard
83    '''
84        _self = kwd.get('_self',cmd)
85        r = DEFAULT_ERROR
86        if name is None:
87            _self.set_wizard()
88            r = DEFAULT_SUCCESS
89        else:
90            name = str(name)
91            if name.lower() == 'distance': # legacy compatibility
92                name = 'measurement'
93            r = _wizard(name,arg,kwd,0,_self=_self)
94        if _self._raising(r,_self): raise pymol.CmdException
95        return r
96
97    def replace_wizard(name=None,*arg,**kwd):
98        '''
99DESCRIPTION
100
101    "replace_wizard" is an unsupported internal command.
102
103    '''
104        _self = kwd.get('_self',cmd)
105        r = DEFAULT_ERROR
106        if name is None:
107            _self.set_wizard()
108            r = DEFAULT_SUCCESS
109        else:
110            r = _wizard(name,arg,kwd,1,_self=_self)
111        if _self._raising(r,_self): raise pymol.CmdException
112        return r
113
114    def set_wizard(wizard=None,replace=0,_self=cmd): # INTERNAL
115        r = DEFAULT_ERROR
116        try:
117            _self.lock(_self)
118            r = _cmd.set_wizard(_self._COb,wizard,replace)
119        finally:
120            _self.unlock(r,_self)
121        if _self._raising(r,_self): raise pymol.CmdException
122        return r
123
124    def set_wizard_stack(stack=[],_self=cmd): # INTERNAL
125        r = DEFAULT_ERROR
126        try:
127            _self.lock(_self)
128            r = _cmd.set_wizard_stack(_self._COb,stack)
129        finally:
130            _self.unlock(r,_self)
131        if _self._raising(r,_self): raise pymol.CmdException
132        return r
133
134    def refresh_wizard(_self=cmd): # INTERNAL
135        '''
136DESCRIPTION
137
138    "refresh_wizard" is in unsupported internal command.
139
140    '''
141        r = DEFAULT_ERROR
142        try:
143            _self.lock(_self)
144            r = _cmd.refresh_wizard(_self._COb)
145        finally:
146            _self.unlock(r,_self)
147        if _self._raising(r,_self): raise pymol.CmdException
148        return r
149
150    def dirty_wizard(_self=cmd): # INTERNAL
151        r = DEFAULT_ERROR
152        try:
153            _self.lock(_self)
154            r = _cmd.dirty_wizard(_self._COb)
155        finally:
156            _self.unlock(r,_self)
157        if _self._raising(r,_self): raise pymol.CmdException
158        return r
159
160    def get_wizard(_self=cmd): # INTERNAL
161        r = DEFAULT_ERROR
162        try:
163            _self.lock(_self)
164            r = _cmd.get_wizard(_self._COb)
165        finally:
166            _self.unlock(r,_self)
167        if _self._raising(r,_self): raise pymol.CmdException
168        return r
169
170    def get_wizard_stack(_self=cmd): # INTERNAL
171        r = DEFAULT_ERROR
172        try:
173            _self.lock(_self)
174            r = _cmd.get_wizard_stack(_self._COb)
175        finally:
176            _self.unlock(r,_self)
177        if _self._raising(r,_self): raise pymol.CmdException
178        return r
179
180    def session_save_wizard(session,_self=cmd):
181        # double-pickle so that session file is class-independent
182        stack = _self.get_wizard_stack()
183        session['wizard']=cPickle.dumps(stack,1)
184        return 1
185
186    def session_restore_wizard(session,_self=cmd):
187        if session is not None:
188            version = session.get('version', 0)
189            if 'wizard' in session:
190                from chempy.io import pkl
191                try:
192                    wizards = pkl.fromString(session['wizard'])
193                    for wiz in wizards:
194                        wiz.cmd = _self
195                        wiz.migrate_session(version)
196                    _self.set_wizard_stack(wizards)
197                except Exception as e:
198                    print(e)
199                    print("Session-Warning: unable to restore wizard.")
200        return 1
201