Exemple #1
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)
Exemple #2
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 = ''
Exemple #3
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_())
Exemple #4
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_())
    def cb_settings_fs_expand_check(self, result):
        if not self.is_tab_on_focus:
            return

        if not report_script_result(result, 'Settings | File System',
                                    'Error getting partition information'):
            self.label_fs_expand_info.hide()
            self.line.hide()
            self.label_pbar_fs_capacity_utilization.hide()
            self.pbar_fs_capacity_utilization.setMinimum(0)
            self.pbar_fs_capacity_utilization.setMaximum(100)
            self.pbar_fs_capacity_utilization.setValue(0)
            self.pbar_fs_capacity_utilization.setFormat('')
            self.pbar_fs_capacity_utilization.setEnabled(False)
            self.pbutton_fs_expand.setEnabled(False)
            return

        try:
            size_dict = json.loads(result.stdout)
            p1_start = float(size_dict['p1_start'])
            p1_size = float(size_dict['p1_size'])
            card_size = float(size_dict['card_size'])
            ext3_size = float(size_dict['ext3_size'])
        except:
            p1_start = 0
            p1_size = 100
            card_size = 100
            ext3_size = 100

        avialable_size = card_size - p1_start
        used_size = min(p1_size, ext3_size)

        percentage_utilization_v = min(
            int(math.ceil((used_size / avialable_size) * 100.0)), 100)

        # due to common file system overhead 100% will normally never be
        # reached just fake 100% in this case to avoid user confusion
        if percentage_utilization_v >= 95:
            percentage_utilization_v = 100

        percentage_utilization = str(percentage_utilization_v)

        self.pbar_fs_capacity_utilization.setEnabled(True)

        self.pbar_fs_capacity_utilization.setMinimum(0)
        self.pbar_fs_capacity_utilization.setMaximum(100)

        self.pbar_fs_capacity_utilization.setValue(percentage_utilization_v)

        if percentage_utilization_v == 100:
            self.pbutton_fs_expand.setEnabled(False)
            self.label_fs_expand_info.hide()
            self.line.hide()
        else:
            self.pbutton_fs_expand.setEnabled(True)
            self.label_fs_expand_info.show()
            self.line.show()

        pbar_fs_capacity_utilization_fmt = "Using {0}% of total capacity".format(
            percentage_utilization)

        if sys.platform == 'darwin' and not get_use_fusion_gui_style():
            self.label_pbar_fs_capacity_utilization.show()
            self.label_pbar_fs_capacity_utilization.setText(
                pbar_fs_capacity_utilization_fmt)
        else:
            self.pbar_fs_capacity_utilization.setFormat(
                pbar_fs_capacity_utilization_fmt)
Exemple #6
0
    def cb_overview(self, result):
        # check if the tab is still on view or not
        if not self.is_tab_on_focus:
            self.refresh_timer.stop()
            return

        self.refresh_counter = 0
        self.refresh_timer.start(REFRESH_TIMEOUT)

        okay, message = check_script_result(result, decode_stderr=True)

        if not okay:
            self.label_error.setText('<b>Error:</b> ' + html.escape(message))
            self.label_error.show()
            return

        self.label_error.hide()

        try:
            data = json.loads(zlib.decompress(memoryview(result.stdout)).decode('utf-8'))

            days, days_remainder = divmod(int(data['uptime']), 24 * 60 * 60)
            hours, hours_remainder = divmod(days_remainder, 60 * 60)
            minutes, _ = divmod(hours_remainder, 60)
            uptime = ''

            if days > 0:
                uptime += str(days)

                if days == 1:
                    uptime += ' day '
                else:
                    uptime += ' days '

            if hours > 0:
                uptime += str(hours)

                if hours == 1:
                    uptime += ' hour '
                else:
                    uptime += ' hours '

            uptime += str(minutes)

            if minutes == 1:
                uptime += ' minute'
            else:
                uptime += ' minutes'

            cpu_percent = data['cpu_used']
            cpu_percent_v = int(data['cpu_used'])

            memory_used = self.bytes2human(int(data['mem_used']))
            memory_total = self.bytes2human(int(data['mem_total']))
            memory_percent = "%.1f" % ((float(memory_used) / float(memory_total)) * 100)
            memory_percent_v = int(memory_percent.split('.')[0])

            storage_used = self.bytes2human(int(data['disk_used']))
            storage_total = self.bytes2human(int(data['disk_total']))
            storage_percent = "%.1f" % ((float(storage_used) / float(storage_total)) * 100)
            storage_percent_v = int(storage_percent.split('.')[0])

            nic_data_dict = data['ifaces']
            processes_data_list = data['processes']
        except:
            # some parsing error due to malfromed or incomplete output occured.
            # ignore it and wait for the next update
            return

        self.label_uptime_value.setText(uptime)

        pbar_cpu_fmt = "{0}%".format(cpu_percent)
        pbar_memory_fmt = "{0}% [{1} of {2} MiB]".format(memory_percent, memory_used, memory_total)
        pbar_storage_fmt = "{0}% [{1} of {2} GiB]".format(storage_percent, storage_used, storage_total)

        if sys.platform == 'darwin' and not get_use_fusion_gui_style():
            self.label_pbar_cpu.show()
            self.label_pbar_memory.show()
            self.label_pbar_storage.show()
            self.label_pbar_cpu.setText(pbar_cpu_fmt)
            self.label_pbar_memory.setText(pbar_memory_fmt)
            self.label_pbar_storage.setText(pbar_storage_fmt)
        else:
            self.pbar_cpu.setFormat(pbar_cpu_fmt)
            self.pbar_memory.setFormat(pbar_memory_fmt)
            self.pbar_storage.setFormat(pbar_storage_fmt)

        self.pbar_cpu.setValue(cpu_percent_v)
        self.pbar_memory.setValue(memory_percent_v)
        self.pbar_storage.setValue(storage_percent_v)

        self.nic_item_model.removeRows(0, self.nic_item_model.rowCount())

        def _get_nic_transfer_rate(bytes_now, bytes_previous, delta_time):
            return "%.1f" % float(((bytes_now - bytes_previous) / delta_time) / 1024.0)

        new_time = time.time()
        delta = new_time - self.nic_time
        self.nic_time = new_time

        for i, key in enumerate(nic_data_dict):
            if key not in self.nic_previous_bytes:
                self.nic_time = time.time()
                self.nic_item_model.setItem(i, 0, QStandardItem(key))
                self.nic_item_model.setItem(i, 1, QStandardItem("Collecting data..."))
                self.nic_item_model.setItem(i, 2, QStandardItem("Collecting data..."))
            else:
                download_rate = _get_nic_transfer_rate(nic_data_dict[key][1],
                                                       self.nic_previous_bytes[key]['received'],
                                                       delta)

                upload_rate = _get_nic_transfer_rate(nic_data_dict[key][0],
                                                     self.nic_previous_bytes[key]['sent'],
                                                     delta)

                self.nic_item_model.setItem(i, 0, QStandardItem(key))
                self.nic_item_model.setItem(i, 1, QStandardItem(download_rate + " KiB/s"))
                self.nic_item_model.setItem(i, 2, QStandardItem(upload_rate + " KiB/s"))

            self.nic_previous_bytes[key] = {'sent': nic_data_dict[key][0],
                                            'received': nic_data_dict[key][1]}

        self.nic_item_model.sort(self.tview_nic_previous_sort['column_index'],
                                 self.tview_nic_previous_sort['order'])

        self.process_item_model.removeRows(0, self.process_item_model.rowCount())

        if self.cbox_based_on.currentIndex() == 0:
            processes_data_list_sorted = sorted(processes_data_list,
                                                key=itemgetter('cpu'),
                                                reverse=True)
        elif self.cbox_based_on.currentIndex() == 1:
            processes_data_list_sorted = sorted(processes_data_list,
                                                key=itemgetter('mem'),
                                                reverse=True)

        processes_data_list_sorted = processes_data_list_sorted[:self.sbox_number_of_process.value()]

        for i, p in enumerate(processes_data_list_sorted):
            name = str(p['name'])
            cmdline = str(p['cmd'])

            if len(cmdline) == 0:
                cmdline = name

            item_name = QStandardItem(name)
            item_name.setToolTip(cmdline)
            self.process_item_model.setItem(i, 0, item_name)

            item_pid = QStandardItem(str(p['pid']))
            self.process_item_model.setItem(i, 1, item_pid)

            item_user = QStandardItem(str(p['user']))
            self.process_item_model.setItem(i, 2, item_user)

            cpu = p['cpu']
            item_cpu = QStandardItem(str(cpu / 10.0)+'%')
            item_cpu.setData(cpu)
            self.process_item_model.setItem(i, 3, item_cpu)

            mem = p['mem']
            item_mem = QStandardItem(str(mem / 10.0)+'%')
            item_mem.setData(mem)
            self.process_item_model.setItem(i, 4, item_mem)

        self.process_item_model.sort(self.tview_process_previous_sort['column_index'],
                                     self.tview_process_previous_sort['order'])
    def cb_settings_fs_expand_check(self, result):
        if not self.is_tab_on_focus:
            return

        if not report_script_result(result, 'Settings | File System',
                                    'Error getting partition information'):
            self.label_fs_expand_info.hide()
            self.line.hide()
            self.label_pbar_fs_capacity_utilization.hide()
            self.pbar_fs_capacity_utilization.setMinimum(0)
            self.pbar_fs_capacity_utilization.setMaximum(100)
            self.pbar_fs_capacity_utilization.setValue(0)
            self.pbar_fs_capacity_utilization.setFormat('')
            self.pbar_fs_capacity_utilization.setEnabled(False)
            self.pbutton_fs_expand.setEnabled(False)
            return

        try:
            size_dict = json.loads(result.stdout)
            p1_start = float(size_dict['p1_start'])
            p1_size = float(size_dict['p1_size'])
            card_size = float(size_dict['card_size'])
            ext3_size = float(size_dict['ext3_size'])
        except:
            p1_start = 0
            p1_size = 100
            card_size = 100
            ext3_size = 100

        avialable_size = card_size - p1_start
        used_size = min(p1_size, ext3_size)

        percentage_utilization_v = min(int(math.ceil((used_size / avialable_size) * 100.0)), 100)

        # due to common file system overhead 100% will normally never be
        # reached just fake 100% in this case to avoid user confusion
        if percentage_utilization_v >= 95:
            percentage_utilization_v = 100

        percentage_utilization = str(percentage_utilization_v)

        self.pbar_fs_capacity_utilization.setEnabled(True)

        self.pbar_fs_capacity_utilization.setMinimum(0)
        self.pbar_fs_capacity_utilization.setMaximum(100)

        self.pbar_fs_capacity_utilization.setValue(percentage_utilization_v)

        if percentage_utilization_v == 100:
            self.pbutton_fs_expand.setEnabled(False)
            self.label_fs_expand_info.hide()
            self.line.hide()
        else:
            self.pbutton_fs_expand.setEnabled(True)
            self.label_fs_expand_info.show()
            self.line.show()

        pbar_fs_capacity_utilization_fmt = "Using {0}% of total capacity".format(percentage_utilization)

        if sys.platform == 'darwin' and not get_use_fusion_gui_style():
            self.label_pbar_fs_capacity_utilization.show()
            self.label_pbar_fs_capacity_utilization.setText(pbar_fs_capacity_utilization_fmt)
        else:
            self.pbar_fs_capacity_utilization.setFormat(pbar_fs_capacity_utilization_fmt)