~ubuntu-branches/debian/experimental/spyder/experimental

« back to all changes in this revision

Viewing changes to spyderlib/widgets/objecteditor.py

  • Committer: Package Import Robot
  • Author(s): Picca Frédéric-Emmanuel
  • Date: 2013-02-27 09:51:28 UTC
  • mfrom: (1.1.18)
  • Revision ID: package-import@ubuntu.com-20130227095128-wtx1irpvf4vl79lj
Tags: 2.2.0~beta3+dfsg-1
* Imported Upstream version 2.2.0~beta3+dfsg
* debian /patches
  - 0002-feature-forwarded-add-icon-to-desktop-file.patch (deleted)
    this patch was integrated by the upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- coding: utf-8 -*-
2
 
#
3
 
# Copyright © 2009-2010 Pierre Raybaut
4
 
# Licensed under the terms of the MIT License
5
 
# (see spyderlib/__init__.py for details)
6
 
 
7
 
"""
8
 
Object Editor Dialog based on Qt
9
 
"""
10
 
 
11
 
from spyderlib.qt.QtCore import QObject, SIGNAL
12
 
 
13
 
 
14
 
class DialogKeeper(QObject):
15
 
    def __init__(self):
16
 
        QObject.__init__(self)
17
 
        self.dialogs = {}
18
 
        self.namespace = None
19
 
        
20
 
    def set_namespace(self, namespace):
21
 
        self.namespace = namespace
22
 
    
23
 
    def create_dialog(self, dialog, refname, func):
24
 
        self.dialogs[id(dialog)] = dialog, refname, func
25
 
        self.connect(dialog, SIGNAL('accepted()'),
26
 
                     lambda eid=id(dialog): self.editor_accepted(eid))
27
 
        self.connect(dialog, SIGNAL('rejected()'),
28
 
                     lambda eid=id(dialog): self.editor_rejected(eid))
29
 
        dialog.show()
30
 
        dialog.activateWindow()
31
 
        dialog.raise_()
32
 
        
33
 
    def editor_accepted(self, dialog_id):
34
 
        dialog, refname, func = self.dialogs[dialog_id]
35
 
        self.namespace[refname] = func(dialog)
36
 
        self.dialogs.pop(dialog_id)
37
 
        
38
 
    def editor_rejected(self, dialog_id):
39
 
        self.dialogs.pop(dialog_id)
40
 
 
41
 
keeper = DialogKeeper()
42
 
 
43
 
 
44
 
def create_dialog(obj, obj_name):
45
 
    """Creates the editor dialog and returns a tuple (dialog, func) where func
46
 
    is the function to be called with the dialog instance as argument, after 
47
 
    quitting the dialog box
48
 
    
49
 
    The role of this intermediate function is to allow easy monkey-patching.
50
 
    (uschmitt suggested this indirection here so that he can monkey patch 
51
 
    oedit to show eMZed related data)
52
 
    """
53
 
    # Local import
54
 
    from spyderlib.widgets.texteditor import TextEditor
55
 
    from spyderlib.widgets.dicteditorutils import (ndarray, FakeObject,
56
 
                                                   Image, is_known_type)
57
 
    from spyderlib.widgets.dicteditor import DictEditor
58
 
    from spyderlib.widgets.arrayeditor import ArrayEditor
59
 
 
60
 
    conv_func = lambda data: data
61
 
    readonly = not is_known_type(obj)
62
 
    if isinstance(obj, ndarray) and ndarray is not FakeObject:
63
 
        dialog = ArrayEditor()
64
 
        if not dialog.setup_and_check(obj, title=obj_name,
65
 
                                      readonly=readonly):
66
 
            return
67
 
    elif isinstance(obj, Image) and Image is not FakeObject \
68
 
         and ndarray is not FakeObject:
69
 
        dialog = ArrayEditor()
70
 
        import numpy as np
71
 
        data = np.array(obj)
72
 
        if not dialog.setup_and_check(data, title=obj_name,
73
 
                                      readonly=readonly):
74
 
            return
75
 
        from spyderlib.pil_patch import Image
76
 
        conv_func = lambda data: Image.fromarray(data, mode=obj.mode)
77
 
    elif isinstance(obj, (str, unicode)):
78
 
        dialog = TextEditor(obj, title=obj_name, readonly=readonly)
79
 
    else:
80
 
        dialog = DictEditor()
81
 
        dialog.setup(obj, title=obj_name, readonly=readonly)
82
 
 
83
 
    def end_func(dialog):
84
 
        return conv_func(dialog.get_value())
85
 
 
86
 
    return dialog, end_func
87
 
 
88
 
 
89
 
def oedit(obj, modal=True, namespace=None):
90
 
    """Edit the object 'obj' in a GUI-based editor and return the edited copy
91
 
    (if Cancel is pressed, return None)
92
 
 
93
 
    The object 'obj' is a container
94
 
    
95
 
    Supported container types:
96
 
    dict, list, tuple, str/unicode or numpy.array
97
 
    
98
 
    (instantiate a new QApplication if necessary,
99
 
    so it can be called directly from the interpreter)
100
 
    """
101
 
    # Local import
102
 
    from spyderlib.utils.qthelpers import qapplication
103
 
    app = qapplication()
104
 
    
105
 
    if modal:
106
 
        obj_name = ''
107
 
    else:
108
 
        assert isinstance(obj, basestring)
109
 
        obj_name = obj
110
 
        if namespace is None:
111
 
            namespace = globals()
112
 
        keeper.set_namespace(namespace)
113
 
        obj = namespace[obj_name]
114
 
        # keep QApplication reference alive in the Python interpreter:
115
 
        namespace['__qapp__'] = app
116
 
    
117
 
    result = create_dialog(obj, obj_name)
118
 
    if result is None:
119
 
        return
120
 
    dialog, end_func = result
121
 
    
122
 
    if modal:
123
 
        if dialog.exec_():
124
 
            return end_func(dialog)
125
 
    else:
126
 
        keeper.create_dialog(dialog, obj_name, end_func)
127
 
        import os
128
 
        qt_inputhook = os.environ.get("INSTALL_QT_INPUTHOOK",
129
 
                                      "").lower() == "true"
130
 
        if os.name == 'nt' and not qt_inputhook:
131
 
            app.exec_()
132
 
 
133
 
 
134
 
def test():
135
 
    """Run object editor test"""
136
 
    import datetime, numpy as np
137
 
    from spyderlib.pil_patch import Image
138
 
    image = Image.fromarray(np.random.random_integers(255, size=(100, 100)))
139
 
    example = {'str': 'kjkj kj k j j kj k jkj',
140
 
               'list': [1, 3, 4, 'kjkj', None],
141
 
               'dict': {'d': 1, 'a': np.random.rand(10, 10), 'b': [1, 2]},
142
 
               'float': 1.2233,
143
 
               'array': np.random.rand(10, 10),
144
 
               'image': image,
145
 
               'date': datetime.date(1945, 5, 8),
146
 
               'datetime': datetime.datetime(1945, 5, 8),
147
 
               }
148
 
    image = oedit(image)
149
 
    class Foobar(object):
150
 
        def __init__(self):
151
 
            self.text = "toto"
152
 
    foobar = Foobar()
153
 
    print oedit(foobar)
154
 
    print oedit(example)
155
 
    print oedit(np.random.rand(10, 10))
156
 
    print oedit(oedit.__doc__)
157
 
    print example
158
 
    
159
 
if __name__ == "__main__":
160
 
    test()
 
1
# -*- coding: utf-8 -*-
 
2
#
 
3
# Copyright © 2009-2010 Pierre Raybaut
 
4
# Licensed under the terms of the MIT License
 
5
# (see spyderlib/__init__.py for details)
 
6
 
 
7
"""
 
8
Object Editor Dialog based on Qt
 
9
"""
 
10
 
 
11
from spyderlib.qt.QtCore import QObject, SIGNAL
 
12
 
 
13
 
 
14
class DialogKeeper(QObject):
 
15
    def __init__(self):
 
16
        QObject.__init__(self)
 
17
        self.dialogs = {}
 
18
        self.namespace = None
 
19
        
 
20
    def set_namespace(self, namespace):
 
21
        self.namespace = namespace
 
22
    
 
23
    def create_dialog(self, dialog, refname, func):
 
24
        self.dialogs[id(dialog)] = dialog, refname, func
 
25
        self.connect(dialog, SIGNAL('accepted()'),
 
26
                     lambda eid=id(dialog): self.editor_accepted(eid))
 
27
        self.connect(dialog, SIGNAL('rejected()'),
 
28
                     lambda eid=id(dialog): self.editor_rejected(eid))
 
29
        dialog.show()
 
30
        dialog.activateWindow()
 
31
        dialog.raise_()
 
32
        
 
33
    def editor_accepted(self, dialog_id):
 
34
        dialog, refname, func = self.dialogs[dialog_id]
 
35
        self.namespace[refname] = func(dialog)
 
36
        self.dialogs.pop(dialog_id)
 
37
        
 
38
    def editor_rejected(self, dialog_id):
 
39
        self.dialogs.pop(dialog_id)
 
40
 
 
41
keeper = DialogKeeper()
 
42
 
 
43
 
 
44
def create_dialog(obj, obj_name):
 
45
    """Creates the editor dialog and returns a tuple (dialog, func) where func
 
46
    is the function to be called with the dialog instance as argument, after 
 
47
    quitting the dialog box
 
48
    
 
49
    The role of this intermediate function is to allow easy monkey-patching.
 
50
    (uschmitt suggested this indirection here so that he can monkey patch 
 
51
    oedit to show eMZed related data)
 
52
    """
 
53
    # Local import
 
54
    from spyderlib.widgets.texteditor import TextEditor
 
55
    from spyderlib.widgets.dicteditorutils import (ndarray, FakeObject,
 
56
                                                   Image, is_known_type)
 
57
    from spyderlib.widgets.dicteditor import DictEditor
 
58
    from spyderlib.widgets.arrayeditor import ArrayEditor
 
59
 
 
60
    conv_func = lambda data: data
 
61
    readonly = not is_known_type(obj)
 
62
    if isinstance(obj, ndarray) and ndarray is not FakeObject:
 
63
        dialog = ArrayEditor()
 
64
        if not dialog.setup_and_check(obj, title=obj_name,
 
65
                                      readonly=readonly):
 
66
            return
 
67
    elif isinstance(obj, Image) and Image is not FakeObject \
 
68
         and ndarray is not FakeObject:
 
69
        dialog = ArrayEditor()
 
70
        import numpy as np
 
71
        data = np.array(obj)
 
72
        if not dialog.setup_and_check(data, title=obj_name,
 
73
                                      readonly=readonly):
 
74
            return
 
75
        from spyderlib.pil_patch import Image
 
76
        conv_func = lambda data: Image.fromarray(data, mode=obj.mode)
 
77
    elif isinstance(obj, (str, unicode)):
 
78
        dialog = TextEditor(obj, title=obj_name, readonly=readonly)
 
79
    else:
 
80
        dialog = DictEditor()
 
81
        dialog.setup(obj, title=obj_name, readonly=readonly)
 
82
 
 
83
    def end_func(dialog):
 
84
        return conv_func(dialog.get_value())
 
85
 
 
86
    return dialog, end_func
 
87
 
 
88
 
 
89
def oedit(obj, modal=True, namespace=None):
 
90
    """Edit the object 'obj' in a GUI-based editor and return the edited copy
 
91
    (if Cancel is pressed, return None)
 
92
 
 
93
    The object 'obj' is a container
 
94
    
 
95
    Supported container types:
 
96
    dict, list, tuple, str/unicode or numpy.array
 
97
    
 
98
    (instantiate a new QApplication if necessary,
 
99
    so it can be called directly from the interpreter)
 
100
    """
 
101
    # Local import
 
102
    from spyderlib.utils.qthelpers import qapplication
 
103
    app = qapplication()
 
104
    
 
105
    if modal:
 
106
        obj_name = ''
 
107
    else:
 
108
        assert isinstance(obj, basestring)
 
109
        obj_name = obj
 
110
        if namespace is None:
 
111
            namespace = globals()
 
112
        keeper.set_namespace(namespace)
 
113
        obj = namespace[obj_name]
 
114
        # keep QApplication reference alive in the Python interpreter:
 
115
        namespace['__qapp__'] = app
 
116
    
 
117
    result = create_dialog(obj, obj_name)
 
118
    if result is None:
 
119
        return
 
120
    dialog, end_func = result
 
121
    
 
122
    if modal:
 
123
        if dialog.exec_():
 
124
            return end_func(dialog)
 
125
    else:
 
126
        keeper.create_dialog(dialog, obj_name, end_func)
 
127
        import os
 
128
        qt_inputhook = os.environ.get("INSTALL_QT_INPUTHOOK",
 
129
                                      "").lower() == "true"
 
130
        if os.name == 'nt' and not qt_inputhook:
 
131
            app.exec_()
 
132
 
 
133
 
 
134
def test():
 
135
    """Run object editor test"""
 
136
    import datetime, numpy as np
 
137
    from spyderlib.pil_patch import Image
 
138
    image = Image.fromarray(np.random.random_integers(255, size=(100, 100)))
 
139
    example = {'str': 'kjkj kj k j j kj k jkj',
 
140
               'list': [1, 3, 4, 'kjkj', None],
 
141
               'dict': {'d': 1, 'a': np.random.rand(10, 10), 'b': [1, 2]},
 
142
               'float': 1.2233,
 
143
               'array': np.random.rand(10, 10),
 
144
               'image': image,
 
145
               'date': datetime.date(1945, 5, 8),
 
146
               'datetime': datetime.datetime(1945, 5, 8),
 
147
               }
 
148
    image = oedit(image)
 
149
    class Foobar(object):
 
150
        def __init__(self):
 
151
            self.text = "toto"
 
152
    foobar = Foobar()
 
153
    print oedit(foobar)
 
154
    print oedit(example)
 
155
    print oedit(np.random.rand(10, 10))
 
156
    print oedit(oedit.__doc__)
 
157
    print example
 
158
    
 
159
if __name__ == "__main__":
 
160
    test()