Esempio n. 1
0
    def __init__(self, *args):
        PluginBase.__init__(self, BrickMaster, *args)

        self.setupUi(self)

        self.master = self.device

        # the firmware version of a Brick can (under common circumstances) not
        # change during the lifetime of a Brick plugin. therefore, it's okay to
        # make final decisions based on it here
        self.has_status_led = self.firmware_version >= (2, 3, 2)

        self.update_timer = QTimer(self)
        self.update_timer.timeout.connect(self.update_data)

        self.extension_type = None

        self.extensions = []
        self.num_extensions = 0
        self.wifi2_ext = None
        self.wifi2_firmware_version = None
        self.wifi_update_button = IconButton(QIcon(load_pixmap('update-icon-normal.png')),
                                             QIcon(load_pixmap('update-icon-hover.png')),
                                             self.tab_widget)
        self.wifi_update_button.setToolTip('Update available')
        self.wifi_update_button.clicked.connect(lambda: get_main_window().show_extension_update(self.device_info.uid))
        self.wifi_update_button.hide()

        self.wifi_update_available = False
        self.wifi_tab_idx = None

        self.extension_label.setText("None Present")
        self.tab_widget.removeTab(0)
        self.tab_widget.hide()

        self.check_extensions = True
        self.extension_type_button.clicked.connect(self.extension_clicked)

        if self.has_status_led:
            self.status_led_action = QAction('Status LED', self)
            self.status_led_action.setCheckable(True)
            self.status_led_action.toggled.connect(lambda checked: self.master.enable_status_led() if checked else self.master.disable_status_led())
            self.set_configs([(0, None, [self.status_led_action])])
        else:
            self.status_led_action = None

        reset = QAction('Reset', self)
        reset.triggered.connect(self.master.reset)
        self.set_actions([(0, None, [reset])])

        self.extension_type_preset = [None,  # None
                                      False, # Chibi
                                      False, # RS485
                                      False, # WIFI
                                      False, # Ethernet
                                      False] # WIFI 2.0

        self.update_extensions_in_device_info()
Esempio n. 2
0
    def __init__(self, tab_widget, name, button_handler, parent=None):
        super(TabWindow, self).__init__(parent)

        self.tab_widget = tab_widget
        self.name = name
        self.button = None # see tab()
        self.button_handler = button_handler
        self.button_icon_default = QIcon(load_pixmap('tab-default-icon.png'))
        self.button_icon_mouse_over = QIcon(load_pixmap('tab-mouse-over-icon.png'))
        self.cb_on_tab = None
        self.cb_on_untab = None
Esempio n. 3
0
    def __init__(self, tab_widget, name, button_handler, parent=None):
        super(TabWindow, self).__init__(parent)

        self.tab_widget = tab_widget
        self.name = name
        self.button = None # see tab()
        self.button_handler = button_handler
        self.button_icon_default = QIcon(load_pixmap('tab-default-icon.png'))
        self.button_icon_mouse_over = QIcon(load_pixmap('tab-mouse-over-icon.png'))
        self.cb_on_tab = None
        self.cb_on_untab = None
Esempio n. 4
0
    def __init__(self, tab_widget, name, button_handler, parent=None):
        super().__init__(parent)

        self.tab_widget = tab_widget
        self.name = name
        self.button = None # see tab()
        self.button_handler = button_handler
        self.button_icon_normal = QIcon(load_pixmap('untab-icon-normal.png'))
        self.button_icon_hover = QIcon(load_pixmap('untab-icon-hover.png'))
        self.cb_on_tab = {}
        self.cb_on_untab = {}
        self.cb_post_tab = {}
        self.cb_post_untab = {}
        self.parent_dialog = None
Esempio n. 5
0
    def show_update_tab_button(self, tool_tip, clicked_fn):
        if not self.tabbed:
            return

        self.update_button = IconButton(
            QIcon(load_pixmap('update-icon-normal.png')),
            QIcon(load_pixmap('update-icon-hover.png')))
        self.update_button.setToolTip(tool_tip)
        self.update_button.clicked.connect(clicked_fn)

        tab_idx = self.tab_widget.indexOf(self)

        self.tab_widget.tabBar().setTabButton(tab_idx, QTabBar.RightSide,
                                              self.update_button)
Esempio n. 6
0
    def btn_start_logging_clicked(self):
        """
            Start/Stop of the logging process
        """
        if (self.data_logger_thread is not None) and (not self.data_logger_thread.stopped):
            self.btn_start_logging.clicked.disconnect()

            self.data_logger_thread.stop()
            self._reset_stop()

        elif self.data_logger_thread is None:
            from brickv.data_logger import main

            self._gui_job = GuiDataJob(name="GuiData-Writer")
            self.connect(self._gui_job, QtCore.SIGNAL(GuiDataJob.SIGNAL_NEW_DATA), self.table_add_row)

            self.data_logger_thread = main.main(None, GuiConfigHandler.create_config(self), self._gui_job)

            if self.data_logger_thread is not None:
                self.btn_start_logging.setText("Stop Logging")
                self.btn_start_logging.setIcon(QIcon(load_pixmap('data_logger/stop-icon.png')))
                self.tab_devices.setEnabled(False)
                self.tab_setup.setEnabled(False)
                self.tab_widget.setCurrentIndex(self.tab_widget.indexOf(self.tab_data))
                self.tab_reset_warning()
Esempio n. 7
0
    def __init__(self, tab_widget, name, button_handler, parent=None):
        super().__init__(parent)

        self.tab_widget = tab_widget
        self.name = name
        self.button = None  # see tab()
        self.button_handler = button_handler
        self.button_icon_normal = QIcon(load_pixmap('untab-icon-normal.png'))
        self.button_icon_hover = QIcon(load_pixmap('untab-icon-hover.png'))
        self.cb_on_tab = {}
        self.cb_on_untab = {}
        self.cb_post_tab = {}
        self.cb_post_untab = {}
        self.toplevel_window = None
        self.update_button = None
        self.tabbed = True
Esempio n. 8
0
    def btn_start_logging_clicked(self):
        """
            Start/Stop of the logging process
        """
        if (self.data_logger_thread
                is not None) and (not self.data_logger_thread.stopped):
            self.btn_start_logging.clicked.disconnect()

            self.data_logger_thread.stop()
            self._reset_stop()

        elif self.data_logger_thread is None:
            from brickv.data_logger import main

            self._gui_job = GuiDataJob(name="GuiData-Writer")
            self.connect(self._gui_job,
                         QtCore.SIGNAL(GuiDataJob.SIGNAL_NEW_DATA),
                         self.table_add_row)

            self.data_logger_thread = main.main(
                None, GuiConfigHandler.create_config(self), self._gui_job)

            if self.data_logger_thread is not None:
                self.btn_start_logging.setText("Stop Logging")
                self.btn_start_logging.setIcon(
                    QIcon(load_pixmap('data_logger/stop-icon.png')))
                self.tab_devices.setEnabled(False)
                self.tab_setup.setEnabled(False)
                self.tab_widget.setCurrentIndex(
                    self.tab_widget.indexOf(self.tab_data))
                self.tab_reset_warning()
Esempio n. 9
0
    def __init__(self, context, update_main_ui_state, set_widget_enabled,
                 is_alive, show_upload_files_wizard, show_download_wizard):
        QWidget.__init__(self)

        self.setupUi(self)

        self.session = context.session
        self.script_manager = context.script_manager
        self.program = context.program
        self.update_main_ui_state = update_main_ui_state
        self.set_widget_enabled = set_widget_enabled
        self.is_alive = is_alive
        self.show_download_wizard = show_download_wizard
        self.bin_directory = posixpath.join(self.program.root_directory, 'bin')
        self.refresh_in_progress = False
        self.any_refresh_in_progress = False  # set from ProgramInfoMain.update_ui_state
        self.available_files = []
        self.available_directories = []
        self.folder_icon = QIcon(load_pixmap('folder-icon.png'))
        self.file_icon = QIcon(load_pixmap('file-icon.png'))
        self.tree_files_model = QStandardItemModel(self)
        self.tree_files_model_header = ['Name', 'Size', 'Last Modified']
        self.tree_files_proxy_model = FilesProxyModel(self)
        self.last_download_directory = get_home_path()

        self.tree_files_model.setHorizontalHeaderLabels(
            self.tree_files_model_header)
        self.tree_files_proxy_model.setSourceModel(self.tree_files_model)
        self.tree_files.setModel(self.tree_files_model)
        self.tree_files.setModel(self.tree_files_proxy_model)
        self.tree_files.setColumnWidth(0, 210)
        self.tree_files.setColumnWidth(1, 85)

        self.tree_files.selectionModel().selectionChanged.connect(
            self.update_ui_state)
        self.tree_files.activated.connect(self.rename_activated_file)
        self.button_upload_files.clicked.connect(show_upload_files_wizard)
        self.button_download_files.clicked.connect(
            self.download_selected_files)
        self.button_rename_file.clicked.connect(self.rename_selected_file)
        self.button_change_file_permissions.clicked.connect(
            self.change_permissions_of_selected_file)
        self.button_delete_files.clicked.connect(self.delete_selected_files)

        self.label_error.setVisible(False)
Esempio n. 10
0
def error_report_main():
    error_message = sys.stdin.read()
    label_suffix, error_message = error_message.split('!!!')
    error_message = "<pre>{}</pre>".format(html.escape(error_message).replace("\n", "<br>"))

    app = QApplication(sys.argv)

    if sys.platform == 'darwin':
        # workaround macOS QTBUG-61562
        from brickv.mac_pasteboard_mime_fixed import MacPasteboardMimeFixed
        mac_pasteboard_mime_fixed = MacPasteboardMimeFixed()

    window = QMainWindow()
    window.setWindowTitle('Error - Brick Viewer ' + config.BRICKV_VERSION)
    window.setWindowIcon(QIcon(load_pixmap('brickv-icon.png')))

    widget = QWidget()
    window.setCentralWidget(widget)
    widget.setLayout(QHBoxLayout())

    icon = QLabel()
    icon.setPixmap(QMessageBox.standardIcon(QMessageBox.Critical))
    icon.setAlignment(Qt.AlignHCenter | Qt.AlignTop)
    widget.layout().addWidget(icon)

    right_widget = QWidget()
    right_widget.setLayout(QVBoxLayout())
    right_widget.layout().setContentsMargins(0, 0, 0, 0)

    label = QLabel("Please report this error to <a href='mailto:[email protected]'>[email protected]</a>.<br/>" +
                   "Please also report what you tried to do, when the error was reported.<br/><br/>" +
                   "If you know what caused the error and could work around it, please report it anyway. This allows us to improve the error messages.{}".format(label_suffix))
    label.setWordWrap(True)
    label.setOpenExternalLinks(True)
    right_widget.layout().addWidget(label)

    tb = QTextBrowser()
    tb.setHtml(error_message)
    right_widget.layout().addWidget(tb)

    cbox = QCheckBox("Show this message again")
    cbox.setChecked(True)
    right_widget.layout().addWidget(cbox)

    btn = QPushButton("Close")
    btn.clicked.connect(lambda event: app.exit())
    right_widget.layout().addWidget(btn)

    widget.layout().addWidget(right_widget)
    window.setMinimumSize(640, 400)
    window.resize(950, 600)
    window.show()

    app.exec_()

    return int(cbox.isChecked())
Esempio n. 11
0
    def device_infos_changed(self, uid):
        if uid != self.device_info.uid:
            return

        if self.extension_type_preset[self.master.EXTENSION_TYPE_WIFI2]:
            try:
                wifi_info = next(ext for ext in self.device_info.extensions.values() if ext.extension_type == self.master.EXTENSION_TYPE_WIFI2)
                wifi_update_avail = wifi_info.firmware_version_installed != (0, 0, 0) and wifi_info.firmware_version_installed < wifi_info.firmware_version_latest
            except StopIteration:
                wifi_update_avail = False
        else:
            wifi_update_avail = False

        brick_update_avail = self.device_info.firmware_version_installed < self.device_info.firmware_version_latest

        tab_idx = get_main_window().tab_widget.indexOf(self.device_info.tab_window)

        if not brick_update_avail and not wifi_update_avail:
            if self.device_info.tab_window is not None:
                self.device_info.tab_window.button_update.hide()
            get_main_window().tab_widget.tabBar().setTabButton(tab_idx, QTabBar.RightSide, None)

            if self.wifi_tab_idx is not None:
                self.tab_widget.tabBar().setTabButton(self.wifi_tab_idx, QTabBar.LeftSide, None)
                if self.wifi_update_button is not None:
                    self.wifi_update_button.hide()
            return

        self.update_tab_button = IconButton(QIcon(load_pixmap('update-icon-normal.png')), QIcon(load_pixmap('update-icon-hover.png')))

        if brick_update_avail:
            if self.device_info.tab_window is not None:
                self.device_info.tab_window.button_update.show()
            self.update_tab_button.setToolTip('Update available')
            self.update_tab_button.clicked.connect(lambda: get_main_window().show_brick_update(self.device_info.url_part))

            if self.wifi_tab_idx is not None:
                self.tab_widget.tabBar().setTabButton(self.wifi_tab_idx, QTabBar.LeftSide, None)
                if self.wifi_update_button is not None:
                    self.wifi_update_button.hide()

        # Intentionally override possible Master Brick update notification: The Extension update is easier for users
        # so they are more likely to update at least the Extension. Also when the Extension is updated, device_infos_changed
        # will be called again, then notifying the user of the Master Brick update.
        if wifi_update_avail:
            self.update_tab_button.setToolTip('WIFI Extension 2.0 Update available')
            self.update_tab_button.clicked.connect(lambda: get_main_window().show_extension_update(self.device_info.uid))

            if self.wifi_tab_idx is not None:
                self.tab_widget.tabBar().setTabButton(self.wifi_tab_idx, QTabBar.LeftSide, self.wifi_update_button)
                self.wifi_update_button.show()


        get_main_window().tab_widget.tabBar().setTabButton(tab_idx, QTabBar.RightSide, self.update_tab_button)
Esempio n. 12
0
    def __init__(self, title_prefix='', last_directory=None):
        ProgramPage.__init__(self)

        self.setupUi(self)

        self.edit_mode   = False
        self.folder_icon = QIcon(load_pixmap('folder-icon.png'))
        self.file_icon   = QIcon(load_pixmap('file-icon.png'))

        if last_directory != None:
            self.last_directory = last_directory
        else:
            self.last_directory = get_home_path()

        self.setTitle(title_prefix + 'Files')

        self.list_files.itemSelectionChanged.connect(self.update_ui_state)
        self.button_add_files.clicked.connect(self.show_add_files_dialog)
        self.button_add_directory.clicked.connect(self.show_add_directory_dialog)
        self.button_remove_selected_files.clicked.connect(self.remove_selected_files)
Esempio n. 13
0
    def _reset_stop(self):
        self.tab_devices.setEnabled(True)
        self.tab_setup.setEnabled(True)
        self.btn_start_logging.setText("Start Logging")
        self.btn_start_logging.setIcon(QIcon(load_pixmap('data_logger/start-icon.png')))

        self.disconnect(self._gui_job, QtCore.SIGNAL(GuiDataJob.SIGNAL_NEW_DATA), self.table_add_row)
        self.data_logger_thread = None
        self._gui_job = None

        self.btn_start_logging.clicked.connect(self.btn_start_logging_clicked)
Esempio n. 14
0
    def _reset_stop(self):
        self.tab_devices.setEnabled(True)
        self.tab_setup.setEnabled(True)
        self.btn_start_logging.setText("Start Logging")
        self.btn_start_logging.setIcon(QIcon(load_pixmap('data_logger/start-icon.png')))

        self.disconnect(self._gui_job, QtCore.SIGNAL(GuiDataJob.SIGNAL_NEW_DATA), self.table_add_row)
        self.data_logger_thread = None
        self._gui_job = None

        self.btn_start_logging.clicked.connect(self.btn_start_logging_clicked)
Esempio n. 15
0
def error_report_main():
    error_message = sys.stdin.read()
    error_message = "<pre>{}</pre>".format(html.escape(error_message).replace("\n", "<br>"))

    app = QApplication(sys.argv)

    if sys.platform == 'darwin':
        # workaround macOS QTBUG-61562
        from brickv.mac_pasteboard_mime_fixed import MacPasteboardMimeFixed
        mac_pasteboard_mime_fixed = MacPasteboardMimeFixed()

    window = QMainWindow()
    window.setWindowTitle('Error - Brick Viewer ' + config.BRICKV_VERSION)
    window.setWindowIcon(QIcon(load_pixmap('brickv-icon.png')))

    widget = QWidget()
    window.setCentralWidget(widget)
    widget.setLayout(QHBoxLayout())

    icon = QLabel()
    icon.setPixmap(QMessageBox.standardIcon(QMessageBox.Critical))
    icon.setAlignment(Qt.AlignHCenter | Qt.AlignTop)
    widget.layout().addWidget(icon)

    right_widget = QWidget()
    right_widget.setLayout(QVBoxLayout())
    right_widget.layout().setContentsMargins(0, 0, 0, 0)

    label = QLabel("Please report this error to <a href='mailto:[email protected]'>[email protected]</a>.<br/><br/>" +
                   "If you know what caused the error and could work around it, please report it anyway. This allows us to improve the error messages.")
    label.setWordWrap(True)
    label.setOpenExternalLinks(True)
    right_widget.layout().addWidget(label)

    tb = QTextBrowser()
    tb.setHtml(error_message)
    right_widget.layout().addWidget(tb)

    cbox = QCheckBox("Show this message again")
    cbox.setChecked(True)
    right_widget.layout().addWidget(cbox)

    btn = QPushButton("Close")
    btn.clicked.connect(lambda event: app.exit())
    right_widget.layout().addWidget(btn)

    widget.layout().addWidget(right_widget)
    window.setMinimumSize(640, 400)
    window.resize(950, 600)
    window.show()

    app.exec_()

    return int(cbox.isChecked())
Esempio n. 16
0
    def _reset_stop(self):
        self.tab_devices.setEnabled(True)
        self.tab_setup.setEnabled(True)
        self.btn_start_logging.setText("Start Logging")
        self.btn_start_logging.setIcon(
            QIcon(load_pixmap('data_logger/start-icon.png')))

        self._gui_job.signalNewData.disconnect(self.table_add_row)
        self.data_logger_thread = None
        self._gui_job = None

        self.btn_start_logging.clicked.connect(self.btn_start_logging_clicked)
Esempio n. 17
0
    def _reset_stop(self):
        self.tab_devices.setEnabled(True)
        self.tab_setup.setEnabled(True)
        self.btn_start_logging.setText("Start Logging")
        self.btn_start_logging.setIcon(QIcon(load_pixmap('data_logger/start-icon.png')))


        self._gui_job.signalNewData.disconnect(self.table_add_row)
        self.data_logger_thread = None
        self._gui_job = None

        self.btn_start_logging.clicked.connect(self.btn_start_logging_clicked)
Esempio n. 18
0
    def __init__(self, context, update_main_ui_state, set_widget_enabled, is_alive, show_upload_files_wizard, show_download_wizard):
        QWidget.__init__(self)

        self.setupUi(self)

        self.session                 = context.session
        self.script_manager          = context.script_manager
        self.program                 = context.program
        self.update_main_ui_state    = update_main_ui_state
        self.set_widget_enabled      = set_widget_enabled
        self.is_alive                = is_alive
        self.show_download_wizard    = show_download_wizard
        self.bin_directory           = posixpath.join(self.program.root_directory, 'bin')
        self.refresh_in_progress     = False
        self.any_refresh_in_progress = False # set from ProgramInfoMain.update_ui_state
        self.available_files         = []
        self.available_directories   = []
        self.folder_icon             = QIcon(load_pixmap('folder-icon.png'))
        self.file_icon               = QIcon(load_pixmap('file-icon.png'))
        self.tree_files_model        = QStandardItemModel(self)
        self.tree_files_model_header = ['Name', 'Size', 'Last Modified']
        self.tree_files_proxy_model  = FilesProxyModel(self)
        self.last_download_directory = get_home_path()

        self.tree_files_model.setHorizontalHeaderLabels(self.tree_files_model_header)
        self.tree_files_proxy_model.setSourceModel(self.tree_files_model)
        self.tree_files.setModel(self.tree_files_model)
        self.tree_files.setModel(self.tree_files_proxy_model)
        self.tree_files.setColumnWidth(0, 210)
        self.tree_files.setColumnWidth(1, 85)

        self.tree_files.selectionModel().selectionChanged.connect(self.update_ui_state)
        self.tree_files.activated.connect(self.rename_activated_file)
        self.button_upload_files.clicked.connect(show_upload_files_wizard)
        self.button_download_files.clicked.connect(self.download_selected_files)
        self.button_rename_file.clicked.connect(self.rename_selected_file)
        self.button_change_file_permissions.clicked.connect(self.change_permissions_of_selected_file)
        self.button_delete_files.clicked.connect(self.delete_selected_files)

        self.label_error.setVisible(False)
Esempio n. 19
0
    def __init__(self, title_prefix='', last_directory=None):
        ProgramPage.__init__(self)

        self.setupUi(self)

        self.edit_mode = False
        self.folder_icon = QIcon(load_pixmap('folder-icon.png'))
        self.file_icon = QIcon(load_pixmap('file-icon.png'))

        if last_directory != None:
            self.last_directory = last_directory
        else:
            self.last_directory = get_home_path()

        self.setTitle(title_prefix + 'Files')

        self.list_files.itemSelectionChanged.connect(self.update_ui_state)
        self.button_add_files.clicked.connect(self.show_add_files_dialog)
        self.button_add_directory.clicked.connect(
            self.show_add_directory_dialog)
        self.button_remove_selected_files.clicked.connect(
            self.remove_selected_files)
Esempio n. 20
0
    def __init__(self,
                 download_kind,
                 download_directory,
                 downloads,
                 title_prefix=''):
        ProgramPage.__init__(self)

        self.setupUi(self)

        self.download_kind = download_kind  # 'logs' or 'files'
        self.download_directory = download_directory  # absolute path on host in host format
        self.conflict_resolution_in_progress = False
        self.auto_conflict_resolution = None
        self.download_successful = False
        self.root_directory = None
        self.remaining_downloads = downloads
        self.download = None
        self.created_directories = set()
        self.target_path = None  # abolsute path on host in host format
        self.chunked_downloader = None
        self.replace_help_template = self.label_replace_help.text()
        self.canceled = False

        self.setTitle(title_prefix + 'Download')

        self.progress_file.setVisible(False)

        self.check_rename_new_file.stateChanged.connect(self.update_ui_state)
        self.edit_new_name.textChanged.connect(self.check_new_name)
        self.button_reset_new_name.clicked.connect(self.reset_new_name)
        self.button_replace.clicked.connect(self.resolve_conflict_by_replace)
        self.button_rename.clicked.connect(self.resolve_conflict_by_rename)
        self.button_skip.clicked.connect(self.skip_conflict)
        self.button_start_download.clicked.connect(self.start_download)

        self.label_replace_icon.clear()
        self.label_replace_icon.setPixmap(load_pixmap('warning-icon.png'))

        self.edit_new_name_checker = MandatoryLineEditChecker(
            self, self.label_new_name, self.edit_new_name)

        self.log(u'Going to download {0} to {1}'.format(
            self.download_kind, self.download_directory))
        self.edit_log.moveCursor(QTextCursor.StartOfLine)
Esempio n. 21
0
    def show_status(self, message, icon='warning', message_id=''):
        self.setStatusBar(None)

        if icon != 'none':
            icon_dict = {
                'warning': 'warning-icon-16.png',
            }

            icon_label = QLabel()
            icon_label.setPixmap(load_pixmap(icon_dict[icon]))

            self.statusBar().addWidget(icon_label)

        message_label = QLabel(message)
        message_label.setOpenExternalLinks(True)

        self.statusBar().addWidget(message_label, 1)

        self.last_status_message_id = message_id
Esempio n. 22
0
    def show_status(self, message, icon='warning', message_id=''):
        self.setStatusBar(None)

        if icon != 'none':
            icon_dict = {
                'warning': 'warning-icon-16.png',
            }

            icon_label = QLabel()
            icon_label.setPixmap(load_pixmap(icon_dict[icon]))

            self.statusBar().addWidget(icon_label)

        message_label = QLabel(message)
        message_label.setOpenExternalLinks(True)

        self.statusBar().addWidget(message_label, 1)

        self.last_status_message_id = message_id
Esempio n. 23
0
    def __init__(self, title_prefix=''):
        ProgramPage.__init__(self)

        self.setupUi(self)

        self.edit_mode = False
        self.conflict_resolution_in_progress = False
        self.auto_conflict_resolution = None
        self.upload_successful = False
        self.language_api_name = None
        self.program = None
        self.program_defined = False
        self.root_directory = None
        self.remaining_uploads = None
        self.upload = None
        self.command = None
        self.created_directories = set()
        self.target_path = None  # abolsute path on RED Brick in POSIX format
        self.chunked_uploader = None
        self.replace_help_template = self.label_replace_help.text()
        self.warnings = 0
        self.canceled = False

        self.setTitle(title_prefix + 'Upload')

        self.progress_file.setVisible(False)

        self.check_rename_new_file.stateChanged.connect(self.update_ui_state)
        self.edit_new_name.textChanged.connect(self.check_new_name)
        self.button_reset_new_name.clicked.connect(self.reset_new_name)
        self.button_replace.clicked.connect(self.resolve_conflict_by_replace)
        self.button_rename.clicked.connect(self.resolve_conflict_by_rename)
        self.button_skip.clicked.connect(self.skip_conflict)
        self.button_start_upload.clicked.connect(self.start_upload)

        self.label_replace_icon.clear()
        self.label_replace_icon.setPixmap(load_pixmap('warning-icon.png'))

        self.edit_new_name_checker = MandatoryLineEditChecker(
            self, self.label_new_name, self.edit_new_name)
Esempio n. 24
0
    def __init__(self, title_prefix=''):
        ProgramPage.__init__(self)

        self.setupUi(self)

        self.edit_mode                       = False
        self.conflict_resolution_in_progress = False
        self.auto_conflict_resolution        = None
        self.upload_successful               = False
        self.language_api_name               = None
        self.program                         = None
        self.program_defined                 = False
        self.root_directory                  = None
        self.remaining_uploads               = None
        self.upload                          = None
        self.command                         = None
        self.created_directories             = set()
        self.target_path                     = None # abolsute path on RED Brick in POSIX format
        self.chunked_uploader                = None
        self.replace_help_template           = self.label_replace_help.text()
        self.warnings                        = 0
        self.canceled                        = False

        self.setTitle(title_prefix + 'Upload')

        self.progress_file.setVisible(False)

        self.check_rename_new_file.stateChanged.connect(self.update_ui_state)
        self.edit_new_name.textChanged.connect(self.check_new_name)
        self.button_reset_new_name.clicked.connect(self.reset_new_name)
        self.button_replace.clicked.connect(self.resolve_conflict_by_replace)
        self.button_rename.clicked.connect(self.resolve_conflict_by_rename)
        self.button_skip.clicked.connect(self.skip_conflict)
        self.button_start_upload.clicked.connect(self.start_upload)

        self.label_replace_icon.clear()
        self.label_replace_icon.setPixmap(load_pixmap('warning-icon-44.png'))

        self.edit_new_name_checker = MandatoryLineEditChecker(self, self.label_new_name, self.edit_new_name)
Esempio n. 25
0
    def __init__(self, context, update_main_ui_state, set_widget_enabled,
                 is_alive, show_download_wizard,
                 set_program_callbacks_enabled):
        QWidget.__init__(self)

        self.setupUi(self)

        self.session = context.session
        self.script_manager = context.script_manager
        self.program = context.program
        self.update_main_ui_state = update_main_ui_state
        self.set_widget_enabled = set_widget_enabled
        self.is_alive = is_alive
        self.show_download_wizard = show_download_wizard
        self.set_program_callbacks_enabled = set_program_callbacks_enabled
        self.log_directory = posixpath.join(self.program.root_directory, 'log')
        self.refresh_in_progress = False
        self.any_refresh_in_progress = False  # set from ProgramInfoMain.update_ui_state
        self.view_dialog = None
        self.file_icon = QIcon(load_pixmap('file-icon.png'))
        self.tree_logs_model = QStandardItemModel(self)
        self.tree_logs_model_header = ['Date/Time', 'Size']
        self.tree_logs_proxy_model = LogsProxyModel(self)
        self.last_download_directory = get_home_path()

        self.tree_logs_model.setHorizontalHeaderLabels(
            self.tree_logs_model_header)
        self.tree_logs_proxy_model.setSourceModel(self.tree_logs_model)
        self.tree_logs.setModel(self.tree_logs_proxy_model)
        self.tree_logs.setColumnWidth(0, 250)

        self.tree_logs.selectionModel().selectionChanged.connect(
            self.update_ui_state)
        self.tree_logs.activated.connect(self.view_activated_log)
        self.button_download_logs.clicked.connect(self.download_selected_logs)
        self.button_view_log.clicked.connect(self.view_selected_log)
        self.button_delete_logs.clicked.connect(self.delete_selected_logs)

        self.label_error.setVisible(False)
Esempio n. 26
0
    def __init__(self, download_kind, download_directory, downloads, title_prefix=''):
        ProgramPage.__init__(self)

        self.setupUi(self)

        self.download_kind                   = download_kind # 'logs' or 'files'
        self.download_directory              = download_directory # absolute path on host in host format
        self.conflict_resolution_in_progress = False
        self.auto_conflict_resolution        = None
        self.download_successful             = False
        self.root_directory                  = None
        self.remaining_downloads             = downloads
        self.download                        = None
        self.created_directories             = set()
        self.target_path                     = None # abolsute path on host in host format
        self.chunked_downloader              = None
        self.replace_help_template           = self.label_replace_help.text()
        self.canceled                        = False

        self.setTitle(title_prefix + 'Download')

        self.progress_file.setVisible(False)

        self.check_rename_new_file.stateChanged.connect(self.update_ui_state)
        self.edit_new_name.textChanged.connect(self.check_new_name)
        self.button_reset_new_name.clicked.connect(self.reset_new_name)
        self.button_replace.clicked.connect(self.resolve_conflict_by_replace)
        self.button_rename.clicked.connect(self.resolve_conflict_by_rename)
        self.button_skip.clicked.connect(self.skip_conflict)
        self.button_start_download.clicked.connect(self.start_download)

        self.label_replace_icon.clear()
        self.label_replace_icon.setPixmap(load_pixmap('warning-icon-44.png'))

        self.edit_new_name_checker = MandatoryLineEditChecker(self, self.label_new_name, self.edit_new_name)

        self.log('Going to download {0} to {1}'.format(self.download_kind, self.download_directory))
        self.edit_log.moveCursor(QTextCursor.StartOfLine)
Esempio n. 27
0
    def __init__(self, context, update_main_ui_state, set_widget_enabled, is_alive,
                 show_download_wizard, set_program_callbacks_enabled):
        QWidget.__init__(self)

        self.setupUi(self)

        self.session                       = context.session
        self.script_manager                = context.script_manager
        self.program                       = context.program
        self.update_main_ui_state          = update_main_ui_state
        self.set_widget_enabled            = set_widget_enabled
        self.is_alive                      = is_alive
        self.show_download_wizard          = show_download_wizard
        self.set_program_callbacks_enabled = set_program_callbacks_enabled
        self.log_directory                 = posixpath.join(self.program.root_directory, 'log')
        self.refresh_in_progress           = False
        self.any_refresh_in_progress       = False # set from ProgramInfoMain.update_ui_state
        self.view_dialog                   = None
        self.file_icon                     = QIcon(load_pixmap('file-icon.png'))
        self.tree_logs_model               = QStandardItemModel(self)
        self.tree_logs_model_header        = ['Date/Time', 'Size']
        self.tree_logs_proxy_model         = LogsProxyModel(self)
        self.last_download_directory       = get_home_path()

        self.tree_logs_model.setHorizontalHeaderLabels(self.tree_logs_model_header)
        self.tree_logs_proxy_model.setSourceModel(self.tree_logs_model)
        self.tree_logs.setModel(self.tree_logs_proxy_model)
        self.tree_logs.setColumnWidth(0, 250)

        self.tree_logs.selectionModel().selectionChanged.connect(self.update_ui_state)
        self.tree_logs.activated.connect(self.view_activated_log)
        self.button_download_logs.clicked.connect(self.download_selected_logs)
        self.button_view_log.clicked.connect(self.view_selected_log)
        self.button_delete_logs.clicked.connect(self.delete_selected_logs)

        self.label_error.setVisible(False)
Esempio n. 28
0
    def __init__(self, parent, host_infos):
        QDialog.__init__(self, parent, get_modeless_dialog_flags())

        self._gui_logger = GUILogger("GUILogger", logging.INFO)
        self._gui_job = None
        EventLogger.add_logger(self._gui_logger)

        self.data_logger_thread = None
        self.tab_debug_warning = False
        self.device_dialog = None
        self.last_host_index = -1

        self.setupUi(self)

        self.model_data = QStandardItemModel(self)
        self.model_data.setHorizontalHeaderLabels(['Time', 'Name', 'UID', 'Var', 'Raw', 'Unit'])
        self.table_data.setModel(self.model_data)
        self.table_data.setColumnWidth(0, 160)
        self.table_data.setColumnWidth(1, 170)
        self.table_data.setColumnWidth(2, 50)
        self.table_data.setColumnWidth(3, 110)
        self.table_data.setColumnWidth(4, 70)
        self.table_data.setColumnWidth(5, 100)

        self.model_devices = QStandardItemModel(self)
        self.model_devices.setHorizontalHeaderLabels(['Device', 'Value'])
        self.tree_devices.setModel(self.model_devices)
        self.tree_devices.setColumnWidth(0, 300)

        self.signal_initialization()

        self.check_authentication.stateChanged.connect(self.authentication_state_changed)
        self.label_secret.hide()
        self.edit_secret.hide()
        self.edit_secret.setEchoMode(QLineEdit.Password)
        self.check_secret_show.hide()
        self.check_secret_show.stateChanged.connect(self.secret_show_state_changed)

        self.btn_start_logging.setIcon(QIcon(load_pixmap('data_logger/start-icon.png')))

        self.example_timestamp = time.time()

        self.edit_csv_file_name.setText(os.path.join(get_home_path(), 'logger_data_{0}.csv'.format(int(self.example_timestamp))))
        self.edit_log_file_name.setText(os.path.join(get_home_path(), 'logger_debug_{0}.log'.format(int(self.example_timestamp))))

        self.combo_data_time_format.addItem(utils.timestamp_to_de(self.example_timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de')
        self.combo_data_time_format.addItem(utils.timestamp_to_de_msec(self.example_timestamp) + ' (DD.MM.YYYY HH:MM:SS,000)', 'de-msec')
        self.combo_data_time_format.insertSeparator(self.combo_data_time_format.count())
        self.combo_data_time_format.addItem(utils.timestamp_to_us(self.example_timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us')
        self.combo_data_time_format.addItem(utils.timestamp_to_us_msec(self.example_timestamp) + ' (MM/DD/YYYY HH:MM:SS.000)', 'us-msec')
        self.combo_data_time_format.insertSeparator(self.combo_data_time_format.count())
        self.combo_data_time_format.addItem(utils.timestamp_to_iso(self.example_timestamp) + ' (ISO 8601)', 'iso')
        self.combo_data_time_format.addItem(utils.timestamp_to_iso_msec(self.example_timestamp) + ' (ISO 8601 + Milliseconds)', 'iso-msec')
        self.combo_data_time_format.insertSeparator(self.combo_data_time_format.count())
        self.combo_data_time_format.addItem(utils.timestamp_to_unix(self.example_timestamp) + ' (Unix)', 'unix')
        self.combo_data_time_format.addItem(utils.timestamp_to_unix_msec(self.example_timestamp) + ' (Unix + Milliseconds)', 'unix-msec')
        self.combo_data_time_format.insertSeparator(self.combo_data_time_format.count())

        t = utils.timestamp_to_strftime(self.example_timestamp, self.edit_data_time_format_strftime.text())
        if len(t) == 0:
            t = '<empty>'

        self.combo_data_time_format.addItem((t + ' (strftime)'), 'strftime')

        self.combo_debug_time_format.addItem(utils.timestamp_to_de(self.example_timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de')
        self.combo_debug_time_format.addItem(utils.timestamp_to_us(self.example_timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us')
        self.combo_debug_time_format.addItem(utils.timestamp_to_iso(self.example_timestamp) + ' (ISO 8601)', 'iso')
        self.combo_debug_time_format.addItem(utils.timestamp_to_unix(self.example_timestamp) + ' (Unix)', 'unix')

        self.combo_log_level.addItem('Debug', 'debug')
        self.combo_log_level.addItem('Info', 'info')
        self.combo_log_level.addItem('Warning', 'warning')
        self.combo_log_level.addItem('Error', 'error')
        self.combo_log_level.addItem('Critical', 'critical')
        self.combo_log_level.setCurrentIndex(0) # debug

        self.combo_debug_level.addItem('Debug', logging.DEBUG)
        self.combo_debug_level.addItem('Info', logging.INFO)
        self.combo_debug_level.addItem('Warning', logging.WARNING)
        self.combo_debug_level.addItem('Error', logging.ERROR)
        self.combo_debug_level.addItem('Critical', logging.CRITICAL)
        self.combo_debug_level.setCurrentIndex(1) # info

        for host_info in host_infos:
            self.combo_host.addItem(host_info.host, (host_info.port, host_info.use_authentication, host_info.secret))

        self._host_index_changed(0)

        self.update_ui_state()
Esempio n. 29
0
    def __init__(self, parent):
        QDialog.__init__(self, parent)

        self._gui_logger = GUILogger("GUILogger", logging.INFO)
        self._gui_job = None
        EventLogger.add_logger(self._gui_logger)

        # FIXME better way to find interval and uids in tree_widget?!
        self.__tree_interval_tooltip = "Update interval in seconds"
        self.__tree_uid_tooltip = "UID cannot be empty"
        self.data_logger_thread = None
        self.tab_debug_warning = False

        self.device_dialog = None

        self.host_infos = None
        self.last_host = None
        self.host_index_changing = None

        self.setupUi(self)

        self.model_data = QStandardItemModel(self)
        self.model_data.setHorizontalHeaderLabels(['Time', 'Name', 'UID', 'Var', 'Raw', 'Unit'])
        self.table_data.setModel(self.model_data)
        self.table_data.setColumnWidth(0, 160)
        self.table_data.setColumnWidth(1, 170)
        self.table_data.setColumnWidth(2, 50)
        self.table_data.setColumnWidth(3, 110)
        self.table_data.setColumnWidth(4, 70)
        self.table_data.setColumnWidth(5, 100)

        self.model_devices = QStandardItemModel(self)
        self.model_devices.setHorizontalHeaderLabels(['Device', 'Value'])
        self.tree_devices.setModel(self.model_devices)
        self.tree_devices.setColumnWidth(0, 300)

        self.widget_initialization()

        self.btn_start_logging.setIcon(QIcon(load_pixmap('data_logger/start-icon.png')))

        timestamp = int(time.time())
        self.edit_csv_file_name.setText(os.path.join(get_home_path(), 'logger_data_{0}.csv'.format(timestamp)))
        self.edit_log_file_name.setText(os.path.join(get_home_path(), 'logger_debug_{0}.log'.format(timestamp)))

        self.combo_data_time_format.addItem(utils.timestamp_to_de(timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de')
        self.combo_data_time_format.addItem(utils.timestamp_to_us(timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us')
        self.combo_data_time_format.addItem(utils.timestamp_to_iso(timestamp) + ' (ISO 8601)', 'iso')
        self.combo_data_time_format.addItem(utils.timestamp_to_unix(timestamp) + ' (Unix)', 'unix')

        self.combo_debug_time_format.addItem(utils.timestamp_to_de(timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de')
        self.combo_debug_time_format.addItem(utils.timestamp_to_us(timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us')
        self.combo_debug_time_format.addItem(utils.timestamp_to_iso(timestamp) + ' (ISO 8601)', 'iso')
        self.combo_debug_time_format.addItem(utils.timestamp_to_unix(timestamp) + ' (Unix)', 'unix')

        self.combo_log_level.addItem('Debug', 'debug')
        self.combo_log_level.addItem('Info', 'info')
        self.combo_log_level.addItem('Warning', 'warning')
        self.combo_log_level.addItem('Error', 'error')
        self.combo_log_level.addItem('Critical', 'critical')
        self.combo_log_level.setCurrentIndex(0) # debug

        self.combo_debug_level.addItem('Debug', logging.DEBUG)
        self.combo_debug_level.addItem('Info', logging.INFO)
        self.combo_debug_level.addItem('Warning', logging.WARNING)
        self.combo_debug_level.addItem('Error', logging.ERROR)
        self.combo_debug_level.addItem('Critical', logging.CRITICAL)
        self.combo_debug_level.setCurrentIndex(1) # info

        self.update_ui_state()
Esempio n. 30
0
    def __init__(self, parent, host_infos):
        QDialog.__init__(self, parent, get_modeless_dialog_flags())

        self._gui_logger = GUILogger("GUILogger", logging.INFO)
        self._gui_job = None
        EventLogger.add_logger(self._gui_logger)

        self.data_logger_thread = None
        self.tab_debug_warning = False
        self.device_dialog = None
        self.last_host_index = -1

        self.setupUi(self)

        self.model_data = QStandardItemModel(self)
        self.model_data.setHorizontalHeaderLabels(
            ['Time', 'Name', 'UID', 'Var', 'Raw', 'Unit'])
        self.table_data.setModel(self.model_data)
        self.table_data.setColumnWidth(0, 160)
        self.table_data.setColumnWidth(1, 170)
        self.table_data.setColumnWidth(2, 50)
        self.table_data.setColumnWidth(3, 110)
        self.table_data.setColumnWidth(4, 70)
        self.table_data.setColumnWidth(5, 100)

        self.model_devices = QStandardItemModel(self)
        self.model_devices.setHorizontalHeaderLabels(['Device', 'Value'])
        self.tree_devices.setModel(self.model_devices)
        self.tree_devices.setColumnWidth(0, 300)

        self.signal_initialization()

        self.check_authentication.stateChanged.connect(
            self.authentication_state_changed)
        self.label_secret.hide()
        self.edit_secret.hide()
        self.edit_secret.setEchoMode(QLineEdit.Password)
        self.check_secret_show.hide()
        self.check_secret_show.stateChanged.connect(
            self.secret_show_state_changed)

        self.btn_start_logging.setIcon(
            QIcon(load_pixmap('data_logger/start-icon.png')))

        self.example_timestamp = time.time()

        self.edit_csv_file_name.setText(
            os.path.join(
                get_home_path(),
                'logger_data_{0}.csv'.format(int(self.example_timestamp))))
        self.edit_log_file_name.setText(
            os.path.join(
                get_home_path(),
                'logger_debug_{0}.log'.format(int(self.example_timestamp))))

        self.combo_data_time_format.addItem(
            utils.timestamp_to_de(self.example_timestamp) +
            ' (DD.MM.YYYY HH:MM:SS)', 'de')
        self.combo_data_time_format.addItem(
            utils.timestamp_to_de_msec(self.example_timestamp) +
            ' (DD.MM.YYYY HH:MM:SS,000)', 'de-msec')
        self.combo_data_time_format.insertSeparator(
            self.combo_data_time_format.count())
        self.combo_data_time_format.addItem(
            utils.timestamp_to_us(self.example_timestamp) +
            ' (MM/DD/YYYY HH:MM:SS)', 'us')
        self.combo_data_time_format.addItem(
            utils.timestamp_to_us_msec(self.example_timestamp) +
            ' (MM/DD/YYYY HH:MM:SS.000)', 'us-msec')
        self.combo_data_time_format.insertSeparator(
            self.combo_data_time_format.count())
        self.combo_data_time_format.addItem(
            utils.timestamp_to_iso(self.example_timestamp) + ' (ISO 8601)',
            'iso')
        self.combo_data_time_format.addItem(
            utils.timestamp_to_iso_msec(self.example_timestamp) +
            ' (ISO 8601 + Milliseconds)', 'iso-msec')
        self.combo_data_time_format.insertSeparator(
            self.combo_data_time_format.count())
        self.combo_data_time_format.addItem(
            utils.timestamp_to_unix(self.example_timestamp) + ' (Unix)',
            'unix')
        self.combo_data_time_format.addItem(
            utils.timestamp_to_unix_msec(self.example_timestamp) +
            ' (Unix + Milliseconds)', 'unix-msec')
        self.combo_data_time_format.insertSeparator(
            self.combo_data_time_format.count())

        t = utils.timestamp_to_strftime(
            self.example_timestamp, self.edit_data_time_format_strftime.text())
        if len(t) == 0:
            t = '<empty>'

        self.combo_data_time_format.addItem((t + ' (strftime)'), 'strftime')

        self.combo_debug_time_format.addItem(
            utils.timestamp_to_de(self.example_timestamp) +
            ' (DD.MM.YYYY HH:MM:SS)', 'de')
        self.combo_debug_time_format.addItem(
            utils.timestamp_to_us(self.example_timestamp) +
            ' (MM/DD/YYYY HH:MM:SS)', 'us')
        self.combo_debug_time_format.addItem(
            utils.timestamp_to_iso(self.example_timestamp) + ' (ISO 8601)',
            'iso')
        self.combo_debug_time_format.addItem(
            utils.timestamp_to_unix(self.example_timestamp) + ' (Unix)',
            'unix')

        self.combo_log_level.addItem('Debug', 'debug')
        self.combo_log_level.addItem('Info', 'info')
        self.combo_log_level.addItem('Warning', 'warning')
        self.combo_log_level.addItem('Error', 'error')
        self.combo_log_level.addItem('Critical', 'critical')
        self.combo_log_level.setCurrentIndex(0)  # debug

        self.combo_debug_level.addItem('Debug', logging.DEBUG)
        self.combo_debug_level.addItem('Info', logging.INFO)
        self.combo_debug_level.addItem('Warning', logging.WARNING)
        self.combo_debug_level.addItem('Error', logging.ERROR)
        self.combo_debug_level.addItem('Critical', logging.CRITICAL)
        self.combo_debug_level.setCurrentIndex(1)  # info

        for host_info in host_infos:
            self.combo_host.addItem(
                host_info.host, (host_info.port, host_info.use_authentication,
                                 host_info.secret))

        self._host_index_changed(0)

        self.update_ui_state()
Esempio n. 31
0
    def __init__(self, *args):
        PluginBase.__init__(self, BrickMaster, *args)

        self.setupUi(self)

        self.master = self.device

        # the firmware version of a Brick can (under common circumstances) not
        # change during the lifetime of a Brick plugin. therefore, it's okay to
        # make final decisions based on it here
        self.has_status_led = self.firmware_version >= (2, 3, 2)

        self.update_timer = QTimer(self)
        self.update_timer.timeout.connect(self.update_data)

        self.extension_type = None

        self.extension_tabs = []

        self.wifi2_firmware_version = None

        self.wifi2_update_button = IconButton(
            QIcon(load_pixmap('update-icon-normal.png')),
            QIcon(load_pixmap('update-icon-hover.png')), self.tab_widget)
        self.wifi2_update_button.setToolTip('Update available')
        self.wifi2_update_button.clicked.connect(lambda: get_main_window(
        ).show_extension_update(self.device_info.uid))
        self.wifi2_update_button.hide()

        self.wifi2_tab_idx = None
        self.wifi2_start_done = False

        self.extension_label.setText("None Present")
        self.tab_widget.removeTab(0)
        self.tab_widget.hide()

        self.start_extensions = True
        self.extension_type_button.clicked.connect(self.extension_clicked)

        if self.has_status_led:
            self.status_led_action = QAction('Status LED', self)
            self.status_led_action.setCheckable(True)
            self.status_led_action.toggled.connect(
                lambda checked: self.master.enable_status_led()
                if checked else self.master.disable_status_led())
            self.set_configs([(0, None, [self.status_led_action])])
        else:
            self.status_led_action = None

        reset = QAction('Reset', self)
        reset.triggered.connect(self.master.reset)
        self.set_actions([(0, None, [reset])])

        self.extension_type_present = [
            None,  # None
            False,  # Chibi
            False,  # RS485
            False,  # WIFI
            False,  # Ethernet
            False
        ]  # WIFI 2.0

        self.query_extensions()
Esempio n. 32
0
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)

        self.setupUi(self)

        # Setting the minimum width of the setup tab ensures, that other tabs can grow
        # the window if more space is required, but we have a sane default for status
        # messages. Setting the minimum width of the main window itself would enfoce
        # it, even if children (i.e. tabs) need more space.
        self.tab_setup.setMinimumWidth(550)

        signal.signal(signal.SIGINT, self.exit_brickv)
        signal.signal(signal.SIGTERM, self.exit_brickv)

        self.async_thread = async_start_thread(self)

        title = 'Brick Viewer ' + config.BRICKV_FULL_VERSION

        self.setWindowTitle(title)

        self.delayed_update_tree_view_timer = QTimer(self)
        self.delayed_update_tree_view_timer.timeout.connect(
            self.update_tree_view)
        self.delayed_update_tree_view_timer.setInterval(100)

        self.tree_view_model_labels = ['Name', 'UID', 'Position', 'FW Version']
        self.tree_view_model = QStandardItemModel(self)
        self.tree_view_proxy_model = DevicesProxyModel(self)
        self.tree_view_proxy_model.setSourceModel(self.tree_view_model)
        self.tree_view.setModel(self.tree_view_proxy_model)
        self.tree_view.activated.connect(self.item_activated)
        self.set_tree_view_defaults()

        inventory.info_changed.connect(
            lambda: self.delayed_update_tree_view_timer.start())

        self.tab_widget.removeTab(1)  # remove dummy tab
        self.tab_widget.setUsesScrollButtons(True)  # force scroll buttons

        self.update_tab_button = IconButton(
            QIcon(load_pixmap('update-icon-normal.png')),
            QIcon(load_pixmap('update-icon-hover.png')),
            parent=self.tab_setup)
        self.update_tab_button.setToolTip('Updates available')
        self.update_tab_button.clicked.connect(self.flashing_clicked)
        self.update_tab_button.hide()

        self.name = '<unknown>'
        self.uid = '<unknown>'
        self.version = (0, 0, 0)

        self.disconnect_times = []

        self.qtcb_enumerate.connect(self.cb_enumerate)
        self.qtcb_connected.connect(self.cb_connected)
        self.qtcb_disconnected.connect(self.cb_disconnected)

        self.ipcon = IPConnection()
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.qtcb_enumerate.emit)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.qtcb_connected.emit)
        self.ipcon.register_callback(IPConnection.CALLBACK_DISCONNECTED,
                                     self.qtcb_disconnected.emit)

        self.current_device_info = None
        self.flashing_window = None
        self.advanced_window = None
        self.data_logger_window = None
        self.delayed_refresh_updates_timer = QTimer(self)
        self.delayed_refresh_updates_timer.timeout.connect(
            self.delayed_refresh_updates)
        self.delayed_refresh_updates_timer.setInterval(100)
        self.reset_view()
        self.button_advanced.setDisabled(True)

        self.fw_version_fetcher = LatestFWVersionFetcher()
        self.fw_version_fetcher.fw_versions_avail.connect(
            self.fw_versions_fetched)
        self.fw_version_fetcher_thread = QThread(self)
        self.fw_version_fetcher_thread.setObjectName(
            "fw_version_fetcher_thread")

        if config.get_auto_search_for_updates():
            self.enable_auto_search_for_updates()
        else:
            self.disable_auto_search_for_updates()

        self.tab_widget.currentChanged.connect(self.tab_changed)
        self.tab_widget.setMovable(True)
        self.tab_widget.tabBar().installEventFilter(self)

        self.button_connect.clicked.connect(self.connect_clicked)
        self.button_flashing.clicked.connect(self.flashing_clicked)
        self.button_advanced.clicked.connect(self.advanced_clicked)
        self.button_data_logger.clicked.connect(self.data_logger_clicked)
        self.plugin_manager = PluginManager()

        # host info
        self.host_infos = config.get_host_infos(config.HOST_INFO_COUNT)
        self.host_index_changing = True

        for host_info in self.host_infos:
            self.combo_host.addItem(host_info.host)

        self.last_host = None
        self.combo_host.installEventFilter(self)
        self.combo_host.currentIndexChanged.connect(self.host_index_changed)

        self.spinbox_port.setValue(self.host_infos[0].port)
        self.spinbox_port.valueChanged.connect(self.port_changed)
        self.spinbox_port.installEventFilter(self)

        self.checkbox_authentication.stateChanged.connect(
            self.authentication_state_changed)

        self.label_secret.hide()
        self.edit_secret.hide()
        self.edit_secret.setEchoMode(QLineEdit.Password)
        self.edit_secret.textEdited.connect(self.secret_changed)
        self.edit_secret.installEventFilter(self)

        self.checkbox_secret_show.hide()
        self.checkbox_secret_show.stateChanged.connect(
            self.secret_show_state_changed)

        self.checkbox_remember_secret.hide()
        self.checkbox_remember_secret.stateChanged.connect(
            self.remember_secret_state_changed)

        self.checkbox_authentication.setChecked(
            self.host_infos[0].use_authentication)
        self.edit_secret.setText(self.host_infos[0].secret)
        self.checkbox_remember_secret.setChecked(
            self.host_infos[0].remember_secret)

        self.host_index_changing = False

        # auto-reconnect
        self.label_auto_reconnects.hide()
        self.auto_reconnects = 0

        # RED Session losts
        self.label_red_session_losts.hide()
        self.red_session_losts = 0

        # fusion style
        self.check_fusion_gui_style.setChecked(
            config.get_use_fusion_gui_style())
        self.check_fusion_gui_style.stateChanged.connect(
            self.gui_style_changed)

        self.checkbox_auto_search_for_updates.setChecked(
            config.get_auto_search_for_updates())
        self.checkbox_auto_search_for_updates.stateChanged.connect(
            self.auto_search_for_updates_changed)

        self.button_update_pixmap_normal = load_pixmap(
            'update-icon-normal.png')
        self.button_update_pixmap_hover = load_pixmap('update-icon-hover.png')

        self.last_status_message_id = ''
Esempio n. 33
0
    def __init__(self, wifi2_firmware_version, parent):
        QWidget.__init__(self)

        self.setupUi(self)

        self.parent = parent
        self.master = parent.master

        self.wifi2_status = None

        if parent.firmware_version < (2, 4, 0):
            # This should not be possible
            return

        self.wifi2_firmware_version = wifi2_firmware_version

        self.wifi_update_firmware_button.setIcon(
            QIcon(load_pixmap('update-icon-normal.png')))
        self.wifi_update_firmware_button.clicked.connect(
            lambda: get_main_window().show_extension_update(parent.device_info.
                                                            uid))
        self.wifi_update_firmware_button.hide()

        self.wifi_firmware_version_label.setText(
            get_version_string(
                wifi2_firmware_version,
                replace_unknown='Waiting for WIFI Extension 2.0 FW Version...')
        )

        self.general_group = [
            self.wifi_port_label, self.wifi_port,
            self.wifi_websocket_port_label, self.wifi_websocket_port,
            self.wifi_website_port_label, self.wifi_website_port,
            self.wifi_disable_web_interface, self.wifi_phy_mode_label,
            self.wifi_phy_mode, self.wifi_use_auth, self.wifi_secret_label,
            self.wifi_secret, self.wifi_show_characters
        ]

        self.authentication_group = [
            self.wifi_secret_label, self.wifi_secret, self.wifi_show_characters
        ]

        self.client_ip_group = [
            self.wifi_client_ip_label, self.wifi_client_sub_label,
            self.wifi_client_gw_label, self.wifi_client_ip4,
            self.wifi_client_ip3, self.wifi_client_ip2, self.wifi_client_ip1,
            self.wifi_client_sub4, self.wifi_client_sub3,
            self.wifi_client_sub2, self.wifi_client_sub1, self.wifi_client_gw4,
            self.wifi_client_gw3, self.wifi_client_gw2, self.wifi_client_gw1,
            self.wifi_client_dot1, self.wifi_client_dot2,
            self.wifi_client_dot3, self.wifi_client_dot4,
            self.wifi_client_dot5, self.wifi_client_dot6,
            self.wifi_client_dot7, self.wifi_client_dot8, self.wifi_client_dot9
        ]
        self.client_bssid_group = [
            self.wifi_client_bssid_label, self.wifi_client_bssid6,
            self.wifi_client_bssid5, self.wifi_client_bssid4,
            self.wifi_client_bssid3, self.wifi_client_bssid2,
            self.wifi_client_bssid1, self.wifi_client_bssid_dot1,
            self.wifi_client_bssid_dot2, self.wifi_client_bssid_dot3,
            self.wifi_client_bssid_dot4, self.wifi_client_bssid_dot5
        ]
        self.client_mac_group = [
            self.wifi_client_mac_label, self.wifi_client_mac6,
            self.wifi_client_mac5, self.wifi_client_mac4,
            self.wifi_client_mac3, self.wifi_client_mac2,
            self.wifi_client_mac1, self.wifi_client_mac_dot1,
            self.wifi_client_mac_dot2, self.wifi_client_mac_dot3,
            self.wifi_client_mac_dot4, self.wifi_client_mac_dot5
        ]
        self.client_enc_group = [
            self.wifi_client_password_label, self.wifi_client_change_password,
            self.wifi_client_password, self.wifi_client_password_show
        ]

        self.ap_ip_group = [
            self.wifi_ap_ip_label, self.wifi_ap_sub_label,
            self.wifi_ap_gw_label, self.wifi_ap_ip4, self.wifi_ap_ip3,
            self.wifi_ap_ip2, self.wifi_ap_ip1, self.wifi_ap_sub4,
            self.wifi_ap_sub3, self.wifi_ap_sub2, self.wifi_ap_sub1,
            self.wifi_ap_gw4, self.wifi_ap_gw3, self.wifi_ap_gw2,
            self.wifi_ap_gw1, self.wifi_ap_dot1, self.wifi_ap_dot2,
            self.wifi_ap_dot3, self.wifi_ap_dot4, self.wifi_ap_dot5,
            self.wifi_ap_dot6, self.wifi_ap_dot7, self.wifi_ap_dot8,
            self.wifi_ap_dot9
        ]
        self.ap_mac_group = [
            self.wifi_ap_mac_label, self.wifi_ap_mac6, self.wifi_ap_mac5,
            self.wifi_ap_mac4, self.wifi_ap_mac3, self.wifi_ap_mac2,
            self.wifi_ap_mac1, self.wifi_ap_mac_dot1, self.wifi_ap_mac_dot2,
            self.wifi_ap_mac_dot3, self.wifi_ap_mac_dot4, self.wifi_ap_mac_dot5
        ]
        self.ap_enc_group = [
            self.wifi_ap_password_label, self.wifi_ap_change_password,
            self.wifi_ap_password, self.wifi_ap_password_show
        ]

        self.mesh_router_enc_group = [
            self.wifi_mesh_router_password_label,
            self.wifi_mesh_router_change_password,
            self.wifi_mesh_router_password, self.wifi_mesh_router_password_show
        ]
        self.mesh_root_static_ip_group = [
            self.wifi_mesh_root_ip_label, self.wifi_mesh_root_sub_label,
            self.wifi_mesh_root_gw_label, self.wifi_mesh_root_ip1,
            self.wifi_mesh_root_ip2, self.wifi_mesh_root_ip3,
            self.wifi_mesh_root_ip4, self.wifi_mesh_root_sub1,
            self.wifi_mesh_root_sub2, self.wifi_mesh_root_sub3,
            self.wifi_mesh_root_sub4, self.wifi_mesh_root_gw1,
            self.wifi_mesh_root_gw2, self.wifi_mesh_root_gw3,
            self.wifi_mesh_root_gw4, self.wifi_mesh_dot1, self.wifi_mesh_dot2,
            self.wifi_mesh_dot3, self.wifi_mesh_dot4, self.wifi_mesh_dot5,
            self.wifi_mesh_dot6, self.wifi_mesh_dot7, self.wifi_mesh_dot8,
            self.wifi_mesh_dot9
        ]
        self.mesh_router_bssid_group = [
            self.wifi_mesh_router_bssid_label, self.wifi_mesh_router_bssid1,
            self.wifi_mesh_router_bssid2, self.wifi_mesh_router_bssid3,
            self.wifi_mesh_router_bssid4, self.wifi_mesh_router_bssid5,
            self.wifi_mesh_router_bssid6, self.wifi_mesh_colon1,
            self.wifi_mesh_colon2, self.wifi_mesh_colon3,
            self.wifi_mesh_colon4, self.wifi_mesh_colon5
        ]

        # Enable/disable web interface
        self.wifi_disable_web_interface.stateChanged.connect(
            self.wifi_disable_web_interface_state_changed)

        # Passwords
        self.wifi_secret_show_state_changed(Qt.Unchecked)
        self.wifi_client_show_state_changed(Qt.Unchecked)
        self.wifi_mesh_router_password_show_state_change(Qt.Unchecked)
        self.wifi_ap_password_show_state_changed(Qt.Unchecked)
        self.wifi_show_characters.stateChanged.connect(
            self.wifi_secret_show_state_changed)
        self.wifi_client_password_show.stateChanged.connect(
            self.wifi_client_show_state_changed)
        self.wifi_ap_password_show.stateChanged.connect(
            self.wifi_ap_password_show_state_changed)
        self.wifi_mesh_router_password_show.stateChanged.connect(
            self.wifi_mesh_router_password_show_state_change)
        self.wifi_client_change_password.stateChanged.connect(
            self.wifi_client_change_password_changed)
        self.wifi_ap_change_password.stateChanged.connect(
            self.wifi_ap_change_password_changed)
        self.wifi_mesh_router_change_password.stateChanged.connect(
            self.wifi_mesh_router_change_password_changed)

        # Use passwords
        self.wifi_client_encryption_changed(1)
        self.wifi_ap_encryption_changed(3)
        self.wifi_mesh_router_encryption_changed(1)

        self.wifi_use_auth_state_changed(Qt.Unchecked)
        self.wifi_mesh_router_encryption_changed(0)
        self.wifi_client_encryption.currentIndexChanged.connect(
            self.wifi_client_encryption_changed)
        self.wifi_ap_encryption.currentIndexChanged.connect(
            self.wifi_ap_encryption_changed)
        self.wifi_use_auth.stateChanged.connect(
            self.wifi_use_auth_state_changed)
        self.wifi_mesh_router_encryption.currentIndexChanged.connect(
            self.wifi_mesh_router_encryption_changed)

        # MACs
        self.wifi_client_use_bssid_state_changed(Qt.Unchecked)
        self.wifi_client_use_mac_state_changed(Qt.Unchecked)
        self.wifi_ap_use_mac_state_changed(Qt.Unchecked)
        self.wifi_client_use_bssid.stateChanged.connect(
            self.wifi_client_use_bssid_state_changed)
        self.wifi_client_use_mac.stateChanged.connect(
            self.wifi_client_use_mac_state_changed)
        self.wifi_ap_use_mac.stateChanged.connect(
            self.wifi_ap_use_mac_state_changed)
        self.wifi_mesh_use_router_bssid_state_changed(Qt.Unchecked)
        self.wifi_mesh_router_use_bssid.stateChanged.connect(
            self.wifi_mesh_use_router_bssid_state_changed)

        # IP Configuration
        self.wifi_client_ip_configuration_changed(0)
        self.wifi_ap_ip_configuration_changed(0)
        self.wifi_mesh_root_ip_configuration_changed(0)
        self.wifi_client_ip_configuration.currentIndexChanged.connect(
            self.wifi_client_ip_configuration_changed)
        self.wifi_ap_ip_configuration.currentIndexChanged.connect(
            self.wifi_ap_ip_configuration_changed)
        self.wifi_mesh_root_ip_configuration.currentIndexChanged.connect(
            self.wifi_mesh_root_ip_configuration_changed)

        # Mode
        self.wifi_mode_changed(0)
        self.wifi_mode.currentIndexChanged.connect(self.wifi_mode_changed)

        # Save/Status
        self.wifi_save.clicked.connect(self.save_clicked)
        self.wifi_show_status.clicked.connect(self.show_status_clicked)

        self.client_enable = False
        self.ap_enable = False
        self.mesh_enable = False

        # Check if the master brick and WIFI extension 2 firmware versions
        # support mesh networking feature
        if self.wifi2_firmware_version >= (
                2, 1, 0) and self.parent.firmware_version >= (2, 4, 2):
            self.wifi_mode.addItem('Mesh')
            self.label_mesh_hint.hide()
Esempio n. 34
0
def main():
    try:
        locale.setlocale(locale.LC_ALL, '')
    except locale.Error:
        pass # ignore this as it might fail on macOS, we'll fallback to UTF-8 in that case

    if config.get_use_fusion_gui_style():
        sys.argv += ['-style', 'fusion']

    if '--error-report' in sys.argv:
        sys.exit(error_report_main())

    # Catch all uncaught exceptions and show an error message for them.
    # PyQt5 does not silence exceptions in slots (as did PyQt4), so there
    # can be slots which try to (for example) send requests but don't wrap
    # them in an async call with error handling.
    argv = deepcopy(sys.argv) # Deep copy because QApplication (i.e. BrickViewer) constructor parses away Qt args and we want to know the style.
    if '--no-error-reporter' not in sys.argv:
        ExceptionReporter(argv)

    # Exceptions that happen before the event loop runs (f.e. syntax errors) kill the brickv so fast, that the error reporter thread
    # (which is daemonized) can not report the error before it is killed. Report them manually.
    try:
        # importing the MainWindow after creating the QApplication instance triggers this warning
        #
        #  Qt WebEngine seems to be initialized from a plugin. Please set Qt::AA_ShareOpenGLContexts
        #  using QCoreApplication::setAttribute before constructing QGuiApplication.
        #
        # do what the warnings says to avoid it
        QApplication.setAttribute(Qt.AA_ShareOpenGLContexts)

        brick_viewer = BrickViewer(sys.argv)

        if sys.platform == 'darwin':
            # workaround macOS QTBUG-61562
            from brickv.mac_pasteboard_mime_fixed import MacPasteboardMimeFixed
            mac_pasteboard_mime_fixed = MacPasteboardMimeFixed()

        splash = QSplashScreen(load_pixmap('splash.png'), Qt.WindowStaysOnTopHint)
        splash.show()

        message = 'Starting Brick Viewer ' + config.BRICKV_FULL_VERSION

        splash.showMessage(message, Qt.AlignHCenter | Qt.AlignBottom, Qt.white)

        brick_viewer.processEvents()

        from brickv.mainwindow import MainWindow

        main_window = MainWindow()
        main_window.show()

        splash.finish(main_window)
    except:
        if '--no-error-reporter' in sys.argv:
            raise

        etype, value, tb = sys.exc_info()
        error = "".join(traceback.format_exception(etype, value, tb))
        error = "The following error is fatal. Exiting now.\n\n" + error

        traceback.print_exception(etype, value, tb)

        try:
            splash.close()
        except:
            pass

        # Either sys.executable is /path/to/python, then run calls /path/to/python /path/to/main.py --error-report,
        # or sys.executable is brickv[.exe], then the --error-report flag ensures, that the path to main.py is ignored.
        subprocess.run([sys.executable, os.path.realpath(__file__), "--error-report"] + argv, input=error, universal_newlines=True)
        sys.exit(1)

    sys.exit(brick_viewer.exec_())
Esempio n. 35
0
    def __init__(self, parent):
        QDialog.__init__(self, parent)

        self._gui_logger = GUILogger("GUILogger", logging.INFO)
        self._gui_job = None
        EventLogger.add_logger(self._gui_logger)

        # FIXME better way to find interval and uids in tree_widget?!
        self.__tree_interval_tooltip = "Update interval in seconds"
        self.__tree_uid_tooltip = "UID cannot be empty"
        self.data_logger_thread = None
        self.tab_debug_warning = False

        self.device_dialog = None

        self.host_infos = None
        self.last_host = None
        self.host_index_changing = None

        self.setupUi(self)

        self.model_data = QStandardItemModel(self)
        self.model_data.setHorizontalHeaderLabels(
            ['Time', 'Name', 'UID', 'Var', 'Raw', 'Unit'])
        self.table_data.setModel(self.model_data)
        self.table_data.setColumnWidth(0, 160)
        self.table_data.setColumnWidth(1, 170)
        self.table_data.setColumnWidth(2, 50)
        self.table_data.setColumnWidth(3, 110)
        self.table_data.setColumnWidth(4, 70)
        self.table_data.setColumnWidth(5, 100)

        self.model_devices = QStandardItemModel(self)
        self.model_devices.setHorizontalHeaderLabels(['Device', 'Value'])
        self.tree_devices.setModel(self.model_devices)
        self.tree_devices.setColumnWidth(0, 300)

        self.widget_initialization()

        self.btn_start_logging.setIcon(
            QIcon(load_pixmap('data_logger/start-icon.png')))

        timestamp = int(time.time())
        self.edit_csv_file_name.setText(
            os.path.join(get_home_path(),
                         'logger_data_{0}.csv'.format(timestamp)))
        self.edit_log_file_name.setText(
            os.path.join(get_home_path(),
                         'logger_debug_{0}.log'.format(timestamp)))

        self.combo_data_time_format.addItem(
            utils.timestamp_to_de(timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de')
        self.combo_data_time_format.addItem(
            utils.timestamp_to_us(timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us')
        self.combo_data_time_format.addItem(
            utils.timestamp_to_iso(timestamp) + ' (ISO 8601)', 'iso')
        self.combo_data_time_format.addItem(
            utils.timestamp_to_unix(timestamp) + ' (Unix)', 'unix')

        self.combo_debug_time_format.addItem(
            utils.timestamp_to_de(timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de')
        self.combo_debug_time_format.addItem(
            utils.timestamp_to_us(timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us')
        self.combo_debug_time_format.addItem(
            utils.timestamp_to_iso(timestamp) + ' (ISO 8601)', 'iso')
        self.combo_debug_time_format.addItem(
            utils.timestamp_to_unix(timestamp) + ' (Unix)', 'unix')

        self.combo_log_level.addItem('Debug', 'debug')
        self.combo_log_level.addItem('Info', 'info')
        self.combo_log_level.addItem('Warning', 'warning')
        self.combo_log_level.addItem('Error', 'error')
        self.combo_log_level.addItem('Critical', 'critical')
        self.combo_log_level.setCurrentIndex(0)  # debug

        self.combo_debug_level.addItem('Debug', logging.DEBUG)
        self.combo_debug_level.addItem('Info', logging.INFO)
        self.combo_debug_level.addItem('Warning', logging.WARNING)
        self.combo_debug_level.addItem('Error', logging.ERROR)
        self.combo_debug_level.addItem('Critical', logging.CRITICAL)
        self.combo_debug_level.setCurrentIndex(1)  # info

        self.update_ui_state()
Esempio n. 36
0
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)

        self.setupUi(self)

        # Setting the minimum width of the setup tab ensures, that other tabs can grow
        # the window if more space is required, but we have a sane default for status
        # messages. Setting the minimum width of the main window itself would enfoce
        # it, even if children (i.e. tabs) need more space.
        self.tab_setup.setMinimumWidth(550)

        signal.signal(signal.SIGINT, self.exit_brickv)
        signal.signal(signal.SIGTERM, self.exit_brickv)

        self.async_thread = async_start_thread(self)

        title = 'Brick Viewer ' + config.BRICKV_VERSION

        if config.INTERNAL != None:
            title += '~{}'.format(config.INTERNAL)

        self.setWindowTitle(title)

        self.tree_view_model_labels = ['Name', 'UID', 'Position', 'FW Version']
        self.tree_view_model = QStandardItemModel(self)
        self.tree_view_proxy_model = DevicesProxyModel(self)
        self.tree_view_proxy_model.setSourceModel(self.tree_view_model)
        self.tree_view.setModel(self.tree_view_proxy_model)
        self.tree_view.activated.connect(self.item_activated)
        self.set_tree_view_defaults()

        self.tab_widget.removeTab(1) # remove dummy tab
        self.tab_widget.setUsesScrollButtons(True) # force scroll buttons

        self.update_tab_button = IconButton(QIcon(load_pixmap('update-icon-normal.png')),
                                            QIcon(load_pixmap('update-icon-hover.png')),
                                            parent=self.tab_setup)
        self.update_tab_button.setToolTip('Updates available')
        self.update_tab_button.clicked.connect(self.flashing_clicked)
        self.update_tab_button.hide()

        self.name = '<unknown>'
        self.uid = '<unknown>'
        self.version = (0, 0, 0)

        self.disconnect_times = []

        self.qtcb_enumerate.connect(self.cb_enumerate)
        self.qtcb_connected.connect(self.cb_connected)
        self.qtcb_disconnected.connect(self.cb_disconnected)

        self.ipcon = IPConnection()
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.qtcb_enumerate.emit)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.qtcb_connected.emit)
        self.ipcon.register_callback(IPConnection.CALLBACK_DISCONNECTED,
                                     self.qtcb_disconnected.emit)

        self.current_device_info = None
        self.flashing_window = None
        self.advanced_window = None
        self.data_logger_window = None
        self.delayed_refresh_updates_timer = QTimer(self)
        self.delayed_refresh_updates_timer.timeout.connect(self.delayed_refresh_updates)
        self.delayed_refresh_updates_timer.setInterval(100)
        self.reset_view()
        self.button_advanced.setDisabled(True)

        self.fw_version_fetcher = LatestFWVersionFetcher()
        self.fw_version_fetcher.fw_versions_avail.connect(self.fw_versions_fetched)
        self.fw_version_fetcher_thread = QThread()
        self.fw_version_fetcher_thread.setObjectName("fw_version_fetcher_thread")

        if config.get_auto_search_for_updates():
            self.enable_auto_search_for_updates()
        else:
            self.disable_auto_search_for_updates()

        self.tab_widget.currentChanged.connect(self.tab_changed)
        self.tab_widget.setMovable(True)
        self.tab_widget.tabBar().installEventFilter(self)

        self.button_connect.clicked.connect(self.connect_clicked)
        self.button_flashing.clicked.connect(self.flashing_clicked)
        self.button_advanced.clicked.connect(self.advanced_clicked)
        self.button_data_logger.clicked.connect(self.data_logger_clicked)
        self.plugin_manager = PluginManager()

        # host info
        self.host_infos = config.get_host_infos(config.HOST_INFO_COUNT)
        self.host_index_changing = True

        for host_info in self.host_infos:
            self.combo_host.addItem(host_info.host)

        self.last_host = None
        self.combo_host.installEventFilter(self)
        self.combo_host.currentIndexChanged.connect(self.host_index_changed)

        self.spinbox_port.setValue(self.host_infos[0].port)
        self.spinbox_port.valueChanged.connect(self.port_changed)
        self.spinbox_port.installEventFilter(self)

        self.checkbox_authentication.stateChanged.connect(self.authentication_state_changed)

        self.label_secret.hide()
        self.edit_secret.hide()
        self.edit_secret.setEchoMode(QLineEdit.Password)
        self.edit_secret.textEdited.connect(self.secret_changed)
        self.edit_secret.installEventFilter(self)

        self.checkbox_secret_show.hide()
        self.checkbox_secret_show.stateChanged.connect(self.secret_show_state_changed)

        self.checkbox_remember_secret.hide()
        self.checkbox_remember_secret.stateChanged.connect(self.remember_secret_state_changed)

        self.checkbox_authentication.setChecked(self.host_infos[0].use_authentication)
        self.edit_secret.setText(self.host_infos[0].secret)
        self.checkbox_remember_secret.setChecked(self.host_infos[0].remember_secret)

        self.host_index_changing = False

        # auto-reconnect
        self.label_auto_reconnects.hide()
        self.auto_reconnects = 0

        # RED Session losts
        self.label_red_session_losts.hide()
        self.red_session_losts = 0

        # fusion style
        self.check_fusion_gui_style.setChecked(config.get_use_fusion_gui_style())
        self.check_fusion_gui_style.stateChanged.connect(self.gui_style_changed)

        self.checkbox_auto_search_for_updates.setChecked(config.get_auto_search_for_updates())
        self.checkbox_auto_search_for_updates.stateChanged.connect(self.auto_search_for_updates_changed)

        self.button_update_pixmap_normal = load_pixmap('update-icon-normal.png')
        self.button_update_pixmap_hover = load_pixmap('update-icon-hover.png')

        self.last_status_message_id = ''

        infos.get_infos_changed_signal().connect(self.update_red_brick_version)
Esempio n. 37
0
    def __init__(self, *args, **kwargs):
        QApplication.__init__(self, *args, **kwargs)

        self.object_creator_signal.connect(self.object_creator_slot)
        self.setWindowIcon(QIcon(load_pixmap('brickv-icon.png')))
Esempio n. 38
0
    def __init__(self, *args, **kwargs):
        QApplication.__init__(self, *args, **kwargs)

        self.object_creator_signal.connect(self.object_creator_slot)
        self.setWindowIcon(QIcon(load_pixmap('brickv-icon.png')))
Esempio n. 39
0
def main():
    try:
        locale.setlocale(locale.LC_ALL, '')
    except locale.Error:
        pass # ignore this as it might fail on macOS, we'll fallback to UTF-8 in that case

    if config.get_use_fusion_gui_style():
        sys.argv += ['-style', 'fusion']

    if '--error-report' in sys.argv:
        sys.exit(error_report_main())

    # Catch all uncaught exceptions and show an error message for them.
    # PyQt5 does not silence exceptions in slots (as did PyQt4), so there
    # can be slots which try to (for example) send requests but don't wrap
    # them in an async call with error handling.
    argv = deepcopy(sys.argv) # Deep copy because QApplication (i.e. BrickViewer) constructor parses away Qt args and we want to know the style.
    if '--no-error-reporter' not in sys.argv:
        ExceptionReporter(argv)

    # Exceptions that happen before the event loop runs (f.e. syntax errors) kill the brickv so fast, that the error reporter thread
    # (which is daemonized) can not report the error before it is killed. Report them manually.
    try:
        # importing the MainWindow after creating the QApplication instance triggers this warning
        #
        #  Qt WebEngine seems to be initialized from a plugin. Please set Qt::AA_ShareOpenGLContexts
        #  using QCoreApplication::setAttribute before constructing QGuiApplication.
        #
        # do what the warnings says to avoid it
        QApplication.setAttribute(Qt.AA_ShareOpenGLContexts)

        brick_viewer = BrickViewer(sys.argv)

        if sys.platform == 'darwin':
            # workaround macOS QTBUG-61562
            from brickv.mac_pasteboard_mime_fixed import MacPasteboardMimeFixed
            mac_pasteboard_mime_fixed = MacPasteboardMimeFixed()

        splash = QSplashScreen(load_pixmap('splash.png'), Qt.WindowStaysOnTopHint)
        splash.show()

        message = 'Starting Brick Viewer ' + config.BRICKV_VERSION

        if config.INTERNAL != None:
            message += '~{}'.format(config.INTERNAL)

        splash.showMessage(message, Qt.AlignHCenter | Qt.AlignBottom, Qt.white)

        brick_viewer.processEvents()

        from brickv.mainwindow import MainWindow

        main_window = MainWindow()
        main_window.show()

        splash.finish(main_window)
    except:
        if '--no-error-reporter' in sys.argv:
            raise

        etype, value, tb = sys.exc_info()
        error = "".join(traceback.format_exception(etype, value, tb))
        error = "The following error is fatal. Exiting now.\n\n" + error

        traceback.print_exception(etype, value, tb)

        try:
            splash.close()
        except:
            pass

        # Either sys.executable is /path/to/python, then run calls /path/to/python /path/to/main.py --error-report,
        # or sys.executable is brickv[.exe], then the --error-report flag ensures, that the path to main.py is ignored.
        subprocess.run([sys.executable, os.path.realpath(__file__), "--error-report"] + argv, input=error, universal_newlines=True)
        sys.exit(1)

    sys.exit(brick_viewer.exec_())
Esempio n. 40
0
def error_report_main():
    error_message = sys.stdin.read()

    if len(error_message) == 0:
        # FIXME: for some unknown reason it can happen that stdin is empty
        label_suffix = ''
        error_message = 'An unknown error occurred!'
    elif '!!!' in error_message:
        label_suffix, error_message = error_message.split('!!!')

    formatted_error_message = "<pre>{}</pre>".format(
        html.escape(error_message).replace("\n", "<br>"))

    app = QApplication(sys.argv)

    if sys.platform == 'darwin':
        # workaround macOS QTBUG-61562
        from brickv.mac_pasteboard_mime_fixed import MacPasteboardMimeFixed
        mac_pasteboard_mime_fixed = MacPasteboardMimeFixed()

    window = ErrorReporter()
    window.setupUi(window)
    window.setWindowTitle('Error - Brick Viewer ' + config.BRICKV_VERSION)
    window.setWindowIcon(QIcon(load_pixmap('brickv-icon.png')))

    mail_url = 'mailto:[email protected]?subject=Brickv Error Report&body=PLEASE ALSO DESCRIBE WHAT YOU TRIED TO DO AT THE TIME THE ERROR OCCURRED.{}'.format(
        urllib.parse.quote("\n\n" + error_message))
    title = "<b>Please report this error to <a href='{}'>[email protected]</a>.<b>".format(
        mail_url)
    description = "You can either save the report to a text file by clicking the <b>Save</b> button below and email the file to us or you can click the <b>Email</b> button below to prepopulate an email in your email program.<br><br>" + \
                  "Please also describe what you tried to do at the time the error occurred.<br/><br/>" + \
                  "If you know what caused the error and could work around it, please tell us anyway. This allows us to improve the robustness of Brick Viewer.{}".format(label_suffix)

    window.label_title.setText(title)
    window.label_description.setText(description)

    def save():
        date = datetime.datetime.now().replace(
            microsecond=0).isoformat().replace('T', '_').replace(':', '-')
        filename = get_save_file_name(
            window, 'Save Report To File',
            os.path.join(get_home_path(),
                         'brickv_error_report_{}.txt'.format(date)))

        if len(filename) == 0:
            return

        try:
            with open(filename, 'w') as f:
                f.write(error_message)
        except Exception as e:
            QMessageBox.critical(window, 'Save Report To File',
                                 'Could not save report to file:\n\n' + str(e),
                                 QMessageBox.Ok)

    window.button_save.clicked.connect(save)
    window.button_email.clicked.connect(
        lambda: QDesktopServices.openUrl(QUrl(mail_url)))
    window.text_error.setHtml(formatted_error_message)
    window.check_show_again.setChecked(True)
    window.button_close.clicked.connect(
        lambda event: app.exit(int(window.check_show_again.isChecked())))

    def close_and_exit():
        app.exit(int(window.check_show_again.isChecked()) + 2)

    window.button_close_and_exit.clicked.connect(
        lambda event: close_and_exit())

    window.setMinimumSize(640, 400)
    window.resize(800, 800)
    window.show()

    return app.exec_()