class Container(QVBoxLayout): def __init__(self, base): QVBoxLayout.__init__(self) self.base = base self.child = None self.columns = {} self.is_empty = None self.loading() def __link_clicked(self, url): if url == "cmd:add_columns": self.base.show_column_menu(QCursor.pos()) elif url == "cmd:add_accounts": self.base.show_accounts_dialog() elif url == "cmd:restart": self.base.restart() def clear_layout(self, layout): if layout is not None: while layout.count(): item = layout.takeAt(0) widget = item.widget() if widget is not None: widget.deleteLater() else: self.clear_layout(item.layout()) def empty(self, with_accounts=None): if self.child: self.clear_layout(self) image = self.base.load_image("turpial-196.png", True) logo = QLabel() logo.setPixmap(image) logo.setAlignment(Qt.AlignCenter) logo.setContentsMargins(0, 80, 0, 0) appname = QLabel("Turpial 3") if detect_os() == OS_MAC: font = QFont("Maven Pro Light", 28, 0, False) font2 = QFont("Ubuntu", 16, 0, False) else: font = QFont("Maven Pro Light", 18, QFont.Light, False) font2 = QFont("Ubuntu", 12, QFont.Normal, False) appname.setFont(font) welcome = QLabel() welcome.setText(i18n.get("welcome")) welcome.setAlignment(Qt.AlignCenter) welcome.setFont(font) message = QLabel() if with_accounts: text = "%s <a href='cmd:add_columns'>%s</a>" % ( i18n.get("you_have_accounts_registered"), i18n.get("add_some_columns"), ) else: text = "<a href='cmd:add_accounts'>%s</a> %s" % ( i18n.get("add_new_account"), i18n.get("to_start_using_turpial"), ) message.setText(text) message.linkActivated.connect(self.__link_clicked) message.setAlignment(Qt.AlignCenter) message.setWordWrap(True) message.setFont(font2) self.child = QVBoxLayout() self.child.addWidget(logo) self.child.addWidget(welcome) self.child.setSpacing(10) self.child.addWidget(message) self.child.setSpacing(10) self.child.setContentsMargins(30, 0, 30, 60) self.insertLayout(0, self.child) self.is_empty = True def loading(self): if self.child: self.clear_layout(self) image = self.base.load_image("turpial-196.png", True) logo = QLabel() logo.setPixmap(image) logo.setAlignment(Qt.AlignCenter) logo.setContentsMargins(0, 80, 0, 0) appname = QLabel("Turpial 3") if detect_os() == OS_MAC: font = QFont("Maven Pro Light", 28, 0, False) font2 = QFont("Ubuntu", 16, 0, False) else: font = QFont("Maven Pro Light", 18, QFont.Light, False) font2 = QFont("Ubuntu", 12, QFont.Normal, False) appname.setFont(font) welcome = QLabel() welcome.setText(i18n.get("hi_there")) welcome.setAlignment(Qt.AlignCenter) welcome.setFont(font) message = QLabel() message.setText(i18n.get("give_me_a_minute")) message.setAlignment(Qt.AlignCenter) message.setWordWrap(True) message.setFont(font2) loader = BarLoadIndicator() self.child = QVBoxLayout() self.child.addWidget(logo) self.child.addWidget(welcome) self.child.addSpacing(10) self.child.addWidget(message) # self.child.setSpacing(10) self.child.addStretch(1) self.child.addWidget(loader) self.child.setContentsMargins(30, 0, 30, 30) self.insertLayout(0, self.child) self.is_empty = True def error(self): if self.child: self.clear_layout(self) image = self.base.load_image("turpial-196.png", True) logo = QLabel() logo.setPixmap(image) logo.setAlignment(Qt.AlignCenter) logo.setContentsMargins(0, 80, 0, 0) appname = QLabel("Turpial 3") if detect_os() == OS_MAC: font = QFont("Maven Pro Light", 28, 0, False) font2 = QFont("Ubuntu", 16, 0, False) else: font = QFont("Maven Pro Light", 18, QFont.Light, False) font2 = QFont("Ubuntu", 12, QFont.Normal, False) appname.setFont(font) welcome = QLabel() welcome.setText(i18n.get("oh_oh")) welcome.setAlignment(Qt.AlignCenter) welcome.setFont(font) message = QLabel() text = "%s. <a href='cmd:restart'>%s</a>" % (i18n.get("something_terrible_happened"), i18n.get("try_again")) message.setText(text) message.linkActivated.connect(self.__link_clicked) message.setAlignment(Qt.AlignCenter) message.setWordWrap(True) message.setFont(font2) self.child = QVBoxLayout() self.child.addWidget(logo) self.child.addWidget(welcome) self.child.addSpacing(10) self.child.addWidget(message) # self.child.setSpacing(10) self.child.addStretch(1) self.child.setContentsMargins(30, 0, 30, 30) self.insertLayout(0, self.child) self.is_empty = True def normal(self): columns = self.base.core.get_registered_columns() if self.child: self.clear_layout(self) hbox = QHBoxLayout() hbox.setSpacing(0) hbox.setContentsMargins(0, 0, 0, 0) self.columns = {} for column in columns: self.columns[column.id_] = StatusesColumn(self.base, column.id_) hbox.addWidget(self.columns[column.id_], 1) viewport = QWidget() viewport.setLayout(hbox) self.child = QScrollArea() self.child.setWidgetResizable(True) self.child.setWidget(viewport) self.addWidget(self.child, 1) self.is_empty = False def start_updating(self, column_id): return self.columns[column_id].start_updating() def stop_updating(self, column_id, errmsg=None, errtype=None): self.columns[column_id].stop_updating() def is_updating(self, column_id): # return self.columns[column_id].updating return False def update_timestamps(self, column_id): self.columns[column_id].update_timestamps() self.stop_updating(column_id) def update_column(self, column_id, statuses): self.columns[column_id].update_statuses(statuses) self.stop_updating(column_id) self.base.add_extra_friends_from_statuses(statuses) def add_column(self, column_id): if self.is_empty: self.normal() else: viewport = self.child.widget() hbox = viewport.layout() self.columns[column_id] = StatusesColumn(self.base, column_id) hbox.addWidget(self.columns[column_id], 1) def remove_column(self, column_id): self.columns[column_id].deleteLater() del self.columns[column_id] def mark_status_as_favorite(self, status_id): for id_, column in self.columns.iteritems(): column.mark_status_as_favorite(status_id) column.release_status(status_id) def unmark_status_as_favorite(self, status_id): for id_, column in self.columns.iteritems(): column.unmark_status_as_favorite(status_id) column.release_status(status_id) def mark_status_as_repeated(self, status_id): for id_, column in self.columns.iteritems(): column.mark_status_as_repeated(status_id) column.release_status(status_id) def remove_status(self, status_id): for id_, column in self.columns.iteritems(): column.remove_status(status_id) def update_conversation(self, status, column_id, status_root_id): for id_, column in self.columns.iteritems(): if id_ == column_id: column.update_conversation(status, status_root_id) def error_loading_conversation(self, column_id, status_root_id): for id_, column in self.columns.iteritems(): if id_ == column_id: column.error_in_conversation(status_root_id) self.notify_error(column_id, self.base.random_id(), i18n.get("error_loading_conversation")) def error_updating_column(self, column_id): self.stop_updating(column_id) self.notify_error(column_id, self.base.random_id(), i18n.get("error_updating_column")) def error_repeating_status(self, column_id, status_id): for id_, column in self.columns.iteritems(): column.release_status(status_id) self.notify_error(column_id, status_id, i18n.get("error_repeating_status")) def error_deleting_status(self, column_id, status_id): for id_, column in self.columns.iteritems(): column.release_status(status_id) self.notify_error(column_id, status_id, i18n.get("error_deleting_status")) def error_marking_status_as_favorite(self, column_id, status_id): for id_, column in self.columns.iteritems(): column.release_status(status_id) self.notify_error(column_id, status_id, i18n.get("error_marking_status_as_favorite")) def error_unmarking_status_as_favorite(self, column_id, status_id): for id_, column in self.columns.iteritems(): column.release_status(status_id) self.notify_error(column_id, status_id, i18n.get("error_unmarking_status_as_favorite")) def notify_error(self, column_id, id_, message): self.columns[str(column_id)].notify_error(id_, message) def notify_success(self, column_id, id_, message): self.columns[str(column_id)].notify_success(id_, message) def notify_warning(self, column_id, id_, message): self.columns[str(column_id)].notify_warning(id_, message) def notify_info(self, column_id, id_, message): self.columns[str(column_id)].notify_info(id_, message)
class Container(QVBoxLayout): def __init__(self, base): QVBoxLayout.__init__(self) self.base = base self.child = None self.columns = {} self.is_empty = None self.loading() def __link_clicked(self, url): if url == 'cmd:add_columns': self.base.show_column_menu(QCursor.pos()) elif url == 'cmd:add_accounts': self.base.show_accounts_dialog() elif url == 'cmd:restart': self.base.restart() def clear_layout(self, layout): if layout is not None: while layout.count(): item = layout.takeAt(0) widget = item.widget() if widget is not None: widget.deleteLater() else: self.clear_layout(item.layout()) def empty(self, with_accounts=None): if self.child: self.clear_layout(self) image = self.base.load_image('turpial-196.png', True) logo = QLabel() logo.setPixmap(image) logo.setAlignment(Qt.AlignCenter) logo.setContentsMargins(0, 80, 0, 0) appname = QLabel('Turpial 3') if detect_os() == OS_MAC: font = QFont('Maven Pro Light', 28, 0, False) font2 = QFont('Ubuntu', 16, 0, False) else: font = QFont('Maven Pro Light', 18, QFont.Light, False) font2 = QFont('Ubuntu', 12, QFont.Normal, False) appname.setFont(font) welcome = QLabel() welcome.setText(i18n.get('welcome')) welcome.setAlignment(Qt.AlignCenter) welcome.setFont(font) message = QLabel() if with_accounts: text = "%s <a href='cmd:add_columns'>%s</a>" % (i18n.get( 'you_have_accounts_registered'), i18n.get('add_some_columns')) else: text = "<a href='cmd:add_accounts'>%s</a> %s" % (i18n.get( 'add_new_account'), i18n.get('to_start_using_turpial')) message.setText(text) message.linkActivated.connect(self.__link_clicked) message.setAlignment(Qt.AlignCenter) message.setWordWrap(True) message.setFont(font2) self.child = QVBoxLayout() self.child.addWidget(logo) self.child.addWidget(welcome) self.child.setSpacing(10) self.child.addWidget(message) self.child.setSpacing(10) self.child.setContentsMargins(30, 0, 30, 60) self.insertLayout(0, self.child) self.is_empty = True def loading(self): if self.child: self.clear_layout(self) image = self.base.load_image('turpial-196.png', True) logo = QLabel() logo.setPixmap(image) logo.setAlignment(Qt.AlignCenter) logo.setContentsMargins(0, 80, 0, 0) appname = QLabel('Turpial 3') if detect_os() == OS_MAC: font = QFont('Maven Pro Light', 28, 0, False) font2 = QFont('Ubuntu', 16, 0, False) else: font = QFont('Maven Pro Light', 18, QFont.Light, False) font2 = QFont('Ubuntu', 12, QFont.Normal, False) appname.setFont(font) welcome = QLabel() welcome.setText(i18n.get('hi_there')) welcome.setAlignment(Qt.AlignCenter) welcome.setFont(font) message = QLabel() message.setText(i18n.get('give_me_a_minute')) message.setAlignment(Qt.AlignCenter) message.setWordWrap(True) message.setFont(font2) loader = BarLoadIndicator() self.child = QVBoxLayout() self.child.addWidget(logo) self.child.addWidget(welcome) self.child.addSpacing(10) self.child.addWidget(message) #self.child.setSpacing(10) self.child.addStretch(1) self.child.addWidget(loader) self.child.setContentsMargins(30, 0, 30, 30) self.insertLayout(0, self.child) self.is_empty = True def error(self): if self.child: self.clear_layout(self) image = self.base.load_image('turpial-196.png', True) logo = QLabel() logo.setPixmap(image) logo.setAlignment(Qt.AlignCenter) logo.setContentsMargins(0, 80, 0, 0) appname = QLabel('Turpial 3') if detect_os() == OS_MAC: font = QFont('Maven Pro Light', 28, 0, False) font2 = QFont('Ubuntu', 16, 0, False) else: font = QFont('Maven Pro Light', 18, QFont.Light, False) font2 = QFont('Ubuntu', 12, QFont.Normal, False) appname.setFont(font) welcome = QLabel() welcome.setText(i18n.get('oh_oh')) welcome.setAlignment(Qt.AlignCenter) welcome.setFont(font) message = QLabel() text = "%s. <a href='cmd:restart'>%s</a>" % ( i18n.get('something_terrible_happened'), i18n.get('try_again')) message.setText(text) message.linkActivated.connect(self.__link_clicked) message.setAlignment(Qt.AlignCenter) message.setWordWrap(True) message.setFont(font2) self.child = QVBoxLayout() self.child.addWidget(logo) self.child.addWidget(welcome) self.child.addSpacing(10) self.child.addWidget(message) #self.child.setSpacing(10) self.child.addStretch(1) self.child.setContentsMargins(30, 0, 30, 30) self.insertLayout(0, self.child) self.is_empty = True def normal(self): columns = self.base.core.get_registered_columns() if self.child: self.clear_layout(self) hbox = QHBoxLayout() hbox.setSpacing(0) hbox.setContentsMargins(0, 0, 0, 0) self.columns = {} for column in columns: self.columns[column.id_] = StatusesColumn(self.base, column.id_) hbox.addWidget(self.columns[column.id_], 1) viewport = QWidget() viewport.setLayout(hbox) self.child = QScrollArea() self.child.setWidgetResizable(True) self.child.setWidget(viewport) self.addWidget(self.child, 1) self.is_empty = False def start_updating(self, column_id): return self.columns[column_id].start_updating() def stop_updating(self, column_id, errmsg=None, errtype=None): self.columns[column_id].stop_updating() def is_updating(self, column_id): #return self.columns[column_id].updating return False def update_timestamps(self, column_id): self.columns[column_id].update_timestamps() self.stop_updating(column_id) def update_column(self, column_id, statuses): self.columns[column_id].update_statuses(statuses) self.stop_updating(column_id) self.base.add_extra_friends_from_statuses(statuses) def add_column(self, column_id): if self.is_empty: self.normal() else: viewport = self.child.widget() hbox = viewport.layout() self.columns[column_id] = StatusesColumn(self.base, column_id) hbox.addWidget(self.columns[column_id], 1) def remove_column(self, column_id): self.columns[column_id].deleteLater() del self.columns[column_id] def mark_status_as_favorite(self, status_id): for id_, column in self.columns.iteritems(): column.mark_status_as_favorite(status_id) column.release_status(status_id) def unmark_status_as_favorite(self, status_id): for id_, column in self.columns.iteritems(): column.unmark_status_as_favorite(status_id) column.release_status(status_id) def mark_status_as_repeated(self, status_id): for id_, column in self.columns.iteritems(): column.mark_status_as_repeated(status_id) column.release_status(status_id) def remove_status(self, status_id): for id_, column in self.columns.iteritems(): column.remove_status(status_id) def update_conversation(self, status, column_id, status_root_id): for id_, column in self.columns.iteritems(): if id_ == column_id: column.update_conversation(status, status_root_id) def error_loading_conversation(self, column_id, status_root_id): for id_, column in self.columns.iteritems(): if id_ == column_id: column.error_in_conversation(status_root_id) self.notify_error(column_id, self.base.random_id(), i18n.get('error_loading_conversation')) def error_updating_column(self, column_id): self.stop_updating(column_id) self.notify_error(column_id, self.base.random_id(), i18n.get('error_updating_column')) def error_repeating_status(self, column_id, status_id): for id_, column in self.columns.iteritems(): column.release_status(status_id) self.notify_error(column_id, status_id, i18n.get('error_repeating_status')) def error_deleting_status(self, column_id, status_id): for id_, column in self.columns.iteritems(): column.release_status(status_id) self.notify_error(column_id, status_id, i18n.get('error_deleting_status')) def error_marking_status_as_favorite(self, column_id, status_id): for id_, column in self.columns.iteritems(): column.release_status(status_id) self.notify_error(column_id, status_id, i18n.get('error_marking_status_as_favorite')) def error_unmarking_status_as_favorite(self, column_id, status_id): for id_, column in self.columns.iteritems(): column.release_status(status_id) self.notify_error(column_id, status_id, i18n.get('error_unmarking_status_as_favorite')) def notify_error(self, column_id, id_, message): self.columns[str(column_id)].notify_error(id_, message) def notify_success(self, column_id, id_, message): self.columns[str(column_id)].notify_success(id_, message) def notify_warning(self, column_id, id_, message): self.columns[str(column_id)].notify_warning(id_, message) def notify_info(self, column_id, id_, message): self.columns[str(column_id)].notify_info(id_, message)
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()