class _StatusBar(QStatusBar): def __init__(self): super(_StatusBar, self).__init__() self._widgetStatus = QWidget() vbox = QVBoxLayout(self._widgetStatus) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) #Search Layout self._searchWidget = SearchWidget(self) vbox.addWidget(self._searchWidget) #Replace Layout self._replaceWidget = ReplaceWidget(self) vbox.addWidget(self._replaceWidget) self._replaceWidget.setVisible(False) #Code Locator self._codeLocator = locator.CodeLocatorWidget(self) vbox.addWidget(self._codeLocator) self._codeLocator.setVisible(False) #File system completer self._fileSystemOpener = FileSystemOpener() vbox.addWidget(self._fileSystemOpener) self._fileSystemOpener.setVisible(False) self.addWidget(self._widgetStatus) # Not Configurable Shortcuts shortEscStatus = QShortcut(QKeySequence(Qt.Key_Escape), self) self.connect(self, SIGNAL("messageChanged(QString)"), self.message_end) self.connect(self._replaceWidget._btnCloseReplace, SIGNAL("clicked()"), lambda: self._replaceWidget.setVisible(False)) self.connect(self._replaceWidget._btnReplace, SIGNAL("clicked()"), self.replace) self.connect(self._replaceWidget._btnReplaceAll, SIGNAL("clicked()"), self.replace_all) self.connect(self._replaceWidget._btnReplaceSelection, SIGNAL("clicked()"), self.replace_selected) self.connect(self._fileSystemOpener.btnClose, SIGNAL("clicked()"), self.hide_status) self.connect(self._fileSystemOpener, SIGNAL("requestHide()"), self.hide_status) self.connect(shortEscStatus, SIGNAL("activated()"), self.hide_status) IDE.register_service('status_bar', self) #Register signals connections connections = ( { 'target': 'main_container', 'signal_name': 'currentEditorChanged(QString)', 'slot': self.handle_tab_changed }, { 'target': 'main_container', 'signal_name': 'updateLocator(QString)', 'slot': self.explore_file_code }, { 'target': 'explorer_container', 'signal_name': 'updateLocator()', 'slot': self.explore_code }, ) IDE.register_signals('status_bar', connections) def install(self): self.hide() ide = IDE.get_service('ide') ide.setStatusBar(self) ui_tools.install_shortcuts(self, actions.ACTIONS_STATUS, ide) def find_next_result(self): self._searchWidget.find_next() def find_previous_result(self): self._searchWidget.find_previous() def handle_tab_changed(self, new_tab): """ Re-run search if tab changed, we use the find of search widget because we want the widget to be updated. """ editor = main_container.MainContainer().get_actual_editor() if self._searchWidget.isVisible(): self._searchWidget.find_matches(editor) if editor: self.disconnect(editor, SIGNAL("textChanged()"), self._notify_editor_changed) self.connect(editor, SIGNAL("textChanged()"), self._notify_editor_changed) def _notify_editor_changed(self): """ Lets search widget know that the editor contents changed and find needs to be re-run """ if self._searchWidget.isVisible(): editor = main_container.MainContainer().get_actual_editor() self._searchWidget.contents_changed(editor) def explore_code(self): self._codeLocator.explore_code() def explore_file_code(self, path): self._codeLocator.explore_file_code(path) def show(self): self.clearMessage() QStatusBar.show(self) editor = main_container.MainContainer().get_actual_editor() if editor and editor.textCursor().hasSelection(): text = editor.textCursor().selectedText() self._searchWidget._line.setText(text) self._searchWidget.find_matches(editor, True) if self._widgetStatus.isVisible(): self._searchWidget._line.setFocus() self._searchWidget._line.selectAll() def show_replace(self): self.clearMessage() self.show() editor = main_container.MainContainer().get_actual_editor() if editor: if editor.textCursor().hasSelection(): word = editor.textCursor().selectedText() self._searchWidget._line.setText(word) self._replaceWidget.setVisible(True) def show_with_word(self): self.clearMessage() editor = main_container.MainContainer().get_actual_editor() if editor: word = editor._text_under_cursor() self._searchWidget._line.setText(word) editor = main_container.MainContainer().get_actual_editor() editor.moveCursor(QTextCursor.WordLeft) self._searchWidget.find_matches(editor) self.show() def show_locator(self): if not self._codeLocator.isVisible(): self.clearMessage() self._searchWidget.setVisible(False) self.show() self._codeLocator.setVisible(True) self._codeLocator._completer.setFocus() self._codeLocator.show_suggestions() def show_file_opener(self): self.clearMessage() self._searchWidget.setVisible(False) self._fileSystemOpener.setVisible(True) self.show() self._fileSystemOpener.pathLine.setFocus() def hide_status(self): self._searchWidget._checkSensitive.setCheckState(Qt.Unchecked) self._searchWidget._checkWholeWord.setCheckState(Qt.Unchecked) self.hide() self._searchWidget.setVisible(True) self._replaceWidget.setVisible(False) self._codeLocator.setVisible(False) self._fileSystemOpener.setVisible(False) widget = main_container.MainContainer().get_actual_widget() if widget: widget.setFocus() def replace(self): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = 0 + s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.replace_match(self._searchWidget._line.text(), self._replaceWidget._lineReplace.text(), flags) if not editor.textCursor().hasSelection(): self.find() def replace_selected(self): self.replace_all(True) def replace_all(self, selected=False): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = 0 + s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.replace_match(self._searchWidget._line.text(), self._replaceWidget._lineReplace.text(), flags, True, selected) def find(self): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.find_match(self._searchWidget._line.text(), flags) def find_next(self): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = 0 + s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.find_match(self._searchWidget._line.text(), flags, True) def find_previous(self): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = 1 + s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.find_match(self._searchWidget._line.text(), flags, True) def showMessage(self, message, timeout): if settings.SHOW_STATUS_NOTIFICATIONS: self._widgetStatus.hide() self._replaceWidget.setVisible(False) self.show() QStatusBar.showMessage(self, message, timeout) def message_end(self, message): if message == '': self.hide() QStatusBar.clearMessage(self) self._widgetStatus.show()
class __StatusBar(QStatusBar): def __init__(self, parent=None): QStatusBar.__init__(self, parent) self._widgetStatus = QWidget() vbox = QVBoxLayout(self._widgetStatus) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) #Search Layout self._searchWidget = SearchWidget(self) vbox.addWidget(self._searchWidget) #Replace Layout self._replaceWidget = ReplaceWidget(self) vbox.addWidget(self._replaceWidget) self._replaceWidget.setVisible(False) #Code Locator self._codeLocator = locator.CodeLocatorWidget(self) vbox.addWidget(self._codeLocator) self._codeLocator.setVisible(False) #File system completer self._fileSystemOpener = FileSystemOpener() vbox.addWidget(self._fileSystemOpener) self._fileSystemOpener.setVisible(False) self.addWidget(self._widgetStatus) self._shortEsc = QShortcut(QKeySequence(Qt.Key_Escape), self) self.connect(self, SIGNAL("messageChanged(QString)"), self.message_end) self.connect(self._replaceWidget._btnCloseReplace, SIGNAL("clicked()"), lambda: self._replaceWidget.setVisible(False)) self.connect(self._replaceWidget._btnReplace, SIGNAL("clicked()"), self.replace) self.connect(self._replaceWidget._btnReplaceAll, SIGNAL("clicked()"), self.replace_all) self.connect(self._replaceWidget._btnReplaceSelection, SIGNAL("clicked()"), self.replace_selected) self.connect(self._shortEsc, SIGNAL("activated()"), self.hide_status) self.connect(self._fileSystemOpener.btnClose, SIGNAL("clicked()"), self.hide_status) self.connect(self._fileSystemOpener, SIGNAL("requestHide()"), self.hide_status) def handle_tab_changed(self, new_tab): """ Re-run search if tab changed, we use the find of search widget because we want the widget to be updated. """ if self._searchWidget.isVisible(): editor = main_container.MainContainer().get_actual_editor() self._searchWidget.find_matches(editor) def explore_code(self): self._codeLocator.explore_code() def explore_file_code(self, path): self._codeLocator.explore_file_code(path) def show(self): self.clearMessage() QStatusBar.show(self) if self._widgetStatus.isVisible(): self._searchWidget._line.setFocus() self._searchWidget._line.selectAll() def show_replace(self): self.clearMessage() self.show() editor = main_container.MainContainer().get_actual_editor() if editor: if editor.textCursor().hasSelection(): word = editor.textCursor().selectedText() self._searchWidget._line.setText(word) self._replaceWidget.setVisible(True) def show_with_word(self): self.clearMessage() editor = main_container.MainContainer().get_actual_editor() if editor: word = editor._text_under_cursor() self._searchWidget._line.setText(word) editor = main_container.MainContainer().get_actual_editor() editor.moveCursor(QTextCursor.WordLeft) self._searchWidget.find_matches(editor) self.show() def show_locator(self): if not self._codeLocator.isVisible(): self.clearMessage() self._searchWidget.setVisible(False) self.show() self._codeLocator.setVisible(True) self._codeLocator._completer.setFocus() self._codeLocator.show_suggestions() def show_file_opener(self): self.clearMessage() self._searchWidget.setVisible(False) self._fileSystemOpener.setVisible(True) self.show() self._fileSystemOpener.pathLine.setFocus() def hide_status(self): self._searchWidget._checkSensitive.setCheckState(Qt.Unchecked) self._searchWidget._checkWholeWord.setCheckState(Qt.Unchecked) self.hide() self._searchWidget.setVisible(True) self._replaceWidget.setVisible(False) self._codeLocator.setVisible(False) self._fileSystemOpener.setVisible(False) widget = main_container.MainContainer().get_actual_widget() if widget: widget.setFocus() def replace(self): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = 0 + s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.replace_match( unicode(self._searchWidget._line.text()), unicode(self._replaceWidget._lineReplace.text()), flags) if not editor.textCursor().hasSelection(): self.find() def replace_selected(self): self.replace_all(True) def replace_all(self, selected=False): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = 0 + s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.replace_match( unicode(self._searchWidget._line.text()), unicode(self._replaceWidget._lineReplace.text()), flags, True, selected) def find(self): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.find_match(unicode(self._searchWidget._line.text()), flags) def find_next(self): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = 0 + s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.find_match(unicode(self._searchWidget._line.text()), flags, True) def find_previous(self): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = 1 + s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.find_match(unicode(self._searchWidget._line.text()), flags, True) def showMessage(self, message, timeout): self._widgetStatus.hide() self._replaceWidget.setVisible(False) self.show() QStatusBar.showMessage(self, message, timeout) def message_end(self, message): if message == '': self.hide() QStatusBar.clearMessage(self) self._widgetStatus.show() widget = main_container.MainContainer().get_actual_widget() if widget: widget.setFocus()
class __StatusBar(QStatusBar): def __init__(self, parent=None): QStatusBar.__init__(self, parent) self._widgetStatus = QWidget() vbox = QVBoxLayout(self._widgetStatus) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) #Search Layout self._searchWidget = SearchWidget(self) vbox.addWidget(self._searchWidget) #Replace Layout self._replaceWidget = ReplaceWidget(self) vbox.addWidget(self._replaceWidget) self._replaceWidget.setVisible(False) #Code Locator self._codeLocator = locator.CodeLocatorWidget(self) vbox.addWidget(self._codeLocator) self._codeLocator.setVisible(False) #File system completer self._fileSystemOpener = FileSystemOpener() vbox.addWidget(self._fileSystemOpener) self._fileSystemOpener.setVisible(False) self.addWidget(self._widgetStatus) self.connect(self, SIGNAL("messageChanged(QString)"), self.message_end) self.connect(self._replaceWidget._btnCloseReplace, SIGNAL("clicked()"), lambda: self._replaceWidget.setVisible(False)) self.connect(self._replaceWidget._btnReplace, SIGNAL("clicked()"), self.replace) self.connect(self._replaceWidget._btnReplaceAll, SIGNAL("clicked()"), self.replace_all) self.connect(self._replaceWidget._btnReplaceSelection, SIGNAL("clicked()"), self.replace_selected) self.connect(self._fileSystemOpener.btnClose, SIGNAL("clicked()"), self.hide_status) self.connect(self._fileSystemOpener, SIGNAL("requestHide()"), self.hide_status) def handle_tab_changed(self, new_tab): """ Re-run search if tab changed, we use the find of search widget because we want the widget to be updated. """ if self._searchWidget.isVisible(): editor = main_container.MainContainer().get_actual_editor() self._searchWidget.find_matches(editor) def explore_code(self): self._codeLocator.explore_code() def explore_file_code(self, path): self._codeLocator.explore_file_code(path) def show(self): self.clearMessage() QStatusBar.show(self) editor = main_container.MainContainer().get_actual_editor() if editor and editor.textCursor().hasSelection(): text = editor.textCursor().selectedText() self._searchWidget._line.setText(text) if self._widgetStatus.isVisible(): self._searchWidget._line.setFocus() self._searchWidget._line.selectAll() def show_replace(self): self.clearMessage() self.show() editor = main_container.MainContainer().get_actual_editor() if editor: if editor.textCursor().hasSelection(): word = editor.textCursor().selectedText() self._searchWidget._line.setText(word) self._replaceWidget.setVisible(True) def show_with_word(self): self.clearMessage() editor = main_container.MainContainer().get_actual_editor() if editor: word = editor._text_under_cursor() self._searchWidget._line.setText(word) editor = main_container.MainContainer().get_actual_editor() editor.moveCursor(QTextCursor.WordLeft) self._searchWidget.find_matches(editor) self.show() def show_locator(self): if not self._codeLocator.isVisible(): self.clearMessage() self._searchWidget.setVisible(False) self.show() self._codeLocator.setVisible(True) self._codeLocator._completer.setFocus() self._codeLocator.show_suggestions() def show_file_opener(self): self.clearMessage() self._searchWidget.setVisible(False) self._fileSystemOpener.setVisible(True) self.show() self._fileSystemOpener.pathLine.setFocus() def hide_status(self): self._searchWidget._checkSensitive.setCheckState(Qt.Unchecked) self._searchWidget._checkWholeWord.setCheckState(Qt.Unchecked) self.hide() self._searchWidget.setVisible(True) self._replaceWidget.setVisible(False) self._codeLocator.setVisible(False) self._fileSystemOpener.setVisible(False) widget = main_container.MainContainer().get_actual_widget() if widget: widget.setFocus() def replace(self): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = 0 + s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.replace_match(self._searchWidget._line.text(), self._replaceWidget._lineReplace.text(), flags) if not editor.textCursor().hasSelection(): self.find() def replace_selected(self): self.replace_all(True) def replace_all(self, selected=False): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = 0 + s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.replace_match(self._searchWidget._line.text(), self._replaceWidget._lineReplace.text(), flags, True, selected) def find(self): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.find_match(self._searchWidget._line.text(), flags) def find_next(self): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = 0 + s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.find_match(self._searchWidget._line.text(), flags, True) def find_previous(self): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = 1 + s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.find_match(self._searchWidget._line.text(), flags, True) def showMessage(self, message, timeout): self._widgetStatus.hide() self._replaceWidget.setVisible(False) self.show() QStatusBar.showMessage(self, message, timeout) def message_end(self, message): if message == '': self.hide() QStatusBar.clearMessage(self) self._widgetStatus.show() widget = main_container.MainContainer().get_actual_widget() if widget: widget.setFocus()
class _StatusBar(QStatusBar): """StatusBar widget to be used in the IDE for several purposes.""" def __init__(self): super(_StatusBar, self).__init__() self.current_status = _STATUSBAR_STATE_SEARCH self._widgetStatus = QWidget() vbox = QVBoxLayout(self._widgetStatus) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) #Search Layout self._searchWidget = SearchWidget() vbox.addWidget(self._searchWidget) #Replace Layout self._replaceWidget = ReplaceWidget() vbox.addWidget(self._replaceWidget) self._replaceWidget.setVisible(False) #Code Locator self._codeLocator = locator.CodeLocatorWidget() vbox.addWidget(self._codeLocator) self._codeLocator.setVisible(False) #File system completer self._fileSystemOpener = FileSystemOpener() vbox.addWidget(self._fileSystemOpener) self._fileSystemOpener.setVisible(False) self.addWidget(self._widgetStatus) # Not Configurable Shortcuts shortEscStatus = QShortcut(QKeySequence(Qt.Key_Escape), self) self.connect(shortEscStatus, SIGNAL("activated()"), self.hide_status) self.connect(self._searchWidget._btnClose, SIGNAL("clicked()"), self.hide_status) self.connect(self._replaceWidget._btnCloseReplace, SIGNAL("clicked()"), lambda: self._replaceWidget.setVisible(False)) self.connect(self._fileSystemOpener.btnClose, SIGNAL("clicked()"), self.hide_status) self.connect(self._fileSystemOpener, SIGNAL("requestHide()"), self.hide_status) self.connect(self._codeLocator, SIGNAL("hidden()"), self.hide_status) #Register signals connections connections = ( {'target': 'main_container', 'signal_name': 'currentEditorChanged(QString)', 'slot': self._handle_tab_changed}, {'target': 'main_container', 'signal_name': 'updateLocator(QString)', 'slot': self._explore_file_code}, {'target': 'projects_explorer', 'signal_name': 'updateLocator()', 'slot': self._explore_code}, ) IDE.register_signals('status_bar', connections) IDE.register_service('status_bar', self) def install(self): """Install StatusBar as a service.""" self.hide() ide = IDE.get_service('ide') ide.setStatusBar(self) ui_tools.install_shortcuts(self, actions.ACTIONS_STATUS, ide) def _handle_tab_changed(self, new_tab): """ Re-run search if tab changed, we use the find of search widget because we want the widget to be updated. """ main_container = IDE.get_service("main_container") if main_container: editor = main_container.get_current_editor() else: return if editor: if self._searchWidget.isVisible(): self._searchWidget.find_matches(editor) if editor: self.disconnect(editor, SIGNAL("textChanged()"), self._notify_editor_changed) self.connect(editor, SIGNAL("textChanged()"), self._notify_editor_changed) def _notify_editor_changed(self): """ Lets search widget know that the editor contents changed and find needs to be re-run """ if self._searchWidget.isVisible(): main_container = IDE.get_service("main_container") if main_container: editor = main_container.get_current_editor() else: return if editor: self._searchWidget.contents_changed(editor) def _explore_code(self): """Update locator metadata for the current projects.""" self._codeLocator.explore_code() def _explore_file_code(self, path): """Update locator metadata for the file in path.""" self._codeLocator.explore_file_code(path) def show_search(self): """Show the status bar with the search widget.""" self.current_status = _STATUSBAR_STATE_SEARCH self._searchWidget.setVisible(True) self.show() main_container = IDE.get_service("main_container") editor = None if main_container: editor = main_container.get_current_editor() if editor and editor.textCursor().hasSelection(): text = editor.textCursor().selectedText() self._searchWidget._line.setText(text) self._searchWidget.find_matches(editor, True) if self._widgetStatus.isVisible(): self._searchWidget._line.setFocus() self._searchWidget._line.selectAll() def show_replace(self): """Show the status bar with the search/replace widget.""" self.current_status = _STATUSBAR_STATE_REPLACE self._replaceWidget.setVisible(True) self.show_search() def show_with_word(self): """Show the status bar with search widget using word under cursor.""" self.show_search() main_container = IDE.get_service("main_container") editor = None if main_container: editor = main_container.get_current_editor() if editor: word = editor._text_under_cursor() self._searchWidget._line.setText(word) editor.moveCursor(QTextCursor.WordLeft) self._searchWidget.find_matches(editor) def show_locator(self): """Show the status bar with the locator widget.""" self.current_status = _STATUSBAR_STATE_LOCATOR if not self._codeLocator.isVisible(): self._codeLocator.setVisible(True) self.show() self._codeLocator.show_suggestions() def show_file_opener(self): """Show the status bar with the file opener completer widget.""" self.current_status = _STATUSBAR_STATE_FILEOPENER self._fileSystemOpener.setVisible(True) self.show() self._fileSystemOpener.pathLine.setFocus() def hide_status(self): """Hide the Status Bar and its widgets.""" self.hide() self._searchWidget._checkSensitive.setCheckState(Qt.Unchecked) self._searchWidget._checkWholeWord.setCheckState(Qt.Unchecked) self._searchWidget.setVisible(False) self._replaceWidget.setVisible(False) self._codeLocator.setVisible(False) self._fileSystemOpener.setVisible(False) main_container = IDE.get_service("main_container") widget = None if main_container: widget = main_container.get_current_widget() if widget: widget.setFocus()
class _StatusBar(QStatusBar): """StatusBar widget to be used in the IDE for several purposes.""" def __init__(self): super(_StatusBar, self).__init__() self.current_status = _STATUSBAR_STATE_SEARCH self._widgetStatus = QWidget() vbox = QVBoxLayout(self._widgetStatus) vbox.setContentsMargins(0, 0, 0, 0) if settings.IS_MAC_OS: vbox.setSpacing(0) else: vbox.setSpacing(3) #Search Layout self._searchWidget = SearchWidget() vbox.addWidget(self._searchWidget) #Replace Layout self._replaceWidget = ReplaceWidget() vbox.addWidget(self._replaceWidget) self._replaceWidget.setVisible(False) #File system completer self._fileSystemOpener = FileSystemOpener() vbox.addWidget(self._fileSystemOpener) self._fileSystemOpener.setVisible(False) self.addWidget(self._widgetStatus) # Not Configurable Shortcuts shortEscStatus = QShortcut(QKeySequence(Qt.Key_Escape), self) self.connect(shortEscStatus, SIGNAL("activated()"), self.hide_status) self.connect(self._searchWidget._btnClose, SIGNAL("clicked()"), self.hide_status) self.connect(self._replaceWidget._btnCloseReplace, SIGNAL("clicked()"), lambda: self._replaceWidget.setVisible(False)) self.connect(self._fileSystemOpener.btnClose, SIGNAL("clicked()"), self.hide_status) self.connect(self._fileSystemOpener, SIGNAL("requestHide()"), self.hide_status) #Register signals connections connections = ( { 'target': 'main_container', 'signal_name': 'currentEditorChanged(QString)', 'slot': self._handle_tab_changed }, { 'target': 'main_container', 'signal_name': 'updateLocator(QString)', 'slot': self._explore_file_code }, { 'target': 'projects_explorer', 'signal_name': 'updateLocator()', 'slot': self._explore_code }, ) IDE.register_signals('status_bar', connections) IDE.register_service('status_bar', self) def install(self): """Install StatusBar as a service.""" self.hide() ide = IDE.get_service('ide') ide.setStatusBar(self) self._codeLocator = locator_widget.LocatorWidget(ide) ui_tools.install_shortcuts(self, actions.ACTIONS_STATUS, ide) def _handle_tab_changed(self, new_tab): """ Re-run search if tab changed, we use the find of search widget because we want the widget to be updated. """ main_container = IDE.get_service("main_container") if main_container: editor = main_container.get_current_editor() else: return if editor: if self._searchWidget.isVisible(): self._searchWidget.find_matches(editor) if editor: self.disconnect(editor, SIGNAL("textChanged()"), self._notify_editor_changed) self.connect(editor, SIGNAL("textChanged()"), self._notify_editor_changed) def _notify_editor_changed(self): """ Lets search widget know that the editor contents changed and find needs to be re-run """ if self._searchWidget.isVisible(): main_container = IDE.get_service("main_container") if main_container: editor = main_container.get_current_editor() else: return if editor: self._searchWidget.contents_changed(editor) def _explore_code(self): """Update locator metadata for the current projects.""" self._codeLocator.explore_code() def _explore_file_code(self, path): """Update locator metadata for the file in path.""" self._codeLocator.explore_file_code(path) def show_search(self): """Show the status bar with the search widget.""" self.current_status = _STATUSBAR_STATE_SEARCH self._searchWidget.setVisible(True) self.show() main_container = IDE.get_service("main_container") editor = None if main_container: editor = main_container.get_current_editor() if editor and editor.textCursor().hasSelection(): text = editor.textCursor().selectedText() self._searchWidget._line.setText(text) self._searchWidget.find_matches(editor, True) if self._widgetStatus.isVisible(): self._searchWidget._line.setFocus() self._searchWidget._line.selectAll() def show_replace(self): """Show the status bar with the search/replace widget.""" self.current_status = _STATUSBAR_STATE_REPLACE self._replaceWidget.setVisible(True) self.show_search() def show_with_word(self): """Show the status bar with search widget using word under cursor.""" self.show_search() main_container = IDE.get_service("main_container") editor = None if main_container: editor = main_container.get_current_editor() if editor: word = editor._text_under_cursor() self._searchWidget._line.setText(word) editor.moveCursor(QTextCursor.WordLeft) self._searchWidget.find_matches(editor) def show_locator(self): """Show the status bar with the locator widget.""" if not self._codeLocator.isVisible(): self._codeLocator.show() def show_file_opener(self): """Show the status bar with the file opener completer widget.""" self.current_status = _STATUSBAR_STATE_FILEOPENER self._fileSystemOpener.setVisible(True) self.show() self._fileSystemOpener.pathLine.setFocus() def hide_status(self): """Hide the Status Bar and its widgets.""" self.hide() self._searchWidget._checkSensitive.setCheckState(Qt.Unchecked) self._searchWidget._checkWholeWord.setCheckState(Qt.Unchecked) self._searchWidget.setVisible(False) self._replaceWidget.setVisible(False) self._fileSystemOpener.setVisible(False) main_container = IDE.get_service("main_container") widget = None if main_container: widget = main_container.get_current_widget() if widget: widget.setFocus()
class _StatusBar(QStatusBar): def __init__(self): super(_StatusBar, self).__init__() self._widgetStatus = QWidget() vbox = QVBoxLayout(self._widgetStatus) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) #Search Layout self._searchWidget = SearchWidget(self) vbox.addWidget(self._searchWidget) #Replace Layout self._replaceWidget = ReplaceWidget(self) vbox.addWidget(self._replaceWidget) self._replaceWidget.setVisible(False) #Code Locator self._codeLocator = locator.CodeLocatorWidget(self) vbox.addWidget(self._codeLocator) self._codeLocator.setVisible(False) #File system completer self._fileSystemOpener = FileSystemOpener() vbox.addWidget(self._fileSystemOpener) self._fileSystemOpener.setVisible(False) self.addWidget(self._widgetStatus) # Not Configurable Shortcuts shortEscStatus = QShortcut(QKeySequence(Qt.Key_Escape), self) self.connect(self, SIGNAL("messageChanged(QString)"), self.message_end) self.connect(self._replaceWidget._btnCloseReplace, SIGNAL("clicked()"), lambda: self._replaceWidget.setVisible(False)) self.connect(self._replaceWidget._btnReplace, SIGNAL("clicked()"), self.replace) self.connect(self._replaceWidget._btnReplaceAll, SIGNAL("clicked()"), self.replace_all) self.connect(self._replaceWidget._btnReplaceSelection, SIGNAL("clicked()"), self.replace_selected) self.connect(self._fileSystemOpener.btnClose, SIGNAL("clicked()"), self.hide_status) self.connect(self._fileSystemOpener, SIGNAL("requestHide()"), self.hide_status) self.connect(shortEscStatus, SIGNAL("activated()"), self.hide_status) #Register signals connections connections = ( {'target': 'main_container', 'signal_name': 'currentEditorChanged(QString)', 'slot': self.handle_tab_changed}, {'target': 'main_container', 'signal_name': 'updateLocator(QString)', 'slot': self.explore_file_code}, {'target': 'explorer_container', 'signal_name': 'updateLocator()', 'slot': self.explore_code}, ) IDE.register_signals('status_bar', connections) IDE.register_service('status_bar', self) def install(self): self.hide() ide = IDE.get_service('ide') ide.setStatusBar(self) ui_tools.install_shortcuts(self, actions.ACTIONS_STATUS, ide) def find_next_result(self): self._searchWidget.find_next() def find_previous_result(self): self._searchWidget.find_previous() def handle_tab_changed(self, new_tab): """ Re-run search if tab changed, we use the find of search widget because we want the widget to be updated. """ editor = main_container.MainContainer().get_actual_editor() if self._searchWidget.isVisible(): self._searchWidget.find_matches(editor) if editor: self.disconnect(editor, SIGNAL("textChanged()"), self._notify_editor_changed) self.connect(editor, SIGNAL("textChanged()"), self._notify_editor_changed) def _notify_editor_changed(self): """ Lets search widget know that the editor contents changed and find needs to be re-run """ if self._searchWidget.isVisible(): editor = main_container.MainContainer().get_actual_editor() self._searchWidget.contents_changed(editor) def explore_code(self): self._codeLocator.explore_code() def explore_file_code(self, path): self._codeLocator.explore_file_code(path) def show(self): self.clearMessage() QStatusBar.show(self) editor = main_container.MainContainer().get_actual_editor() if editor and editor.textCursor().hasSelection(): text = editor.textCursor().selectedText() self._searchWidget._line.setText(text) self._searchWidget.find_matches(editor, True) if self._widgetStatus.isVisible(): self._searchWidget._line.setFocus() self._searchWidget._line.selectAll() def show_replace(self): self.clearMessage() self.show() editor = main_container.MainContainer().get_actual_editor() if editor: if editor.textCursor().hasSelection(): word = editor.textCursor().selectedText() self._searchWidget._line.setText(word) self._replaceWidget.setVisible(True) def show_with_word(self): self.clearMessage() editor = main_container.MainContainer().get_actual_editor() if editor: word = editor._text_under_cursor() self._searchWidget._line.setText(word) editor = main_container.MainContainer().get_actual_editor() editor.moveCursor(QTextCursor.WordLeft) self._searchWidget.find_matches(editor) self.show() def show_locator(self): if not self._codeLocator.isVisible(): self.clearMessage() self._searchWidget.setVisible(False) self.show() self._codeLocator.setVisible(True) self._codeLocator._completer.setFocus() self._codeLocator.show_suggestions() def show_file_opener(self): self.clearMessage() self._searchWidget.setVisible(False) self._fileSystemOpener.setVisible(True) self.show() self._fileSystemOpener.pathLine.setFocus() def hide_status(self): self._searchWidget._checkSensitive.setCheckState(Qt.Unchecked) self._searchWidget._checkWholeWord.setCheckState(Qt.Unchecked) self.hide() self._searchWidget.setVisible(True) self._replaceWidget.setVisible(False) self._codeLocator.setVisible(False) self._fileSystemOpener.setVisible(False) widget = main_container.MainContainer().get_actual_widget() if widget: widget.setFocus() def replace(self): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = 0 + s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.replace_match(self._searchWidget._line.text(), self._replaceWidget._lineReplace.text(), flags) if not editor.textCursor().hasSelection(): self.find() def replace_selected(self): self.replace_all(True) def replace_all(self, selected=False): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = 0 + s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.replace_match(self._searchWidget._line.text(), self._replaceWidget._lineReplace.text(), flags, True, selected) def find(self): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.find_match(self._searchWidget._line.text(), flags) def find_next(self): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = 0 + s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.find_match(self._searchWidget._line.text(), flags, True) def find_previous(self): s = 0 if not self._searchWidget._checkSensitive.isChecked() \ else QTextDocument.FindCaseSensitively w = 0 if not self._searchWidget._checkWholeWord.isChecked() \ else QTextDocument.FindWholeWords flags = 1 + s + w editor = main_container.MainContainer().get_actual_editor() if editor: editor.find_match(self._searchWidget._line.text(), flags, True) def showMessage(self, message, timeout): if settings.SHOW_STATUS_NOTIFICATIONS: self._widgetStatus.hide() self._replaceWidget.setVisible(False) self.show() QStatusBar.showMessage(self, message, timeout) def message_end(self, message): if message == '': self.hide() QStatusBar.clearMessage(self) self._widgetStatus.show()
class XNavigationEdit(XLineEdit): """ """ navigationChanged = Signal() __designer_icon__ = projexui.resources.find('img/ui/navigate.png') def __init__( self, parent = None ): super(XNavigationEdit, self).__init__( parent ) # define custom properties self._separator = '/' self._partsEditingEnabled = True self._originalText = '' self._scrollWidget = QScrollArea(self) self._partsWidget = QWidget(self._scrollWidget) self._buttonGroup = QButtonGroup(self) self._scrollAmount = 0 self._navigationModel = None # create the completer tree palette = self.palette() palette.setColor(palette.Base, palette.color(palette.Window)) palette.setColor(palette.Text, palette.color(palette.WindowText)) bg = palette.color(palette.Highlight) abg = bg.darker(115) fg = palette.color(palette.HighlightedText) sbg = 'rgb(%s, %s, %s)' % (bg.red(), bg.green(), bg.blue()) sabg = 'rgb(%s, %s, %s)' % (abg.red(), abg.green(), abg.blue()) sfg = 'rgb(%s, %s, %s)' % (fg.red(), fg.green(), fg.blue()) style = 'QTreeView::item:hover { '\ ' color: %s;'\ ' background: qlineargradient(x1:0,'\ ' y1:0,'\ ' x2:0,'\ ' y2:1,'\ ' stop: 0 %s,'\ ' stop: 1 %s);'\ '}' % (sfg, sbg, sabg) self._completerTree = QTreeView(self) self._completerTree.setStyleSheet(style) self._completerTree.header().hide() self._completerTree.setFrameShape(QTreeView.Box) self._completerTree.setFrameShadow(QTreeView.Plain) self._completerTree.setPalette(palette) self._completerTree.setEditTriggers(QTreeView.NoEditTriggers) self._completerTree.setWindowFlags(Qt.Popup) self._completerTree.installEventFilter(self) self._completerTree.setRootIsDecorated(False) self._completerTree.setItemsExpandable(False) # create the editing widget layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addStretch() self._scrollWidget.setFrameShape( QScrollArea.NoFrame ) self._scrollWidget.setFocusPolicy(Qt.NoFocus) self._scrollWidget.setWidget(self._partsWidget) self._scrollWidget.setWidgetResizable(True) self._scrollWidget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self._scrollWidget.setAlignment(Qt.AlignTop | Qt.AlignRight) self._scrollWidget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self._scrollWidget.setContentsMargins(0, 0, 0, 0) self._scrollWidget.setViewportMargins(0, 0, 0, 0) self._scrollWidget.move(2, 2) self._partsWidget.setLayout(layout) self._partsWidget.setCursor(Qt.ArrowCursor) self._partsWidget.setAutoFillBackground(True) self._partsWidget.setFixedHeight(self.height() - 12) palette = self._partsWidget.palette() palette.setColor(palette.Background, palette.color(palette.Base)) self._partsWidget.setPalette(palette) # create connections self._completerTree.clicked.connect( self.navigateToIndex ) self._buttonGroup.buttonClicked.connect( self.handleButtonClick ) self._scrollWidget.horizontalScrollBar().valueChanged.connect( self.scrollParts ) def acceptEdit( self ): """ Accepts the current text and rebuilds the parts widget. """ if ( self._partsWidget.isVisible() ): return False use_completion = self.completer().popup().isVisible() completion = self.completer().currentCompletion() self._completerTree.hide() self.completer().popup().hide() if ( use_completion ): self.setText(completion) else: self.rebuild() return True def cancelEdit( self ): """ Rejects the current edit and shows the parts widget. """ if ( self._partsWidget.isVisible() ): return False self._completerTree.hide() self.completer().popup().hide() self.setText(self._originalText) return True def currentItem( self ): """ Returns the current navigation item from the current path. :return <XNavigationItem> || None """ model = self.navigationModel() if ( not model ): return None return model.itemByPath(self.text()) def eventFilter( self, object, event ): """ Filters the events for the inputed object through this edit. :param object | <QObject> event | <QEvent> :return <bool> | consumed """ if ( event.type() == event.KeyPress ): if ( event.key() == Qt.Key_Escape ): self._completerTree.hide() self.completer().popup().hide() self.cancelEdit() elif ( event.key() in (Qt.Key_Return, Qt.Key_Enter) ): self.acceptEdit() return True elif ( event.key() == Qt.Key_Tab ): if ( self.completer().popup().isVisible() ): text = str(self.completer().currentCompletion()) super(XNavigationEdit, self).setText(text) return True else: self.acceptEdit() return False elif ( event.type() == event.MouseButtonPress ): if ( not self._completerTree.rect().contains(event.pos()) ): self._completerTree.hide() self.completer().popup().hide() self.cancelEdit() return False def focusOutEvent( self, event ): """ Overloads the focus out event to cancel editing when the widget loses focus. :param event | <QFocusEvent> """ super(XNavigationEdit, self).focusOutEvent(event) self.cancelEdit() def handleButtonClick( self, button ): """ Handle the event when a user clicks on one of the part buttons. :param button | <QToolButton> """ path = button.property('path') is_completer = button.property('is_completer') # popup a completion menu if ( unwrapVariant(is_completer) ): model = self.navigationModel() if ( not model ): return sep = self.separator() path = str(unwrapVariant(path)) item = model.itemByPath(path, includeRoot = True) if ( not item ): return curr_path = str(self.text()).strip(self.separator()) curr_path = curr_path.replace(path, '').strip(self.separator()) child_name = '' if ( curr_path ): child_name = curr_path.split(self.separator())[0] index = model.indexFromItem(item) self._completerTree.move(QCursor.pos()) self._completerTree.setRootIndex(index) self._completerTree.verticalScrollBar().setValue(0) if ( child_name ): child_item = None for i in range(item.rowCount()): child = item.child(i) if ( child.text() == child_name ): child_item = child break if ( child_item ): child_index = model.indexFromItem(child_item) self._completerTree.setCurrentIndex(child_index) self._completerTree.scrollTo(child_index) self._completerTree.show() self._completerTree.setUpdatesEnabled(True) else: self.setText(unwrapVariant(path)) def keyPressEvent( self, event ): """ Overloads the key press event to listen for escape calls to cancel the parts editing. :param event | <QKeyPressEvent> """ if ( self.scrollWidget().isHidden() ): if ( event.key() == Qt.Key_Escape ): self.cancelEdit() return elif ( event.key() in (Qt.Key_Return, Qt.Key_Enter) ): self.acceptEdit() return elif ( event.key() == Qt.Key_A and event.modifiers() == Qt.ControlModifier ): self.startEdit() super(XNavigationEdit, self).keyPressEvent(event) def mouseDoubleClickEvent( self, event ): """ Overloads the system to enable editing when a user double clicks. :param event | <QMouseEvent> """ super(XNavigationEdit, self).mouseDoubleClickEvent(event) self.startEdit() def navigationModel( self ): """ Returns the navigation model linked with this edit. :return <XNavigationModel> || None """ return self._navigationModel def navigateToIndex( self, index ): """ Navigates to the inputed action's path. :param action | <QAction> """ self._completerTree.hide() item = self._navigationModel.itemFromIndex(index) self.setText(self._navigationModel.itemPath(item)) def parts( self ): """ Returns the parts that are used for this system. :return [<str>, ..] """ path = str(self.text()).strip(self.separator()) if ( not path ): return [] return path.split(self.separator()) def partsWidget( self ): """ Returns the widget that contains the parts system. :return <QScrollArea> """ return self._partsWidget def startEdit( self ): """ Rebuilds the pathing based on the parts. """ self._originalText = self.text() self.scrollWidget().hide() self.setFocus() self.selectAll() def rebuild( self ): """ Rebuilds the parts widget with the latest text. """ navitem = self.currentItem() if ( navitem ): navitem.initialize() self.setUpdatesEnabled(False) self.scrollWidget().show() self._originalText = '' partsw = self.partsWidget() for button in self._buttonGroup.buttons(): self._buttonGroup.removeButton(button) button.close() button.setParent(None) button.deleteLater() # create the root button layout = partsw.layout() parts = self.parts() button = QToolButton(partsw) button.setAutoRaise(True) button.setMaximumWidth(12) button.setArrowType(Qt.RightArrow) button.setProperty('path', wrapVariant('')) button.setProperty('is_completer', wrapVariant(True)) last_button = button self._buttonGroup.addButton(button) layout.insertWidget(0, button) # check to see if we have a navigation model setup if ( self._navigationModel ): last_item = self._navigationModel.itemByPath(self.text()) show_last = last_item and last_item.rowCount() > 0 else: show_last = False # load the navigation system count = len(parts) for i, part in enumerate(parts): path = self.separator().join(parts[:i+1]) button = QToolButton(partsw) button.setAutoRaise(True) button.setText(part) if ( self._navigationModel ): item = self._navigationModel.itemByPath(path) if ( item ): button.setIcon(item.icon()) button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) button.setProperty('path', wrapVariant(path)) button.setProperty('is_completer', wrapVariant(False)) self._buttonGroup.addButton(button) layout.insertWidget((i * 2) + 1, button) # determine if we should show the final button if ( show_last or i < (count - 1) ): button = QToolButton(partsw) button.setAutoRaise(True) button.setMaximumWidth(12) button.setArrowType(Qt.RightArrow) button.setProperty('path', wrapVariant(path)) button.setProperty('is_completer', wrapVariant(True)) self._buttonGroup.addButton(button) layout.insertWidget((i * 2) + 2, button) last_button = button if ( self.scrollWidget().width() < partsw.width() ): self.scrollParts(partsw.width() - self.scrollWidget().width()) self.setUpdatesEnabled(True) self.navigationChanged.emit() def resizeEvent( self, event ): """ Resizes the current widget and its parts widget. :param event | <QResizeEvent> """ super(XNavigationEdit, self).resizeEvent(event) w = self.width() h = self.height() self._scrollWidget.resize(w - 4, h - 4) if ( self._scrollWidget.width() < self._partsWidget.width() ): self.scrollParts( self._partsWidget.width() - self._scrollWidget.width() ) def scrollParts( self, amount ): """ Scrolls the parts to offset the scrolling amount. :param amount | <int> """ change = self._scrollAmount - amount self._partsWidget.scroll(change, 0) self._scrollAmount = amount def scrollWidget( self ): """ Returns the scrolling widget. :return <QScrollArea> """ return self._scrollWidget def separator( self ): """ Returns the separation character that is used for this edit. :return <str> """ return self._separator def setTopLevelItems( self, items ): """ Initializes the navigation system to start with the inputed root \ item. :param item | <XNavigationItem> """ if ( not self._navigationModel ): self.setNavigationModel(XNavigationModel(self)) self._navigationModel.setTopLevelItems(items) def setNavigationModel( self, model ): """ Sets the navigation model for this edit. :param model | <XNavigationModel> """ self._navigationModel = model self._completerTree.setModel(model) if ( model ): model.setSeparator(self.separator()) completer = XNavigationCompleter(model, self) self.setCompleter(completer) completer.popup().installEventFilter(self) else: self.setCompleter(None) self.rebuild() def setParts( self, parts ): """ Sets the path for this edit widget by providing the parts to the path. :param parts | [<str>, ..] """ self.setText(self.separator().join(map(str, parts))) def setSeparator( self, separator ): """ Sets the separator to the inputed character. :param separator | <str> """ self._separator = separator if ( self._navigationModel ): self._navigationModel.setSeparator(separator) self.rebuild() def setText( self, text ): """ Sets the text for this edit to the inputed text. :param text | <str> """ super(XNavigationEdit, self).setText(text) self.scrollWidget().show() if ( text == '' or self._originalText != text ): self.rebuild()
def isVisible(self): """not only visible but also not minimized""" return QWidget.isVisible( self) and not self.windowState() & Qt.WindowMinimized
def isVisible(self): """not only visible but also not minimized""" return QWidget.isVisible(self) and not self.windowState() & Qt.WindowMinimized
class UiController: def __init__(self, controller, debug_mode, logger): self.controller = controller self.datahandler = controller.datahandler self.debug_mode = debug_mode self.logger = logger ### Main Window self.main_widget = QMainWindow() self.main_widget.setAttribute(Qt.WA_Maemo5StackedWindow) self.main_ui = Ui_DropN900Widget() self.main_ui.setupUi(self.main_widget) # Stacked layout for context switching self.stacked_layout = QtGui.QStackedLayout() self.main_ui.centralwidget.setLayout(self.stacked_layout) # Menu items self.action_transfers = QtGui.QAction("Transfers", self.main_widget) self.action_settings = QtGui.QAction("Settings", self.main_widget) self.action_sync = QtGui.QAction("Synchronize", self.main_widget) self.action_sync_photos = QtGui.QAction("Sync Media", self.main_widget) self.action_console = QtGui.QAction("Show Log", self.main_widget) self.action_about = QtGui.QAction("About", self.main_widget) self.action_exit = QtGui.QAction("Exit", self.main_widget) self.main_ui.menubar.addAction(self.action_transfers) self.main_ui.menubar.addAction(self.action_settings) self.main_ui.menubar.addAction(self.action_sync) self.main_ui.menubar.addAction(self.action_sync_photos) self.main_ui.menubar.addAction(self.action_console) self.main_ui.menubar.addAction(self.action_about) self.main_ui.menubar.addAction(self.action_exit) # Connects self.action_transfers.triggered.connect(self.show_transfer_widget) self.action_sync.triggered.connect(self.synchronize_now) self.action_sync_photos.triggered.connect(self.synchronize_now_photos) self.action_settings.triggered.connect(self.show_settings_widget) self.action_console.triggered.connect(self.show_console) self.action_about.triggered.connect(self.show_about) self.action_exit.triggered.connect(self.shut_down) ### Trusted Login Widget self.trusted_login_widget = QWidget() self.trusted_login_ui = Ui_TrustedLoginWidget() self.trusted_login_ui.setupUi(self.trusted_login_widget) self.trusted_login_ui.label_icon.setPixmap(QPixmap(self.datahandler.datapath("ui/images/dropn900_logo.png")).scaled(65,65)) # Connects self.trusted_login_ui.button_auth.clicked.connect(self.try_trusted_login) ### Manager Widget self.manager_widget = QWidget() self.manager_ui = Ui_ManagerWidget() self.manager_ui.setupUi(self.manager_widget) # Tree Controller tree = self.manager_ui.tree_widget self.tree_controller = TreeController(tree, self.manager_ui, self.controller, self.logger) # Hide public link elements on start self.manager_ui.button_copy_public_link.hide() self.manager_ui.button_open_public_link.hide() # Connects self.manager_ui.button_copy_public_link.clicked.connect(self.copy_item_link) self.manager_ui.button_open_public_link.clicked.connect(self.open_item_link) self.manager_ui.button_download.clicked.connect(self.item_download) self.manager_ui.button_upload.clicked.connect(self.item_upload) self.manager_ui.button_rename.clicked.connect(self.item_rename) self.manager_ui.button_remove.clicked.connect(self.item_remove) self.manager_ui.button_new_folder.clicked.connect(self.item_new_folder) self.manager_ui.sync_button.clicked.connect(self.synchronize_now) self.last_dl_location = None self.last_ul_location = None ### Console widget self.console_widget = QWidget(self.main_widget, Qt.Window) self.console_widget.setAttribute(Qt.WA_Maemo5StackedWindow) self.console_ui = Ui_ConsoleWidget() self.console_ui.setupUi(self.console_widget) self.console_ui.button_save.clicked.connect(self.save_log_to_file) self.console_ui.button_back.clicked.connect(self.hide_console) ### Settings widget self.settings_widget = None ### Fill stacked layout self.stacked_layout.addWidget(self.trusted_login_widget) self.stacked_layout.addWidget(self.manager_widget) self.stacked_layout.setCurrentWidget(self.trusted_login_widget) ### Loading Widget self.loading_widget = QWidget(self.manager_widget) self.loading_ui = Ui_LoadingWidget() self.loading_ui.setupUi(self.loading_widget) self.manager_ui.action_layout.insertWidget(3, self.loading_widget) self.loading_widget.hide() self.tree_controller.set_loading_ui(self.loading_ui) # Init loading animation self.loading_animation = QMovie(self.datahandler.datapath("ui/images/loading.gif"), "GIF", self.loading_ui.load_animation_label) self.loading_animation.setCacheMode(QMovie.CacheAll) self.loading_animation.setSpeed(150) self.loading_animation.setScaledSize(QtCore.QSize(48,48)) self.loading_ui.load_animation_label.setMovie(self.loading_animation) # Init hide timer and icons for information messages self.information_message_timer = QTimer() self.information_message_timer.setSingleShot(True) self.information_message_timer.timeout.connect(self.hide_information_message) self.information_icon_ok = QPixmap(self.datahandler.datapath("ui/icons/check.png")).scaled(24,24) self.information_icon_error = QPixmap(self.datahandler.datapath("ui/icons/cancel.png")).scaled(24,24) self.information_icon_queue = QPixmap(self.datahandler.datapath("ui/icons/queue.png")).scaled(24,24) ### About dialog self.about_dialog = AboutDialog(self) self.set_synching(False) def set_synching(self, syncing): self.manager_ui.sync_button.setVisible(not syncing) self.manager_ui.sync_label.setVisible(syncing) def set_settings_widget(self, settings_widget): self.settings_widget = settings_widget def set_transfer_widget(self, transfer_widget): self.transfer_widget = transfer_widget def synchronize_now(self): self.settings_widget.sync_now_clicked() def synchronize_now_photos(self): self.controller.sync_manager.sync_media() def show(self): # Nokia N900 screen resolution, full screen self.main_widget.resize(800, 480) self.main_widget.show() self.main_widget.showMaximized() def show_settings_widget(self): if self.settings_widget != None: if not self.settings_widget.isVisible(): self.settings_widget.show() self.settings_widget.check_settings() def show_transfer_widget(self): if self.settings_widget.isVisible(): self.settings_widget.hide() self.transfer_widget.show() def show_about(self): if not self.about_dialog.isVisible(): self.about_dialog.show() def show_note(self, message): QMaemo5InformationBox.information(None, QString(message), 0) def show_banner(self, message, timeout = 5000): QMaemo5InformationBox.information(None, QString(message), timeout) def show_loading_ui(self, message = "", loading = True): self.loading_ui.info_label.setText(message) self.loading_ui.info_label_icon.hide() self.thumb_was_visible = self.manager_ui.thumb_container.isVisible() self.manager_ui.thumb_container.hide() self.loading_widget.show() self.loading_ui.load_animation_label.setVisible(loading) if loading: self.loading_animation.start() else: self.loading_animation.stop() def show_information_ui(self, message, succesfull, timeout = 4000): self.loading_ui.load_animation_label.hide() self.thumb_was_visible = self.manager_ui.thumb_container.isVisible() if self.thumb_was_visible: self.manager_ui.thumb_container.hide() self.loading_ui.info_label.setText(message) if succesfull == None: icon = self.information_icon_queue elif succesfull: icon = self.information_icon_ok else: icon = self.information_icon_error self.loading_ui.info_label_icon.setPixmap(icon) self.loading_ui.info_label_icon.show() self.loading_widget.show() self.information_message_timer.start(timeout) def hide_loading_ui(self): if not self.information_message_timer.isActive(): self.loading_widget.hide() if self.loading_animation.state() == QMovie.Running: self.loading_animation.stop() def hide_information_message(self): self.loading_ui.info_label_icon.hide() self.hide_loading_ui() self.manager_ui.thumb_container.setVisible(self.thumb_was_visible) def try_trusted_login(self): self.trusted_login_ui.label_error.setText("") email = self.trusted_login_ui.line_edit_email.text() password = self.trusted_login_ui.line_edit_password.text() error = None if email.isEmpty(): error = "Email can't be empty!" elif email.count("@") != 1: error = "Invalid email, check your @ signs!" elif email.contains(" "): error = "Invalid email, can't have spaces!" elif password.isEmpty(): error = "Password can't be empty!" if error == None: self.show_banner("Authenticating...", 3000) self.set_trusted_login_info("Authenticating, please wait...") self.truested_email = self.datahandler.to_unicode(str(email.toUtf8())) self.trusted_password = self.datahandler.to_unicode(str(password.toUtf8())) QTimer.singleShot(100, self.do_trusted_login_networking) else: self.set_trusted_login_error(error) def set_trusted_login_error(self, error): self.trusted_login_ui.label_error.setStyleSheet("color: #9d1414;") self.trusted_login_ui.label_error.setText(error) self.truested_email = None self.trusted_password = None def set_trusted_login_info(self, info): self.trusted_login_ui.label_error.setStyleSheet("color: #149d2b;") self.trusted_login_ui.label_error.setText(info) def do_trusted_login_networking(self): self.controller.end_trusted_auth(self.truested_email.encode("utf-8"), self.trusted_password.encode("utf-8")) self.truested_email = None self.trusted_password = None def reset_trusted_login(self): self.trusted_login_ui.line_edit_email.clear() self.trusted_login_ui.line_edit_password.clear() self.trusted_login_ui.label_error.clear() def switch_context(self, view = None): widget = None if view == "trustedlogin": widget = self.trusted_login_widget if view == "manager": widget = self.manager_widget if view == "console": self.console_widget.show() if view == None and self.last_view != None: widget = self.last_view if widget != None: self.last_view = self.stacked_layout.currentWidget() self.stacked_layout.setCurrentWidget(widget) def get_selected_data(self): return self.tree_controller.selected_data # Signal handlers def shut_down(self): self.main_widget.close() def show_console(self): if self.console_widget.isVisible() == False: self.switch_context("console") else: self.hide_console() def hide_console(self): self.console_widget.hide() def save_log_to_file(self): filename = self.datahandler.get_data_dir_path() + "dropn900.log" log_string = str(self.console_ui.text_area.toPlainText()) try: log_file = open(filename, "w") log_file.write(log_string) log_file.close() self.show_banner("Log saved to " + filename) except IOError: self.logger.error("Could not open " + filename + " to save log") def browser_control_clicked(self): if self.controller.connected: self.switch_context() else: self.controller.end_auth() def copy_item_link(self): url = self.tree_controller.current_public_link if url == None: return self.datahandler.copy_url_to_clipboard(url) def open_item_link(self): url = self.tree_controller.current_public_link if url == None: return QDesktopServices.openUrl(QtCore.QUrl(url)) def item_download(self): data = self.get_selected_data() if data == None: return if self.datahandler.dont_show_dl_dialog == False: # This dialog shows sometimes strange stuff on maemo5 # It's a PyQt4 bug and its the best we got, you can cope with this if self.last_dl_location == None: self.last_dl_location = self.datahandler.get_data_dir_path() local_folder_path = QFileDialog.getExistingDirectory(self.manager_widget, QString("Select Download Folder"), QString(self.last_dl_location), QFileDialog.ShowDirsOnly|QFileDialog.HideNameFilterDetails|QFileDialog.ReadOnly) if local_folder_path.isEmpty(): return py_unicode_path = self.datahandler.to_unicode(str(local_folder_path.toUtf8())) self.last_dl_location = py_unicode_path store_path = py_unicode_path + "/" + data.name else: dir_check = QDir(self.datahandler.get_data_dir_path()) if not dir_check.exists(): self.show_note("Cannot download, destination " + self.datahandler.get_data_dir_path() + " does not exist. Please set a new folder in settings.") return store_path = self.datahandler.get_data_dir_path() + data.name self.controller.connection.get_file(data.path, data.root, store_path, data.get_size(), data.mime_type) def item_upload(self): data = self.get_selected_data() if data == None or not data.is_folder(): return # This dialog shows sometimes strange stuff on maemo5 # It's a PyQt4 bug and its the best we got, you can cope with this if self.last_ul_location == None: self.last_ul_location = self.datahandler.get_data_dir_path() local_file_path = QFileDialog.getOpenFileName(self.manager_widget, QString("Select File for Upload"), QString(self.last_ul_location)) if local_file_path.isEmpty(): return py_unicode_path = self.datahandler.to_unicode(str(local_file_path.toUtf8())) self.last_ul_location = py_unicode_path[0:py_unicode_path.rfind("/")] self.controller.connection.upload_file(data.path, data.root, py_unicode_path) def item_rename(self): data = self.get_selected_data() if data == None: return # Get new name from user old_name = data.get_name() keyword = "file" if not data.is_folder() else "folder" new_name, ok = QInputDialog.getText(None, "Renaming " + keyword, "Give new name for " + keyword + " " + old_name, QtGui.QLineEdit.Normal, old_name) if not ok: return # Validate with QString if not self.is_name_valid(new_name, keyword): return # Make QString to python 'unicode' new_name = self.datahandler.to_unicode(str(new_name.toUtf8())) if old_name == new_name: return # Extension will be lost, ask user if he wants to leave it q_old_name = QtCore.QString(old_name) if q_old_name.contains("."): if not new_name.contains("."): format = old_name[q_old_name.lastIndexOf("."):] confirmation = QMessageBox.question(None, "Extension missing", "Do you want to append the original '" + format + "' extensions to the filename '" + new_name + "'?", QMessageBox.Yes, QMessageBox.No) if confirmation == QMessageBox.Yes: new_name.append(format) # Get final new path and rename if data.parent == "/": new_name = data.parent + new_name else: new_name = data.parent + "/" + new_name self.controller.connection.rename(data.root, data.path, new_name, data) def item_remove(self): data = self.get_selected_data() if data == None: return if data.is_folder(): confirmation = QMessageBox.question(None, "Remove folder verification", "Are you sure you want to remove the entire folder " + data.get_name() +"?", QMessageBox.Yes, QMessageBox.Cancel) else: confirmation = QMessageBox.question(None, "Remove file verification", "Are you sure you want to remove " + data.get_name() +"?", QMessageBox.Yes, QMessageBox.Cancel) if confirmation == QMessageBox.Yes: self.controller.connection.remove_file(data.root, data.path, data.parent, data.is_folder()) def item_new_folder(self): data = self.get_selected_data() if data == None: return if not data.is_folder(): return full_create_path = data.path + "/" new_folder_name, ok = QInputDialog.getText(None, "Give new folder name", "") if not ok: return # Validate QString if not self.is_name_valid(new_folder_name, "folder"): return # Make QString to python unicode new_folder_name = self.datahandler.to_unicode(str(new_folder_name.toUtf8())) full_create_path = data.path + "/" + new_folder_name self.controller.connection.create_folder(data.root, full_create_path, new_folder_name, data.path) def is_name_valid(self, name, item_type): if name.isEmpty() or name.isNull(): return False if name.contains("/"): self.show_information_ui("Cant use / in new " + item_type + " name", False) return False if name.contains("\\"): self.show_information_ui("Cant use \ in new " + item_type + " name", False) return False if name.startsWith(" "): self.show_information_ui("New " + item_type + " name cant start with a space", False) return False if name.endsWith(" "): self.show_information_ui("New " + item_type + " name cant end with a space", False) return False return True