Completed
Push — pulsed_with_queued_connections ( b02de1...6b1460 )
by
unknown
03:27
created

ConfigMainWindow.nodesToConfig()   F

Complexity

Conditions 9

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
c 1
b 0
f 0
dl 0
loc 34
rs 3
1
# -*- coding: utf-8 -*-
2
"""
3
Qudi is free software: you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation, either version 3 of the License, or
6
(at your option) any later version.
7
8
Qudi is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
GNU General Public License for more details.
12
13
You should have received a copy of the GNU General Public License
14
along with Qudi. If not, see <http://www.gnu.org/licenses/>.
15
16
Copyright (c) the Qudi Developers. See the COPYRIGHT.txt file at the
17
top-level directory of this distribution and at <https://github.com/Ulm-IQO/qudi/>
18
"""
19
if __package__ is None:
20
    import __init__
0 ignored issues
show
Unused Code introduced by
The import __init__ seems to be unused.
Loading history...
21
    __package__ = 'config_gui'
0 ignored issues
show
Bug Best Practice introduced by
This seems to re-define the built-in __package__.

It is generally discouraged to redefine built-ins as this makes code very hard to read.

Loading history...
22
else:
23
    import __init__
24
25
from qtpy import QtCore, QtGui, QtWidgets, uic
0 ignored issues
show
Unused Code introduced by
Unused QtGui imported from qtpy
Loading history...
26
27
from pyflowgraph.graph_view import GraphView
0 ignored issues
show
Unused Code introduced by
Unused GraphView imported from pyflowgraph.graph_view
Loading history...
28
from pyflowgraph.graph_view_widget import GraphViewWidget
0 ignored issues
show
Unused Code introduced by
Unused GraphViewWidget imported from pyflowgraph.graph_view_widget
Loading history...
29
from pyflowgraph.node import Node
30
from pyflowgraph.port import InputPort, OutputPort, IOPort
0 ignored issues
show
Unused Code introduced by
Unused IOPort imported from pyflowgraph.port
Loading history...
31
32
import sys
33
import os
34
35
sys.path.append(os.getcwd())
36
from gui.colordefs import QudiPalettePale as palette
0 ignored issues
show
Bug introduced by
The name colordefs does not seem to exist in module gui.
Loading history...
37
import core.config
0 ignored issues
show
Bug introduced by
The name config does not seem to exist in module core.
Loading history...
38
from menu import ModMenu
39
from collections import OrderedDict
40
import listmods
41
import logging
42
import argparse
43
44
class ConfigMainWindow(QtWidgets.QMainWindow):
45
    """ This class represents the Manager Window.
46
    """
47
    def __init__(self, loadfile=None):
48
        """ Create the Manager Window.
49
        """
50
        # Get the path to the *.ui file
51
        this_dir = os.path.dirname(__file__)
52
        ui_file = os.path.join(this_dir, 'ui_config_window.ui')
53
        self.log = logging.getLogger(__name__)
54
55
        # Load it
56
        super().__init__()
57
        uic.loadUi(ui_file, self)
58
59
        self.mods = dict()
60
        self.globalsection = OrderedDict()
61
        self.currentFile = ''
62
63
        # init 
64
        self.setupUi()
65
        self.show()
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named show.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
66
67
        if loadfile is not None:
68
            self.loadConfigFile(loadfile)
69
70
    def setupUi(self):
71
        self.actionNew_configuration.triggered.connect(self.newConfigFile)
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named actionNew_configuration.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
72
        self.actionSave_configuration.triggered.connect(self.saveConfigFile)
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named actionSave_configuration.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
73
        self.actionSave_configuration_as.triggered.connect(self.saveConfigFileAs)
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named actionSave_configuration_as.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
74
        self.actionOpen_configuration.triggered.connect(self.openConfigFile)
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named actionOpen_configuration.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
75
        self.actionDelete_selected_nodes.triggered.connect(self.graphView.deleteSelectedNodes)
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named actionDelete_selected_nodes.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named graphView.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
76
        self.actionFrame_selected_nodes.triggered.connect(self.graphView.frameSelectedNodes)
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named actionFrame_selected_nodes.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named graphView.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
77
        self.actionFrame_all_nodes.activated.connect(self.graphView.frameAllNodes)
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named actionFrame_all_nodes.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named graphView.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
78
79
        # add module menu
80
        self.findModules()
81
        self.mmroot = ModMenu(self.m)
82
        for mod in self.mmroot.modules:
83
            mod.sigAddModule.connect(self.addModule)
84
        self.actionAdd_Module.setMenu(self.mmroot)
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named actionAdd_Module.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
85
86
        # node change signals
87
        self.graphView.nodeAdded.connect(self.nodeAdded)
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named graphView.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
88
        self.graphView.nodeRemoved.connect(self.nodeRemoved)
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named graphView.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
89 View Code Duplication
        self.graphView.nodeNameChanged.connect(self.nodeNameChanged)
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named graphView.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
90
91
    def findModules(self):
92
        modules = listmods.find_pyfiles(os.getcwd())
0 ignored issues
show
Bug introduced by
The Module listmods does not seem to have a member named find_pyfiles.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
93
        m, i_s, ie, oe = listmods.check_qudi_modules(modules)
0 ignored issues
show
Bug introduced by
The Module listmods does not seem to have a member named check_qudi_modules.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
Unused Code introduced by
The variable i_s seems to be unused.
Loading history...
94
        self.m = m
95
96
        if len(oe) > 0 or len(ie) > 0:
97
            print('\n==========  ERRORS:  ===========', file=sys.stderr)
98
            for e in oe:
99
                print(e[0], file=sys.stderr)
100
                print(e[1], file=sys.stderr)
101
102
            for e in ie:
103
                print(e[0], file=sys.stderr)
104
                print(e[1], file=sys.stderr)
105
       #  print(self.m)
106
107
    def addModule(self, module, name=None, pos=(0,0)):
108
        if name is None:
109
            name = 'new_module'
110
        n = 1
111
        if self.graphView.hasNode(name):
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named graphView.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
112
            while self.graphView.hasNode('{}{}'.format(name, n)):
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named graphView.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
113
                n += 1
114
            name = '{}{}'.format(name, n)
115
116
        g = self.graphView
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named graphView.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
117
        node = Node(g, name)
118
        if module.path.startswith('hardware'):
119
            node.setColor(palette.c2)
120
        elif module.path.startswith('logic'):
121
            node.setColor(palette.c1)
122
        elif module.path.startswith('gui'):
123
            node.setColor(palette.c4)
124
        else:
125
            node.setColor(palette.c3)
126
127
        for conn in module.conn_in:
128
            node.addPort(InputPort(node, g, conn[0], palette.c3, conn[1]))
129
130
        for conn in module.conn_out:
131
            node.addPort(OutputPort(node, g, conn[0], palette.c3, conn[1]))
132
133
        node.setGraphPos(QtCore.QPointF(pos[0], pos[1]))
134
135
        self.mods[name] = {
136
            'node': node,
137
            'module': module,
138
            }
139
        g.addNode(node)
140
141
    def openConfigFile(self):
142
        defaultconfigpath = ''
143
        filename = QtWidgets.QFileDialog.getOpenFileName(
144
            self,
145
            'Load Configration',
146
            defaultconfigpath ,
147
            'Configuration files (*.cfg)')
148
        if len(filename) > 0:
149
            print('Open:', filename)
150
            self.loadConfigFile(filename)
151
152
    def loadConfigFile(self, filename):
153
        config = core.config.load(filename)
0 ignored issues
show
Bug introduced by
The Module core does not seem to have a member named config.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
154
        self.configToNodes(config)
155
        self.currentFile = filename
156
        self.graphView.frameAllNodes()
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named graphView.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
157
158
    def newConfigFile(self):
159
        self.graphView.reset()
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named graphView.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
160
        self.configFileName = 'New configuration'
161
        self.updateWindowTitle(self.configFileName, extra='*')
162
163
    def saveConfigFile(self):
164
        if os.path.isfile(self.currentFile):
165
            config = self.nodesToConfig()
166
            core.config.save(self.currentFile, config)
0 ignored issues
show
Bug introduced by
The Module core does not seem to have a member named config.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
167
        else:
168
             self.saveConfigFileAs()
169
170
    def saveConfigFileAs(self):
171
        defaultconfigpath = os.path.dirname(self.currentFile)
172
        filename = QtWidgets.QFileDialog.getSaveFileName(
173
            self,
174
            'Save Configration As',
175
            defaultconfigpath ,
176
            'Configuration files (*.cfg)')
177
        if len(filename) > 0:
178
            print('Save:', filename)
179
            config = self.nodesToConfig()
180
            core.config.save(filename, config)
0 ignored issues
show
Bug introduced by
The Module core does not seem to have a member named config.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
181
            self.currentFile = filename
182
183
    def updateWindowTitle(self, filename, extra=''):
184
        self.setWindowTitle('{}{} - Qudi configuration editor'.format(filename, extra))
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named setWindowTitle.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
185
    
186
    def getModuleInfo(self):
0 ignored issues
show
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
187
        modules = listmods.find_pyfiles(os.getcwd())
0 ignored issues
show
Bug introduced by
The Module listmods does not seem to have a member named find_pyfiles.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
188
        m, i_s, ie, oe = listmods.check_qudi_modules(modules)
0 ignored issues
show
Unused Code introduced by
The variable oe seems to be unused.
Loading history...
Unused Code introduced by
The variable ie seems to be unused.
Loading history...
Unused Code introduced by
The variable m seems to be unused.
Loading history...
Bug introduced by
The Module listmods does not seem to have a member named check_qudi_modules.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
Unused Code introduced by
The variable i_s seems to be unused.
Loading history...
189
190
    def configToNodes(self, config):
191
        pos = [0, 0]
192
        for b,m in config.items():
193
            if b not in ['hardware', 'logic', 'gui']:
194
                continue
195
            for k,v in m.items():
196
                mc = 'module.Class'
197
                #print(b, k, v)
198
                if mc in v and self.mmroot.hasModule(b + '.' + v[mc]):
199
                    mod = self.mmroot.getModule(b + '.' + v[mc])
200
                    self.addModule(mod, k, pos)
201
                pos[1] += 100
202
            pos[0] += 600
203
            pos[1] = 0
204
205
        for b,m in config.items():
206
            if b not in ['hardware', 'logic', 'gui']:
207
                continue
208
            for k,v in m.items():
209
                if 'connect' in v:
210
                    for conn_in, conn_out in v['connect'].items():
211
                        cl = conn_out.split('.')
212
                        src = '.'.join(cl[:-1])
213
214
                        if k not in self.mods:
215
                            self.log.error(
216
                                'Target module {} not present while connecting {}.{} to {}'
217
                                ''.format(k, conn_in, src, cl[-1]))
218
                            continue
219
                        if conn_in not in [c[0] for c in self.mods[k]['module'].conn_in]:
220
                            self.log.error(
221
                                'Target connector {} not present while connecting {}.{} to {}.{}'
222
                                ''.format(conn_in, src, cl[-1], k, conn_in))
223
                            continue
224
                        if src not in self.mods:
225
                            self.log.error(
226
                                'Source module {} not present while connecting {} to {}.{}'
227
                                ''.format(src, cl[-1], k, conn_in))
228
                            continue
229
                        if cl[-1] not in [c[0] for c in self.mods[src]['module'].conn_out]:
230
                            self.log.error(
231
                                'Source connector {} not present while connecting {}.{} to {}.{}'
232
                                ''.format(conn_in, src, cl[-1], k, conn_in))
233
                            continue
234
235
                        try:
236
                            self.graphView.connectPorts(self.mods[src]['node'], cl[-1], self.mods[k]['node'], conn_in)
0 ignored issues
show
Bug introduced by
The Instance of ConfigMainWindow does not seem to have a member named graphView.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
237
                        except:
238
                            self.log.error(
239
                                'pyflowgraph failed while connecting {}.{} to {}.{}'
240
                                ''.format(src, cl[-1], k, conn_in))
241
                            
242
        self.globalsection = config['global']
243
244
    def nodesToConfig(self):
245
        """ Convert nodes into OrderedDict for saving.
246
        """
247
        config = OrderedDict()
248
        config['global'] = OrderedDict()
249
        config['hardware'] = OrderedDict()
250
        config['logic'] = OrderedDict()
251
        config['gui'] = OrderedDict()
252
253
        for key,value in self.globalsection.items():
254
            config['global'][key] = value
255
256
        for mname,mod in self.mods.items():
257
            entry = OrderedDict()
258
            path = mod['module'].path.split('.')
259
260
            if len(path) > 1 and path[0] in ('hardware', 'logic', 'gui'):
261
                config[path[0]][mname] = entry
262
                entry['module.Class'] = '.'.join(path[1:])
263
264
                portin = (mod['node'].getPort(x[0]) for x in mod['module'].conn_in)
265
                conndict = OrderedDict()
266
                for port in portin:
267
                    conns = port.inCircle().getConnections()
268
                    if len(conns) == 1:
269
                        c = tuple(conns)[0]
270
                        src = c.getSrcPort()
271
                        node = src.getNode()
272
                        conndict[port.getName()] = '{}.{}'.format(node.getName(), src.getName())
273
                if len(conndict) > 0:
274
                    entry['connect'] = conndict
275
            print(entry)
276
277
        return config
278
279
    def nodeAdded(self):
280
        pass
281
282
    def nodeRemoved(self):
283
        pass
284
285
    def nodeNameChanged(self):
286
        pass
287
288
if __name__ == "__main__":
289
    parser = argparse.ArgumentParser(prog='config_gui')
290
    parser.add_argument('-c', '--config', default=None, help='configuration file')
291
    args = parser.parse_args()
292
293
    app = QtWidgets.QApplication(sys.argv)
294
    mw = ConfigMainWindow(loadfile=args.config)
295
    app.exec_()
296
297