def __init__(self, parent): QWidget.__init__(self, parent) self.status_text = QLabel(self) self.spinner = QWaitingSpinner(self, centerOnParent=False) self.spinner.setNumberOfLines(12) self.spinner.setInnerRadius(2) layout = QHBoxLayout() layout.addWidget(self.spinner) layout.addWidget(self.status_text) self.setLayout(layout)
class FileProgressBar(QWidget): """Simple progress spinner with a label""" def __init__(self, parent): QWidget.__init__(self, parent) self.status_text = QLabel(self) self.spinner = QWaitingSpinner(self, centerOnParent=False) self.spinner.setNumberOfLines(12) self.spinner.setInnerRadius(2) layout = QHBoxLayout() layout.addWidget(self.spinner) layout.addWidget(self.status_text) self.setLayout(layout) @Slot(str) def set_label_path(self, path, folder=False): text = truncate_path(path) if not folder: status_str = _(u' Scanning: {0}').format(text) else: status_str = _(u' Searching for files in folder: {0}').format(text) self.status_text.setText(status_str) def reset(self): self.status_text.setText(_(" Searching for files...")) def showEvent(self, event): """Override show event to start waiting spinner.""" QWidget.showEvent(self, event) self.spinner.start() def hideEvent(self, event): """Override hide event to stop waiting spinner.""" QWidget.hideEvent(self, event) self.spinner.stop()
def __init__(self, parent, menu_actions=None): """Initialiaze ReportsWidget.""" QWidget.__init__(self, parent) self.renderviews = {} self.filenames = [] self.menu_actions = menu_actions self.setWindowTitle("Reports") self.tabs = BaseTabs(self, actions=self.menu_actions, menu_use_tooltips=False) self.tabs.setMovable(True) self.tabs.setTabsClosable(True) self.tabs.tabCloseRequested.connect(self.close_tab) self.tabs.tabBar().tabMoved.connect(self.move_tab) # Progress bar self.progress_bar = QWidget(self) self.status_text = QLabel(self.progress_bar) self.spinner = QWaitingSpinner(self.progress_bar, centerOnParent=False) self.spinner.setNumberOfLines(12) self.spinner.setInnerRadius(2) progress_layout = QHBoxLayout() progress_layout.addWidget(self.spinner) progress_layout.addWidget(self.status_text) self.progress_bar.setLayout(progress_layout) self.progress_bar.hide() # Menu as corner widget if self.menu_actions: options_button = create_toolbutton(self, text='Options', icon=ima.icon('tooloptions')) options_button.setPopupMode(QToolButton.InstantPopup) menu = QMenu(self) add_actions(menu, self.menu_actions) options_button.setMenu(menu) self.tabs.setCornerWidget(options_button) layout = QVBoxLayout() layout.addWidget(self.tabs) layout.addWidget(self.progress_bar) self.setLayout(layout)
class FileProgressBar(QWidget): """Simple progress spinner with a label""" MAX_LABEL_LENGTH = 60 def __init__(self, parent): QWidget.__init__(self, parent) self.status_text = QLabel(self) self.spinner = QWaitingSpinner(self, centerOnParent=False) self.spinner.setNumberOfLines(12) self.spinner.setInnerRadius(2) self.spinner.start() layout = QHBoxLayout() layout.addWidget(self.spinner) layout.addWidget(self.status_text) self.setLayout(layout) def __truncate(self, text): ellipsis = '...' part_len = (self.MAX_LABEL_LENGTH - len(ellipsis)) / 2.0 left_text = text[:int(math.ceil(part_len))] right_text = text[-int(math.floor(part_len)):] return left_text + ellipsis + right_text @Slot(str) def set_label_path(self, path, folder=False): text = self.__truncate(path) if not folder: status_str = _(u' Scanning: {0}').format(text) else: status_str = _(u' Searching for files in folder: {0}').format(text) self.status_text.setText(status_str) def reset(self): self.status_text.setText(_(" Searching for files..."))
def create_waitspinner(size=32, n=11, parent=None): """ Create a wait spinner with the specified size built with n circling dots. """ dot_padding = 1 # To calculate the size of the dots, we need to solve the following # system of two equations in two variables. # (1) middle_circumference = pi * (size - dot_size) # (2) middle_circumference = n * (dot_size + dot_padding) dot_size = (pi * size - n * dot_padding) / (n + pi) inner_radius = (size - 2 * dot_size) / 2 spinner = QWaitingSpinner(parent, centerOnParent=False) spinner.setTrailSizeDecreasing(True) spinner.setNumberOfLines(n) spinner.setLineLength(dot_size) spinner.setLineWidth(dot_size) spinner.setInnerRadius(inner_radius) spinner.setColor(Qt.white if is_dark_interface() else Qt.black) return spinner
class ReportsWidget(QWidget): """Reports widget.""" def __init__(self, parent, menu_actions=None): """Initialiaze ReportsWidget.""" QWidget.__init__(self, parent) self.renderviews = {} self.filenames = [] self.menu_actions = menu_actions self.setWindowTitle("Reports") self.tabs = BaseTabs(self, actions=self.menu_actions, menu_use_tooltips=False) self.tabs.setMovable(True) self.tabs.setTabsClosable(True) self.tabs.tabCloseRequested.connect(self.close_tab) self.tabs.tabBar().tabMoved.connect(self.move_tab) # Progress bar self.progress_bar = QWidget(self) self.status_text = QLabel(self.progress_bar) self.spinner = QWaitingSpinner(self.progress_bar, centerOnParent=False) self.spinner.setNumberOfLines(12) self.spinner.setInnerRadius(2) progress_layout = QHBoxLayout() progress_layout.addWidget(self.spinner) progress_layout.addWidget(self.status_text) self.progress_bar.setLayout(progress_layout) self.progress_bar.hide() # Menu as corner widget if self.menu_actions: options_button = create_toolbutton(self, text='Options', icon=ima.icon('tooloptions')) options_button.setPopupMode(QToolButton.InstantPopup) menu = QMenu(self) add_actions(menu, self.menu_actions) options_button.setMenu(menu) self.tabs.setCornerWidget(options_button) layout = QVBoxLayout() layout.addWidget(self.tabs) layout.addWidget(self.progress_bar) self.setLayout(layout) def set_html(self, html_text, fname, base_url=None): """Set html text.""" name = self.disambiguate_fname(fname) renderview = self.renderviews.get(fname) if WELCOME_PATH in self.renderviews and renderview is None: # Overwrite the welcome tab renderview = self.renderviews.pop(WELCOME_PATH) self.renderviews[fname] = renderview self.tabs.setTabText(0, name) self.filenames[0] = fname if renderview is None: # create a new renderview renderview = RenderView(self) self.renderviews[fname] = renderview self.tabs.addTab(renderview, name) self.filenames.append(fname) if base_url is not None: renderview.setHtml(html_text, base_url) else: renderview.setHtml(html_text) self.tabs.setCurrentWidget(renderview) self.tabs.currentChanged.emit(self.tabs.currentIndex()) def set_html_from_file(self, output_fname, input_fname=None): """Set html text from a file.""" if input_fname is None: input_fname = output_fname html = "" with codecs.open(output_fname, encoding="utf-8") as file: html = file.read() base_url = QUrl() self.set_html(html, input_fname, base_url) @Slot(str) def render_started(self, fname): """Show progress bar and starts spinner. Args: fname (str): Name of the file being rendered """ self.spinner.start() name = self.disambiguate_fname(fname) text = "Rendering: {}".format(name) self.status_text.setText(text) self.progress_bar.show() self.set_html('', fname) @Slot(str) def update_progress(self, text): """Update progress bar status text. Args: text (str): text to be displayed. """ if len(text) > 50: text = "{}...".format(text[:47]) self.status_text.setText(text) @Slot(bool, object, object) def render_finished(self, ok, fname, error): """Handle render finish signal. If error, displays it, otherwise hide progress bar. Args: ok (bool): True f the rener was succesful fname (str): Name of the file being rendered error (str): Error string to display """ self.spinner.stop() if error is not None: self.status_text.setText(error) self.close_tab(self.filenames.index(fname)) else: self.progress_bar.hide() def close_tab(self, index): """Close tab, and remove its widget form renderviews.""" fname = self.filenames.pop(index) self.renderviews.pop(fname) self.tabs.removeTab(index) def move_tab(self, start, end): """Move self.filenames list to be synchronized when tabs are moved.""" if start < 0 or end < 0: return steps = abs(end - start) direction = (end - start) // steps # +1 for right, -1 for left fnames = self.filenames for i in range(start, end, direction): fnames[i], fnames[i + direction] = fnames[i + direction], fnames[i] def disambiguate_fname(self, fname): """Generate a file name without ambiguation.""" files_path_list = [filename for filename in self.filenames if filename] return disambiguate_fname(files_path_list, fname) def get_focus_report(self): """Return current report.""" try: return self.filenames[self.tabs.currentIndex()] except IndexError: return None