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)
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 = ''
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_())
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)
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)