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

ManagerGui.showAboutQudi()   A

Complexity

Conditions 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
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 threading
39
import numpy as np
40
import os
41
42
try:
43
    import pyqtgraph as pg
44
    _has_pyqtgraph = True
45
except:
46
    _has_pyqtgraph = False
47
48
# Rather than import the ui*.py file here, the ui*.ui file itself is
49
# loaded by uic.loadUI in the QtGui classes below.
50
51
52
class ManagerGui(GUIBase):
53
    """This class provides a GUI to the Qudi manager.
54
55
      @signal sigStartAll: sent when all modules should be loaded
56
      @signal str str sigStartThis: load a specific module
57
      @signal str str sigReloadThis reload a specific module from Python code
58
      @signal str str sigStopThis: stop all actions of a module and remove
59
                                   references
60
      It supports module loading, reloading, logging and other
61
      administrative tasks.
62
    """
63
    sigStartAll = QtCore.Signal()
64
    sigStartModule = QtCore.Signal(str, str)
65
    sigReloadModule = QtCore.Signal(str, str)
66
    sigCleanupStatus = QtCore.Signal(str, str)
67
    sigStopModule = QtCore.Signal(str, str)
68
    sigLoadConfig = QtCore.Signal(str, bool)
69
    sigSaveConfig = QtCore.Signal(str)
70
71
    def __init__(self, **kwargs):
72
        """Create an instance of the module.
73
74
          @param object manager:
75
          @param str name:
76
          @param dict config:
77
        """
78
        super().__init__(**kwargs)
79
        self.modlist = list()
80
        self.modules = set()
81
82
    def on_activate(self, e=None):
83
        """ Activation method called on change to active state.
84
85
        @param object e: Fysom.event object from Fysom class.
86
                         An object created by the state machine module Fysom,
87
                         which is connected to a specific event (have a look
88
                         in the Base Class). This object contains the passed
89
                         event, the state before the event happened and the
90
                         destination of the state which should be reached
91
                         after the event had happened.
92
93
        This method creates the Manager main window.
94
        """
95
        if _has_pyqtgraph:
96
            # set background of pyqtgraph
97
            testwidget = QWidget()
98
            testwidget.ensurePolished()
99
            bgcolor = testwidget.palette().color(QPalette.Normal,
100
                                                 testwidget.backgroundRole())
101
            # set manually the background color in hex code according to our
102
            # color scheme:
103
            pg.setConfigOption('background', bgcolor)
104
105
            # opengl usage
106
            if 'useOpenGL' in self._manager.tree['global']:
107
                pg.setConfigOption('useOpenGL',
108
                                   self._manager.tree['global']['useOpenGL'])
109
        self._mw = ManagerMainWindow()
110
        self.restoreWindowPos(self._mw)
111
        self.errorDialog = ErrorDialog(self)
112
        self._about = AboutDialog()
113
        version = self.getSoftwareVersion()
114
        configFile = self._manager.configFile
115
        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...
116
            '<a href=\"https://github.com/Ulm-IQO/qudi/commit/{0}\"'
117
            ' style=\"color: cyan;\"> {0} </a>, on branch {1}.'.format(
118
                version[0], version[1]))
119
        self.versionLabel = QtWidgets.QLabel()
120
        self.versionLabel.setText(
121
            '<a href=\"https://github.com/Ulm-IQO/qudi/commit/{0}\"'
122
            ' style=\"color: cyan;\"> {0} </a>,'
123
            ' on branch {1}, configured from {2}'.format(
124
                version[0], version[1], configFile))
125
        self.versionLabel.setOpenExternalLinks(True)
126
        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...
127
        # Connect up the buttons.
128
        self._mw.loadAllButton.clicked.connect(
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named loadAllButton.

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._manager.startAllConfiguredModules)
130
        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...
131
        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...
132
        self._mw.actionReload_current_configuration.triggered.connect(
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...
133
            self.reloadConfig)
134
        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...
135
        self._mw.action_Load_all_modules.triggered.connect(
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...
136
            self._manager.startAllConfiguredModules)
137
        self._mw.actionAbout_Qt.triggered.connect(
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...
138
            QtWidgets.QApplication.aboutQt)
139
        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...
140
141
        self._manager.sigShowManager.connect(self.show)
142
        self._manager.sigConfigChanged.connect(self.updateConfigWidgets)
143
        self._manager.sigModulesChanged.connect(self.updateConfigWidgets)
144
        # Log widget
145
        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...
146
        for loghandler in logging.getLogger().handlers:
147
            if isinstance(loghandler, core.logger.QtLogHandler):
148
                loghandler.sigLoggedMessage.connect(self.handleLogEntry)
149
        # Module widgets
150
        self.sigStartModule.connect(self._manager.startModule)
151
        self.sigReloadModule.connect(self._manager.restartModuleSimple)
152
        self.sigCleanupStatus.connect(self._manager.removeStatusFile)
153
        self.sigStopModule.connect(self._manager.deactivateModule)
154
        self.sigLoadConfig.connect(self._manager.loadConfig)
155
        self.sigSaveConfig.connect(self._manager.saveConfig)
156
        # Module state display
157
        self.checkTimer = QtCore.QTimer()
158
        self.checkTimer.start(1000)
159
        self.updateGUIModuleList()
160
        # IPython console widget
161
        self.startIPython()
162
        self.updateIPythonModuleList()
163
        self.startIPythonWidget()
164
        # thread widget
165
        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...
166
        # remote widget
167
        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...
168
        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...
169
            'rpyc://{0}:{1}/'.format(self._manager.rm.host,
170
                                     self._manager.rm.server.port))
171
        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...
172
            self._manager.rm.remoteModules)
173
        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...
174
            self._manager.rm.sharedModules)
175
176
        self._mw.config_display_dockWidget.hide()
0 ignored issues
show
Bug introduced by
The Instance of ManagerMainWindow does not seem to have a member named config_display_dockWidget.

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

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...
199
        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...
200
        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...
201
        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...
202
        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...
203
        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...
204
        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...
205
        self.saveWindowPos(self._mw)
206
        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...
207
208
    def show(self):
209
        """Show the window and bring it t the top.
210
        """
211
        QtWidgets.QMainWindow.show(self._mw)
212
        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...
213
        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...
214
215
    def showAboutQudi(self):
216
        """Show a dialog with details about Qudi.
217
        """
218
        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...
219
220
    def handleLogEntry(self, entry):
221
        """ Forward log entry to log widget and show an error popup if it is
222
            an error message.
223
224
            @param dict entry: Log entry
225
        """
226
        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...
227
        if entry['level'] == 'error' or entry['level'] == 'critical':
228
            self.errorDialog.show(entry)
229
230
    def startIPython(self):
231
        """ Create an IPython kernel manager and kernel.
232
            Add modules to its namespace.
233
        """
234
        # make sure we only log errors and above from ipython
235
        logging.getLogger('ipykernel').setLevel(logging.WARNING)
236
        self.log.debug('IPy activation in thread {0}'.format(
237
            threading.get_ident()))
238
        self.kernel_manager = QtInProcessKernelManager()
239
        self.kernel_manager.start_kernel()
240
        self.kernel = self.kernel_manager.kernel
241
        self.namespace = self.kernel.shell.user_ns
242
        self.namespace.update({
243
            'np': np,
244
            'config': self._manager.tree['defined'],
245
            'manager': self._manager
246
        })
247
        if _has_pyqtgraph:
248
            self.namespace['pg'] = pg
249
        self.updateIPythonModuleList()
250
        self.kernel.gui = 'qt4'
251
        self.log.info('IPython has kernel {0}'.format(
252
            self.kernel_manager.has_kernel))
253
        self.log.info('IPython kernel alive {0}'.format(
254
            self.kernel_manager.is_alive()))
255
        self._manager.sigModulesChanged.connect(self.updateIPythonModuleList)
256
257
    def startIPythonWidget(self):
258
        """ Create an IPython console widget and connect it to an IPython
259
        kernel.
260
        """
261
        if (_has_pyqtgraph):
262
            banner_modules = 'The numpy and pyqtgraph modules have already ' \
263
                             'been imported as ''np'' and ''pg''.'
264
        else:
265
            banner_modules = 'The numpy module has already been imported ' \
266
                             'as ''np''.'
267
        banner = """
268
This is an interactive IPython console. {0}
269
Configuration is in 'config', the manager is 'manager' and all loaded modules are in this namespace with their configured name.
270
View the current namespace with dir().
271
Go, play.
272
""".format(banner_modules)
273
        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...
274
        # font size
275
        if 'console_font_size' in self._statusVariables:
276
            self.consoleSetFontSize(self._statusVariables['console_font_size'])
277
        # settings
278
        self._csd = ConsoleSettingsDialog()
279
        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...
280
        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...
281
        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...
282
            QtWidgets.QDialogButtonBox.Apply).clicked.connect(
283
                self.consoleApplySettings)
284
        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...
285
        self.consoleKeepSettings()
286
287
        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...
288
        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...
289
            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...
290
        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...
291
        # the linux style theme which is basically the monokai theme
292
        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...
293
294
    def stopIPython(self):
295
        """ Stop the IPython kernel.
296
        """
297
        self.log.debug('IPy deactivation: {0}'.format(threading.get_ident()))
298
        self.kernel_manager.shutdown_kernel()
299
300
    def stopIPythonWidget(self):
301
        """ Disconnect the IPython widget from the kernel.
302
        """
303
        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...
304
305
    def updateIPythonModuleList(self):
306
        """Remove non-existing modules from namespace,
307
            add new modules to namespace, update reloaded modules
308
        """
309
        currentModules = set()
310
        newNamespace = dict()
311
        for base in ['hardware', 'logic', 'gui']:
312
            for module in self._manager.tree['loaded'][base]:
313
                currentModules.add(module)
314
                newNamespace[module] = self._manager.tree[
315
                    'loaded'][base][module]
316
        discard = self.modules - currentModules
317
        self.namespace.update(newNamespace)
318
        for module in discard:
319
            self.namespace.pop(module, None)
320
        self.modules = currentModules
321
322
    def consoleKeepSettings(self):
323
        """ Write old values into config dialog.
324
        """
325
        if 'console_font_size' in self._statusVariables:
326
            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...
327
                'value', self._statusVariables['console_font_size'])
328
        else:
329
            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...
330
331
    def consoleApplySettings(self):
332
        """ Apply values from config dialog to console.
333
        """
334
        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...
335
336
    def consoleSetFontSize(self, fontsize):
337
        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...
338
        self._statusVariables['console_font_size'] = fontsize
339
        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...
340
341
    def updateConfigWidgets(self):
342
        """ Clear and refill the tree widget showing the configuration.
343
        """
344
        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...
345
346
    def updateGUIModuleList(self):
347
        """ Clear and refill the module list widget
348
        """
349
        # self.clearModuleList(self)
350
        self.fillModuleList(self._mw.guilayout, 'gui')
351
        self.fillModuleList(self._mw.logiclayout, 'logic')
352
        self.fillModuleList(self._mw.hwlayout, 'hardware')
353
354
    def fillModuleList(self, layout, base):
355
        """ Fill the module list widget with module widgets for defined gui
356
            modules.
357
358
          @param QLayout layout: layout of th module list widget where
359
                                 module widgest should be addad
360
          @param str base: module category to fill
361
        """
362
        for module in self._manager.tree['defined'][base]:
363
            if not module in self._manager.tree['global']['startup']:
364
                widget = ModuleListItem(self._manager, base, module)
365
                self.modlist.append(widget)
366
                layout.addWidget(widget)
367
                widget.sigLoadThis.connect(self.sigStartModule)
368
                widget.sigReloadThis.connect(self.sigReloadModule)
369
                widget.sigDeactivateThis.connect(self.sigStopModule)
370
                widget.sigCleanupStatus.connect(self.sigCleanupStatus)
371
                self.checkTimer.timeout.connect(widget.checkModuleState)
372
373
    def fillTreeItem(self, item, value):
374
        """ Recursively fill a QTreeWidgeItem with the contents from a
375
            dictionary.
376
377
          @param QTreeWidgetItem item: the widget item to fill
378
          @param (dict, list, etc) value: value to fill in
379
        """
380
        item.setExpanded(True)
381
        if type(value) is OrderedDict or type(value) is dict:
382
            for key in value:
383
                child = QtWidgets.QTreeWidgetItem()
384
                child.setText(0, key)
385
                item.addChild(child)
386
                self.fillTreeItem(child, value[key])
387
        elif type(value) is list:
388
            for val in value:
389
                child = QtWidgets.QTreeWidgetItem()
390
                item.addChild(child)
391
                if type(val) is dict:
392
                    child.setText(0, '[dict]')
393
                    self.fillTreeItem(child, val)
394
                elif type(val) is OrderedDict:
395
                    child.setText(0, '[odict]')
396
                    self.fillTreeItem(child, val)
397
                elif type(val) is list:
398
                    child.setText(0, '[list]')
399
                    self.fillTreeItem(child, val)
400
                else:
401
                    child.setText(0, str(val))
402
                child.setExpanded(True)
403
        else:
404
            child = QtWidgets.QTreeWidgetItem()
405
            child.setText(0, str(value))
406
            item.addChild(child)
407
408
    def getSoftwareVersion(self):
409
        """ Try to determine the software version in case the program is in
410
            a git repository.
411
        """
412
        try:
413
            repo = Repo(self.get_main_dir())
414
            branch = repo.active_branch
415
            rev = str(repo.head.commit)
416
            return (rev, str(branch))
417
418
        except Exception as e:
419
            print('Could not get git repo because:', e)
420
            return ('unknown', -1)
421
422
    def fillTreeWidget(self, widget, value):
423
        """ Fill a QTreeWidget with the content of a dictionary
424
425
          @param QTreeWidget widget: the tree widget to fill
426
          @param dict,OrderedDict value: the dictionary to fill in
427
        """
428
        widget.clear()
429
        self.fillTreeItem(widget.invisibleRootItem(), value)
430
431
    def reloadConfig(self):
432
        """  Reload the current config. """
433
434
        reply = QtWidgets.QMessageBox.question(
435
            self._mw,
436
            'Restart',
437
            'Do you want to restart the current configuration?',
438
            QtWidgets.QMessageBox.Yes,
439
            QtWidgets.QMessageBox.No
440
        )
441
442
        configFile = self._manager._getConfigFile()
443
        restart = (reply == QtWidgets.QMessageBox.Yes)
444
        self.sigLoadConfig.emit(configFile, restart)
445
446
    def getLoadFile(self):
447
        """ Ask the user for a file where the configuration should be loaded
448
            from
449
        """
450
        defaultconfigpath = os.path.join(self.get_main_dir(), 'config')
451
        filename = QtWidgets.QFileDialog.getOpenFileName(
452
            self._mw,
453
            'Load Configration',
454
            defaultconfigpath,
455
            'Configuration files (*.cfg)')
456
        if filename != '':
457
            reply = QtWidgets.QMessageBox.question(
458
                self._mw,
459
                'Restart',
460
                'Do you want to restart to use the configuration?',
461
                QtWidgets.QMessageBox.Yes,
462
                QtWidgets.QMessageBox.No
463
            )
464
            restart = (reply == QtWidgets.QMessageBox.Yes)
465
            self.sigLoadConfig.emit(filename, restart)
466
467
    def getSaveFile(self):
468
        """ Ask the user for a file where the configuration should be saved
469
            to.
470
        """
471
        defaultconfigpath = os.path.join(self.get_main_dir(), 'config')
472
        filename = QtWidgets.QFileDialog.getSaveFileName(
473
            self._mw,
474
            'Save Configration',
475
            defaultconfigpath,
476
            'Configuration files (*.cfg)')
477
        if filename != '':
478
            self.sigSaveConfig.emit(filename)
479
480
481
class ManagerMainWindow(QtWidgets.QMainWindow):
482
    """ This class represents the Manager Window.
483
    """
484
485
    def __init__(self):
486
        """ Create the Manager Window.
487
        """
488
        # Get the path to the *.ui file
489
        this_dir = os.path.dirname(__file__)
490
        ui_file = os.path.join(this_dir, 'ui_manager_window.ui')
491
492
        # Load it
493
        super(ManagerMainWindow, self).__init__()
494
        uic.loadUi(ui_file, self)
495
        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...
496
497
        # Set up the layout
498
        # this really cannot be done in Qt designer, you cannot set a layout
499
        # on an empty widget
500
        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...
501
        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...
502
        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...
503
504
505
class AboutDialog(QtWidgets.QDialog):
506
    """ This class represents the Qudi About dialog.
507
    """
508
509
    def __init__(self):
510
        """ Create Qudi About Dialog.
511
        """
512
        # Get the path to the *.ui file
513
        this_dir = os.path.dirname(__file__)
514
        ui_file = os.path.join(this_dir, 'ui_about.ui')
515
516
        # Load it
517
        super().__init__()
518
        uic.loadUi(ui_file, self)
519
520
521
class ConsoleSettingsDialog(QtWidgets.QDialog):
522
    """ Create the SettingsDialog window, based on the corresponding *.ui
523
        file.
524
    """
525
526
    def __init__(self):
527
         # Get the path to the *.ui file
528
        this_dir = os.path.dirname(__file__)
529
        ui_file = os.path.join(this_dir, 'ui_console_settings.ui')
530
531
        # Load it
532
        super().__init__()
533
        uic.loadUi(ui_file, self)
534
535
536
class ModuleListItem(QtWidgets.QFrame):
537
    """ This class represents a module widget in the Qudi module list.
538
539
      @signal str str sigLoadThis: gives signal with base and name of module
540
                                   to be loaded
541
      @signal str str sigReloadThis: gives signal with base and name of
542
                                     module to be reloaded
543
      @signal str str sigStopThis: gives signal with base and name of module
544
                                   to be deactivated
545
    """
546
547
    sigLoadThis = QtCore.Signal(str, str)
548
    sigReloadThis = QtCore.Signal(str, str)
549
    sigDeactivateThis = QtCore.Signal(str, str)
550
    sigCleanupStatus = QtCore.Signal(str, str)
551
552
    def __init__(self, manager, basename, modulename):
553
        """ Create a module widget.
554
555
          @param str basename: module category
556
          @param str modulename: unique module name
557
        """
558
        # Get the path to the *.ui file
559
        this_dir = os.path.dirname(__file__)
560
        ui_file = os.path.join(this_dir, 'ui_module_widget.ui')
561
562
        # Load it
563
        super().__init__()
564
        uic.loadUi(ui_file, self)
565
566
        self.manager = manager
567
        self.name = modulename
568
        self.base = basename
569
570
        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...
571
        # connect buttons
572
        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...
573
        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...
574
        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...
575
        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...
576
577
    def loadButtonClicked(self):
578
        """ Send signal to load and activate this module.
579
        """
580
        self.sigLoadThis.emit(self.base, self.name)
581
        if self.base == 'gui':
582
            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...
583
584
    def reloadButtonClicked(self):
585
        """ Send signal to reload this module.
586
        """
587
        self.sigReloadThis.emit(self.base, self.name)
588
589
    def deactivateButtonClicked(self):
590
        """ Send signal to deactivate this module.
591
        """
592
        self.sigDeactivateThis.emit(self.base, self.name)
593
594
    def cleanupButtonClicked(self):
595
        """ Send signal to deactivate this module.
596
        """
597
        self.sigCleanupStatus.emit(self.base, self.name)
598
599
    def checkModuleState(self):
600
        """ Get the state of this module and display it in the statusLabel
601
        """
602
        state = ''
603
        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...
604
            try:
605
                if (self.base in self.manager.tree['loaded']
606
                        and self.name in self.manager.tree['loaded'][
607
                            self.base]):
608
                    state = self.manager.tree['loaded'][
609
                        self.base][self.name].getState()
610
                else:
611
                    state = 'not loaded'
612
            except:
613
                state = 'exception, cannot get state'
614
615
            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...
616