Completed
Push — pulsed_with_queued_connections ( 0b7aaa...175b78 )
by
unknown
04:14 queued 01:18
created

ManagerGui.resetToDefaultLayout()   B

Complexity

Conditions 1

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
c 0
b 0
f 0
dl 0
loc 25
rs 8.8571
1
# -*- coding: utf-8 -*-
2
""" This module contains a GUI through which the Manager core class can be controlled.
3
It can load and reload modules, show the configuration, and re-open closed windows.
4
5
Qudi is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9
10
Qudi is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14
15
You should have received a copy of the GNU General Public License
16
along with Qudi. If not, see <http://www.gnu.org/licenses/>.
17
18
Copyright (c) the Qudi Developers. See the COPYRIGHT.txt file at the
19
top-level directory of this distribution and at <https://github.com/Ulm-IQO/qudi/>
20
"""
21
22
import logging
23
import core.logger
24
from gui.guibase import GUIBase
25
from qtpy import QtCore, QtWidgets, uic
26
from qtpy.QtGui import QPalette
27
from qtpy.QtWidgets import QWidget
28
try:
29
    from qtconsole.inprocess import QtInProcessKernelManager
30
except ImportError:
31
    from IPython.qt.inprocess import QtInProcessKernelManager
32
try:
33
    from git import Repo
34
except:
35
    pass
0 ignored issues
show
Unused Code introduced by
This except handler seems to be unused and could be removed.

Except handlers which only contain pass and do not have an else clause can usually simply be removed:

try:
    raises_exception()
except:  # Could be removed
    pass
Loading history...
36
from collections import OrderedDict
37
from .errordialog import ErrorDialog
38
import numpy as np
39
import os
40
41
try:
42
    import pyqtgraph as pg
43
    _has_pyqtgraph = True
44
except:
45
    _has_pyqtgraph = False
46
47
# Rather than import the ui*.py file here, the ui*.ui file itself is
48
# loaded by uic.loadUI in the QtGui classes below.
49
50
51
class ManagerGui(GUIBase):
52
    """This class provides a GUI to the Qudi manager.
53
54
      @signal sigStartAll: sent when all modules should be loaded
55
      @signal str str sigStartThis: load a specific module
56
      @signal str str sigReloadThis reload a specific module from Python code
57
      @signal str str sigStopThis: stop all actions of a module and remove
58
                                   references
59
      It supports module loading, reloading, logging and other
60
      administrative tasks.
61
    """
62
    sigStartAll = QtCore.Signal()
63
    sigStartModule = QtCore.Signal(str, str)
64
    sigReloadModule = QtCore.Signal(str, str)
65
    sigCleanupStatus = QtCore.Signal(str, str)
66
    sigStopModule = QtCore.Signal(str, str)
67
    sigLoadConfig = QtCore.Signal(str, bool)
68
    sigSaveConfig = QtCore.Signal(str)
69
70
    def __init__(self, **kwargs):
71
        """Create an instance of the module.
72
73
          @param object manager:
74
          @param str name:
75
          @param dict config:
76
        """
77
        super().__init__(**kwargs)
78
        self.modlist = list()
79
        self.modules = set()
80
81
    def on_activate(self, e=None):
82
        """ Activation method called on change to active state.
83
84
        @param object e: Fysom.event object from Fysom class.
85
                         An object created by the state machine module Fysom,
86
                         which is connected to a specific event (have a look
87
                         in the Base Class). This object contains the passed
88
                         event, the state before the event happened and the
89
                         destination of the state which should be reached
90
                         after the event had happened.
91
92
        This method creates the Manager main window.
93
        """
94
        if _has_pyqtgraph:
95
            # set background of pyqtgraph
96
            testwidget = QWidget()
97
            testwidget.ensurePolished()
98
            bgcolor = testwidget.palette().color(QPalette.Normal,
99
                                                 testwidget.backgroundRole())
100
            # set manually the background color in hex code according to our
101
            # color scheme:
102
            pg.setConfigOption('background', bgcolor)
103
104
            # opengl usage
105
            if 'useOpenGL' in self._manager.tree['global']:
106
                pg.setConfigOption('useOpenGL',
107
                                   self._manager.tree['global']['useOpenGL'])
108
        self._mw = ManagerMainWindow()
109
        self.restoreWindowPos(self._mw)
110
        self.errorDialog = ErrorDialog(self)
111
        self._about = AboutDialog()
112
        version = self.getSoftwareVersion()
113
        configFile = self._manager.configFile
114
        self._about.label.setText(
0 ignored issues
show
Bug introduced by
The Instance of AboutDialog does not seem to have a member named label.

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...
115
            '<a href=\"https://github.com/Ulm-IQO/qudi/commit/{0}\"'
116
            ' style=\"color: cyan;\"> {0} </a>, on branch {1}.'.format(
117
                version[0], version[1]))
118
        self.versionLabel = QtWidgets.QLabel()
119
        self.versionLabel.setText(
120
            '<a href=\"https://github.com/Ulm-IQO/qudi/commit/{0}\"'
121
            ' style=\"color: cyan;\"> {0} </a>,'
122
            ' on branch {1}, configured from {2}'.format(
123
                version[0], version[1], configFile))
124
        self.versionLabel.setOpenExternalLinks(True)
125
        self._mw.statusBar().addWidget(self.versionLabel)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named statusBar.

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...
126
        # Connect up the buttons.
127
        self._mw.actionQuit.triggered.connect(self._manager.quit)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named actionQuit.

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...
128
        self._mw.actionLoad_configuration.triggered.connect(self.getLoadFile)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named actionLoad_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...
129
        self._mw.actionReload_current_configuration.triggered.connect(self.reloadConfig)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named actionReload_current_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...
130
        self._mw.actionSave_configuration.triggered.connect(self.getSaveFile)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow 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...
131
        self._mw.action_Load_all_modules.triggered.connect(self._manager.startAllConfiguredModules)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named action_Load_all_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...
132
        self._mw.actionAbout_Qt.triggered.connect(QtWidgets.QApplication.aboutQt)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named actionAbout_Qt.

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...
133
        self._mw.actionAbout_Qudi.triggered.connect(self.showAboutQudi)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named actionAbout_Qudi.

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...
134
        self._mw.actionReset_to_default_layout.triggered.connect(self.resetToDefaultLayout)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named actionReset_to_default_layout.

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...
135
136
        self._manager.sigShowManager.connect(self.show)
137
        self._manager.sigConfigChanged.connect(self.updateConfigWidgets)
138
        self._manager.sigModulesChanged.connect(self.updateConfigWidgets)
139
        # Log widget
140
        self._mw.logwidget.setManager(self._manager)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named logwidget.

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...
141
        for loghandler in logging.getLogger().handlers:
142
            if isinstance(loghandler, core.logger.QtLogHandler):
143
                loghandler.sigLoggedMessage.connect(self.handleLogEntry)
144
        # Module widgets
145
        self.sigStartModule.connect(self._manager.startModule)
146
        self.sigReloadModule.connect(self._manager.restartModuleSimple)
147
        self.sigCleanupStatus.connect(self._manager.removeStatusFile)
148
        self.sigStopModule.connect(self._manager.deactivateModule)
149
        self.sigLoadConfig.connect(self._manager.loadConfig)
150
        self.sigSaveConfig.connect(self._manager.saveConfig)
151
        # Module state display
152
        self.checkTimer = QtCore.QTimer()
153
        self.checkTimer.start(1000)
154
        self.updateGUIModuleList()
155
        # IPython console widget
156
        self.startIPython()
157
        self.updateIPythonModuleList()
158
        self.startIPythonWidget()
159
        # thread widget
160
        self._mw.threadWidget.threadListView.setModel(self._manager.tm)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named threadWidget.

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...
161
        # remote widget
162
        self._mw.remoteWidget.hostLabel.setText('URL:')
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named remoteWidget.

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...
163
        self._mw.remoteWidget.portLabel.setText(
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named remoteWidget.

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...
164
            'rpyc://{0}:{1}/'.format(self._manager.rm.host,
165
                                     self._manager.rm.server.port))
166
        self._mw.remoteWidget.remoteModuleListView.setModel(
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named remoteWidget.

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
            self._manager.rm.remoteModules)
168
        self._mw.remoteWidget.sharedModuleListView.setModel(
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named remoteWidget.

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...
169
            self._manager.rm.sharedModules)
170
171
        self._mw.configDisplayDockWidget.hide()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named configDisplayDockWidget.

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...
172
        self._mw.remoteDockWidget.hide()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named remoteDockWidget.

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...
173
        self._mw.threadDockWidget.hide()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named threadDockWidget.

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...
174
        self._mw.show()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow 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...
175
176
    def on_deactivate(self, e):
177
        """Close window and remove connections.
178
179
        @param object e: Fysom.event object from Fysom class. A more detailed
180
                         explanation can be found in the method activation.
181
        """
182
        self.stopIPythonWidget()
183
        self.stopIPython()
184
        self.checkTimer.stop()
185
        if len(self.modlist) > 0:
186
            self.checkTimer.timeout.disconnect()
187
        self.sigStartModule.disconnect()
188
        self.sigReloadModule.disconnect()
189
        self.sigStopModule.disconnect()
190
        self.sigLoadConfig.disconnect()
191
        self.sigSaveConfig.disconnect()
192
        self._mw.actionQuit.triggered.disconnect()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named actionQuit.

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...
193
        self._mw.actionLoad_configuration.triggered.disconnect()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named actionLoad_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...
194
        self._mw.actionSave_configuration.triggered.disconnect()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow 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...
195
        self._mw.action_Load_all_modules.triggered.disconnect()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named action_Load_all_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...
196
        self._mw.actionAbout_Qt.triggered.disconnect()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named actionAbout_Qt.

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...
197
        self._mw.actionAbout_Qudi.triggered.disconnect()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named actionAbout_Qudi.

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...
198
        self.saveWindowPos(self._mw)
199
        self._mw.close()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named close.

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...
200
201
    def show(self):
202
        """Show the window and bring it t the top.
203
        """
204
        QtWidgets.QMainWindow.show(self._mw)
205
        self._mw.activateWindow()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named activateWindow.

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...
206
        self._mw.raise_()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named raise_.

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...
207
208
    def showAboutQudi(self):
209
        """Show a dialog with details about Qudi.
210
        """
211
        self._about.show()
0 ignored issues
show
Bug introduced by
The Instance of AboutDialog 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...
212
213
    def resetToDefaultLayout(self):
214
        """ Return the dockwidget layout and visibility to its default state """
215
        self._mw.configDisplayDockWidget.setVisible(False)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named configDisplayDockWidget.

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...
216
        self._mw.consoleDockWidget.setVisible(True)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named consoleDockWidget.

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...
217
        self._mw.remoteDockWidget.setVisible(False)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named remoteDockWidget.

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...
218
        self._mw.threadDockWidget.setVisible(False)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named threadDockWidget.

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...
219
        self._mw.logDockWidget.setVisible(True)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named logDockWidget.

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...
220
221
        self._mw.actionConfigurationView.setChecked(False)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named actionConfigurationView.

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...
222
        self._mw.actionConsoleView.setChecked(True)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named actionConsoleView.

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...
223
        self._mw.actionRemoteView.setChecked(False)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named actionRemoteView.

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...
224
        self._mw.actionThreadsView.setChecked(False)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named actionThreadsView.

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...
225
        self._mw.actionLogView.setChecked(True)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named actionLogView.

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...
226
227
        self._mw.configDisplayDockWidget.setFloating(False)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named configDisplayDockWidget.

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...
228
        self._mw.consoleDockWidget.setFloating(False)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named consoleDockWidget.

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...
229
        self._mw.remoteDockWidget.setFloating(False)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named remoteDockWidget.

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...
230
        self._mw.threadDockWidget.setFloating(False)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named threadDockWidget.

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...
231
        self._mw.logDockWidget.setFloating(False)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named logDockWidget.

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...
232
233
        self._mw.addDockWidget(QtCore.Qt.DockWidgetArea(8), self._mw.configDisplayDockWidget)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named addDockWidget.

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 ManagerMainWindow does not seem to have a member named configDisplayDockWidget.

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...
234
        self._mw.addDockWidget(QtCore.Qt.DockWidgetArea(2), self._mw.consoleDockWidget)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named addDockWidget.

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 ManagerMainWindow does not seem to have a member named consoleDockWidget.

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...
235
        self._mw.addDockWidget(QtCore.Qt.DockWidgetArea(8), self._mw.remoteDockWidget)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named addDockWidget.

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 ManagerMainWindow does not seem to have a member named remoteDockWidget.

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...
236
        self._mw.addDockWidget(QtCore.Qt.DockWidgetArea(8), self._mw.threadDockWidget)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named addDockWidget.

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 ManagerMainWindow does not seem to have a member named threadDockWidget.

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
        self._mw.addDockWidget(QtCore.Qt.DockWidgetArea(8), self._mw.logDockWidget)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named addDockWidget.

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 ManagerMainWindow does not seem to have a member named logDockWidget.

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...
238
239
    def handleLogEntry(self, entry):
240
        """ Forward log entry to log widget and show an error popup if it is
241
            an error message.
242
243
            @param dict entry: Log entry
244
        """
245
        self._mw.logwidget.addEntry(entry)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named logwidget.

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...
246
        if entry['level'] == 'error' or entry['level'] == 'critical':
247
            self.errorDialog.show(entry)
248
249
    def startIPython(self):
250
        """ Create an IPython kernel manager and kernel.
251
            Add modules to its namespace.
252
        """
253
        # make sure we only log errors and above from ipython
254
        logging.getLogger('ipykernel').setLevel(logging.WARNING)
255
        self.log.debug('IPy activation in thread {0}'.format(
256
            QtCore.QThread.currentThreadId()))
257
        self.kernel_manager = QtInProcessKernelManager()
258
        self.kernel_manager.start_kernel()
259
        self.kernel = self.kernel_manager.kernel
260
        self.namespace = self.kernel.shell.user_ns
261
        self.namespace.update({
262
            'np': np,
263
            'config': self._manager.tree['defined'],
264
            'manager': self._manager
265
        })
266
        if _has_pyqtgraph:
267
            self.namespace['pg'] = pg
268
        self.updateIPythonModuleList()
269
        self.kernel.gui = 'qt4'
270
        self.log.info('IPython has kernel {0}'.format(
271
            self.kernel_manager.has_kernel))
272
        self.log.info('IPython kernel alive {0}'.format(
273
            self.kernel_manager.is_alive()))
274
        self._manager.sigModulesChanged.connect(self.updateIPythonModuleList)
275
276
    def startIPythonWidget(self):
277
        """ Create an IPython console widget and connect it to an IPython
278
        kernel.
279
        """
280
        if (_has_pyqtgraph):
281
            banner_modules = 'The numpy and pyqtgraph modules have already ' \
282
                             'been imported as ''np'' and ''pg''.'
283
        else:
284
            banner_modules = 'The numpy module has already been imported ' \
285
                             'as ''np''.'
286
        banner = """
287
This is an interactive IPython console. {0}
288
Configuration is in 'config', the manager is 'manager' and all loaded modules are in this namespace with their configured name.
289
View the current namespace with dir().
290
Go, play.
291
""".format(banner_modules)
292
        self._mw.consolewidget.banner = banner
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named consolewidget.

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...
293
        # font size
294
        if 'console_font_size' in self._statusVariables:
295
            self.consoleSetFontSize(self._statusVariables['console_font_size'])
296
        # settings
297
        self._csd = ConsoleSettingsDialog()
298
        self._csd.accepted.connect(self.consoleApplySettings)
0 ignored issues
show
Bug introduced by
The Instance of ConsoleSettingsDialog does not seem to have a member named accepted.

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...
299
        self._csd.rejected.connect(self.consoleKeepSettings)
0 ignored issues
show
Bug introduced by
The Instance of ConsoleSettingsDialog does not seem to have a member named rejected.

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...
300
        self._csd.buttonBox.button(
0 ignored issues
show
Bug introduced by
The Instance of ConsoleSettingsDialog does not seem to have a member named buttonBox.

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...
301
            QtWidgets.QDialogButtonBox.Apply).clicked.connect(
302
                self.consoleApplySettings)
303
        self._mw.actionConsoleSettings.triggered.connect(self._csd.exec_)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named actionConsoleSettings.

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 ConsoleSettingsDialog does not seem to have a member named exec_.

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...
304
        self.consoleKeepSettings()
305
306
        self._mw.consolewidget.kernel_manager = self.kernel_manager
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named consolewidget.

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...
307
        self._mw.consolewidget.kernel_client = \
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named consolewidget.

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...
308
            self._mw.consolewidget.kernel_manager.client()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named consolewidget.

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...
309
        self._mw.consolewidget.kernel_client.start_channels()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named consolewidget.

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...
310
        # the linux style theme which is basically the monokai theme
311
        self._mw.consolewidget.set_default_style(colors='linux')
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named consolewidget.

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...
312
313
    def stopIPython(self):
314
        """ Stop the IPython kernel.
315
        """
316
        self.log.debug('IPy deactivation: {0}'.format(QtCore.QThread.currentThreadId()))
317
        self.kernel_manager.shutdown_kernel()
318
319
    def stopIPythonWidget(self):
320
        """ Disconnect the IPython widget from the kernel.
321
        """
322
        self._mw.consolewidget.kernel_client.stop_channels()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named consolewidget.

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...
323
324
    def updateIPythonModuleList(self):
325
        """Remove non-existing modules from namespace,
326
            add new modules to namespace, update reloaded modules
327
        """
328
        currentModules = set()
329
        newNamespace = dict()
330
        for base in ['hardware', 'logic', 'gui']:
331
            for module in self._manager.tree['loaded'][base]:
332
                currentModules.add(module)
333
                newNamespace[module] = self._manager.tree[
334
                    'loaded'][base][module]
335
        discard = self.modules - currentModules
336
        self.namespace.update(newNamespace)
337
        for module in discard:
338
            self.namespace.pop(module, None)
339
        self.modules = currentModules
340
341
    def consoleKeepSettings(self):
342
        """ Write old values into config dialog.
343
        """
344
        if 'console_font_size' in self._statusVariables:
345
            self._csd.fontSizeBox.setProperty(
0 ignored issues
show
Bug introduced by
The Instance of ConsoleSettingsDialog does not seem to have a member named fontSizeBox.

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...
346
                'value', self._statusVariables['console_font_size'])
347
        else:
348
            self._csd.fontSizeBox.setProperty('value', 10)
0 ignored issues
show
Bug introduced by
The Instance of ConsoleSettingsDialog does not seem to have a member named fontSizeBox.

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...
349
350
    def consoleApplySettings(self):
351
        """ Apply values from config dialog to console.
352
        """
353
        self.consoleSetFontSize(self._csd.fontSizeBox.value())
0 ignored issues
show
Bug introduced by
The Instance of ConsoleSettingsDialog does not seem to have a member named fontSizeBox.

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...
354
355
    def consoleSetFontSize(self, fontsize):
356
        self._mw.consolewidget.font_size = fontsize
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named consolewidget.

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...
357
        self._statusVariables['console_font_size'] = fontsize
358
        self._mw.consolewidget.reset_font()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named consolewidget.

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...
359
360
    def updateConfigWidgets(self):
361
        """ Clear and refill the tree widget showing the configuration.
362
        """
363
        self.fillTreeWidget(self._mw.treeWidget, self._manager.tree)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named treeWidget.

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...
364
365
    def updateGUIModuleList(self):
366
        """ Clear and refill the module list widget
367
        """
368
        # self.clearModuleList(self)
369
        self.fillModuleList(self._mw.guilayout, 'gui')
370
        self.fillModuleList(self._mw.logiclayout, 'logic')
371
        self.fillModuleList(self._mw.hwlayout, 'hardware')
372
373
    def fillModuleList(self, layout, base):
374
        """ Fill the module list widget with module widgets for defined gui
375
            modules.
376
377
          @param QLayout layout: layout of th module list widget where
378
                                 module widgest should be addad
379
          @param str base: module category to fill
380
        """
381
        for module in self._manager.tree['defined'][base]:
382
            if not module in self._manager.tree['global']['startup']:
383
                widget = ModuleListItem(self._manager, base, module)
384
                self.modlist.append(widget)
385
                layout.addWidget(widget)
386
                widget.sigLoadThis.connect(self.sigStartModule)
387
                widget.sigReloadThis.connect(self.sigReloadModule)
388
                widget.sigDeactivateThis.connect(self.sigStopModule)
389
                widget.sigCleanupStatus.connect(self.sigCleanupStatus)
390
                self.checkTimer.timeout.connect(widget.checkModuleState)
391
392
    def fillTreeItem(self, item, value):
393
        """ Recursively fill a QTreeWidgeItem with the contents from a
394
            dictionary.
395
396
          @param QTreeWidgetItem item: the widget item to fill
397
          @param (dict, list, etc) value: value to fill in
398
        """
399
        item.setExpanded(True)
400
        if type(value) is OrderedDict or type(value) is dict:
401
            for key in value:
402
                child = QtWidgets.QTreeWidgetItem()
403
                child.setText(0, key)
404
                item.addChild(child)
405
                self.fillTreeItem(child, value[key])
406
        elif type(value) is list:
407
            for val in value:
408
                child = QtWidgets.QTreeWidgetItem()
409
                item.addChild(child)
410
                if type(val) is dict:
411
                    child.setText(0, '[dict]')
412
                    self.fillTreeItem(child, val)
413
                elif type(val) is OrderedDict:
414
                    child.setText(0, '[odict]')
415
                    self.fillTreeItem(child, val)
416
                elif type(val) is list:
417
                    child.setText(0, '[list]')
418
                    self.fillTreeItem(child, val)
419
                else:
420
                    child.setText(0, str(val))
421
                child.setExpanded(True)
422
        else:
423
            child = QtWidgets.QTreeWidgetItem()
424
            child.setText(0, str(value))
425
            item.addChild(child)
426
427
    def getSoftwareVersion(self):
428
        """ Try to determine the software version in case the program is in
429
            a git repository.
430
        """
431
        try:
432
            repo = Repo(self.get_main_dir())
433
            branch = repo.active_branch
434
            rev = str(repo.head.commit)
435
            return (rev, str(branch))
436
437
        except Exception as e:
438
            print('Could not get git repo because:', e)
439
            return ('unknown', -1)
440
441
    def fillTreeWidget(self, widget, value):
442
        """ Fill a QTreeWidget with the content of a dictionary
443
444
          @param QTreeWidget widget: the tree widget to fill
445
          @param dict,OrderedDict value: the dictionary to fill in
446
        """
447
        widget.clear()
448
        self.fillTreeItem(widget.invisibleRootItem(), value)
449
450
    def reloadConfig(self):
451
        """  Reload the current config. """
452
453
        reply = QtWidgets.QMessageBox.question(
454
            self._mw,
455
            'Restart',
456
            'Do you want to restart the current configuration?',
457
            QtWidgets.QMessageBox.Yes,
458
            QtWidgets.QMessageBox.No
459
        )
460
461
        configFile = self._manager._getConfigFile()
462
        restart = (reply == QtWidgets.QMessageBox.Yes)
463
        self.sigLoadConfig.emit(configFile, restart)
464
465
    def getLoadFile(self):
466
        """ Ask the user for a file where the configuration should be loaded
467
            from
468
        """
469
        defaultconfigpath = os.path.join(self.get_main_dir(), 'config')
470
        filename = QtWidgets.QFileDialog.getOpenFileName(
471
            self._mw,
472
            'Load Configration',
473
            defaultconfigpath,
474
            'Configuration files (*.cfg)')
475
        if filename != '':
476
            reply = QtWidgets.QMessageBox.question(
477
                self._mw,
478
                'Restart',
479
                'Do you want to restart to use the configuration?',
480
                QtWidgets.QMessageBox.Yes,
481
                QtWidgets.QMessageBox.No
482
            )
483
            restart = (reply == QtWidgets.QMessageBox.Yes)
484
            self.sigLoadConfig.emit(filename, restart)
485
486
    def getSaveFile(self):
487
        """ Ask the user for a file where the configuration should be saved
488
            to.
489
        """
490
        defaultconfigpath = os.path.join(self.get_main_dir(), 'config')
491
        filename = QtWidgets.QFileDialog.getSaveFileName(
492
            self._mw,
493
            'Save Configration',
494
            defaultconfigpath,
495
            'Configuration files (*.cfg)')
496
        if filename != '':
497
            self.sigSaveConfig.emit(filename)
498
499
500
class ManagerMainWindow(QtWidgets.QMainWindow):
501
    """ This class represents the Manager Window.
502
    """
503
504
    def __init__(self):
505
        """ Create the Manager Window.
506
        """
507
        # Get the path to the *.ui file
508
        this_dir = os.path.dirname(__file__)
509
        ui_file = os.path.join(this_dir, 'ui_manager_window.ui')
510
511
        # Load it
512
        super(ManagerMainWindow, self).__init__()
513
        uic.loadUi(ui_file, self)
514
        self.show()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow 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...
515
516
        # Set up the layout
517
        # this really cannot be done in Qt designer, you cannot set a layout
518
        # on an empty widget
519
        self.guilayout = QtWidgets.QVBoxLayout(self.guiscroll)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named guiscroll.

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...
520
        self.logiclayout = QtWidgets.QVBoxLayout(self.logicscroll)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named logicscroll.

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...
521
        self.hwlayout = QtWidgets.QVBoxLayout(self.hwscroll)
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named hwscroll.

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...
522
523
524
class AboutDialog(QtWidgets.QDialog):
525
    """ This class represents the Qudi About dialog.
526
    """
527
528
    def __init__(self):
529
        """ Create Qudi About Dialog.
530
        """
531
        # Get the path to the *.ui file
532
        this_dir = os.path.dirname(__file__)
533
        ui_file = os.path.join(this_dir, 'ui_about.ui')
534
535
        # Load it
536
        super().__init__()
537
        uic.loadUi(ui_file, self)
538
539
540
class ConsoleSettingsDialog(QtWidgets.QDialog):
541
    """ Create the SettingsDialog window, based on the corresponding *.ui
542
        file.
543
    """
544
545
    def __init__(self):
546
         # Get the path to the *.ui file
547
        this_dir = os.path.dirname(__file__)
548
        ui_file = os.path.join(this_dir, 'ui_console_settings.ui')
549
550
        # Load it
551
        super().__init__()
552
        uic.loadUi(ui_file, self)
553
554
555
class ModuleListItem(QtWidgets.QFrame):
556
    """ This class represents a module widget in the Qudi module list.
557
558
      @signal str str sigLoadThis: gives signal with base and name of module
559
                                   to be loaded
560
      @signal str str sigReloadThis: gives signal with base and name of
561
                                     module to be reloaded
562
      @signal str str sigStopThis: gives signal with base and name of module
563
                                   to be deactivated
564
    """
565
566
    sigLoadThis = QtCore.Signal(str, str)
567
    sigReloadThis = QtCore.Signal(str, str)
568
    sigDeactivateThis = QtCore.Signal(str, str)
569
    sigCleanupStatus = QtCore.Signal(str, str)
570
571
    def __init__(self, manager, basename, modulename):
572
        """ Create a module widget.
573
574
          @param str basename: module category
575
          @param str modulename: unique module name
576
        """
577
        # Get the path to the *.ui file
578
        this_dir = os.path.dirname(__file__)
579
        ui_file = os.path.join(this_dir, 'ui_module_widget.ui')
580
581
        # Load it
582
        super().__init__()
583
        uic.loadUi(ui_file, self)
584
585
        self.manager = manager
586
        self.name = modulename
587
        self.base = basename
588
589
        self.loadButton.setText('Load {0}'.format(self.name))
0 ignored issues
show
Bug introduced by
The Instance of ModuleListItem does not seem to have a member named loadButton.

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...
590
        # connect buttons
591
        self.loadButton.clicked.connect(self.loadButtonClicked)
0 ignored issues
show
Bug introduced by
The Instance of ModuleListItem does not seem to have a member named loadButton.

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...
592
        self.reloadButton.clicked.connect(self.reloadButtonClicked)
0 ignored issues
show
Bug introduced by
The Instance of ModuleListItem does not seem to have a member named reloadButton.

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...
593
        self.deactivateButton.clicked.connect(self.deactivateButtonClicked)
0 ignored issues
show
Bug introduced by
The Instance of ModuleListItem does not seem to have a member named deactivateButton.

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...
594
        self.cleanupButton.clicked.connect(self.cleanupButtonClicked)
0 ignored issues
show
Bug introduced by
The Instance of ModuleListItem does not seem to have a member named cleanupButton.

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...
595
596
    def loadButtonClicked(self):
597
        """ Send signal to load and activate this module.
598
        """
599
        self.sigLoadThis.emit(self.base, self.name)
600
        if self.base == 'gui':
601
            self.loadButton.setText('Show {0}'.format(self.name))
0 ignored issues
show
Bug introduced by
The Instance of ModuleListItem does not seem to have a member named loadButton.

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...
602
603
    def reloadButtonClicked(self):
604
        """ Send signal to reload this module.
605
        """
606
        self.sigReloadThis.emit(self.base, self.name)
607
608
    def deactivateButtonClicked(self):
609
        """ Send signal to deactivate this module.
610
        """
611
        self.sigDeactivateThis.emit(self.base, self.name)
612
613
    def cleanupButtonClicked(self):
614
        """ Send signal to deactivate this module.
615
        """
616
        self.sigCleanupStatus.emit(self.base, self.name)
617
618
    def checkModuleState(self):
619
        """ Get the state of this module and display it in the statusLabel
620
        """
621
        state = ''
622
        if self.statusLabel.text() != 'exception, cannot get state':
0 ignored issues
show
Bug introduced by
The Instance of ModuleListItem does not seem to have a member named statusLabel.

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...
623
            try:
624
                if (self.base in self.manager.tree['loaded']
625
                        and self.name in self.manager.tree['loaded'][self.base]):
626
                    state = self.manager.tree['loaded'][self.base][self.name].getState()
627
                else:
628
                    state = 'not loaded'
629
            except:
630
                state = 'exception, cannot get state'
631
632
            self.statusLabel.setText(state)
0 ignored issues
show
Bug introduced by
The Instance of ModuleListItem does not seem to have a member named statusLabel.

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...
633