def __init__(self, base): QWidget.__init__(self) self.base = base self.showed = False self.setFixedSize(500, 120) self.text_edit = CompletionTextEdit() self.upload_button = ImageButton(base, 'action-upload.png', i18n.get('upload_image')) self.short_button = ImageButton(base, 'action-shorten.png', i18n.get('short_urls')) font = QFont() font.setPointSize(18) font.setBold(True) self.char_count = QLabel('140') self.char_count.setFont(font) self.update_button = QPushButton(i18n.get('update')) self.update_button.setToolTip(self.base.get_shortcut_string('Enter')) self.queue_button = QPushButton(i18n.get('add_to_queue')) self.queue_button.setToolTip(self.base.get_shortcut_string('P')) self.accounts_combo = QComboBox() buttons = QHBoxLayout() buttons.setSpacing(4) buttons.addWidget(self.accounts_combo) buttons.addWidget(self.upload_button) buttons.addWidget(self.short_button) buttons.addStretch(0) buttons.addWidget(self.char_count) buttons.addWidget(self.queue_button) buttons.addWidget(self.update_button) self.loader = BarLoadIndicator() self.error_message = ErrorLabel() self.update_button.clicked.connect(self.__update_status) self.queue_button.clicked.connect(self.__queue_status) self.short_button.clicked.connect(self.__short_urls) self.upload_button.clicked.connect(self.__upload_image) self.text_edit.textChanged.connect(self.__update_count) self.text_edit.quit.connect(self.closeEvent) self.text_edit.activated.connect(self.__update_status) self.text_edit.enqueued.connect(self.__queue_status) layout = QVBoxLayout() layout.setSpacing(0) layout.addWidget(self.text_edit) layout.addWidget(self.loader) layout.addSpacing(5) layout.addWidget(self.error_message) layout.addLayout(buttons) layout.setContentsMargins(5, 5, 5, 5) self.setLayout(layout) self.__clear()
def __build_header(self, column_id): self.set_column_id(column_id) username = get_username_from(self.account_id) column_slug = get_column_slug_from(column_id) column_slug = column_slug.replace('%23', '#') column_slug = column_slug.replace('%40', '@') #font = QFont('Titillium Web', 18, QFont.Normal, False) # This is to handle the 96dpi vs 72dpi screen resolutions on Mac vs the world if detect_os() == OS_MAC: font = QFont('Maven Pro Light', 25, 0, False) font2 = QFont('Monda', 14, 0, False) else: font = QFont('Maven Pro Light', 16, QFont.Light, False) font2 = QFont('Monda', 10, QFont.Light, False) bg_style = "background-color: %s; color: %s;" % (self.base.bgcolor, self.base.fgcolor) label = "%s : %s" % (username, column_slug) caption = QLabel(username) caption.setStyleSheet("QLabel { %s }" % bg_style) caption.setFont(font) caption2 = QLabel(column_slug) caption2.setStyleSheet("QLabel { %s }" % bg_style) caption2.setFont(font2) caption2.setAlignment(Qt.AlignLeft | Qt.AlignBottom) caption_box = QHBoxLayout() caption_box.setSpacing(8) caption_box.addWidget(caption) caption_box.addWidget(caption2) caption_box.addStretch(1) close_button = ImageButton(self.base, 'action-delete-shadowed.png', i18n.get('delete_column')) close_button.clicked.connect(self.__delete_column) close_button.setStyleSheet("QToolButton { %s border: 0px solid %s;}" % (bg_style, self.base.bgcolor)) header_layout = QHBoxLayout() header_layout.addLayout(caption_box, 1) header_layout.addWidget(close_button) header = QWidget() header.setStyleSheet("QWidget { %s }" % bg_style) header.setLayout(header_layout) return header
def __init__(self, base): QStatusBar.__init__(self) self.base = base self.status = self.LOADING style = "background-color: %s; border: 0px solid %s;" % (self.base.bgcolor, self.base.bgcolor) self.updates_button = ImageButton(base, 'dock-updates.png', i18n.get('update_status')) self.messages_button = ImageButton(base, 'dock-messages.png', i18n.get('send_direct_message')) self.search_button = ImageButton(base, 'dock-search.png', i18n.get('search')) self.settings_button = ImageButton(base, 'dock-preferences.png', i18n.get('settings')) self.updates_button.clicked.connect(self.__updates_clicked) self.messages_button.clicked.connect(self.__messages_clicked) self.search_button.clicked.connect(self.__search_clicked) self.settings_button.clicked.connect(self.__settings_clicked) separator = QWidget() separator.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) toolbar = QToolBar() toolbar.addWidget(self.settings_button) toolbar.addWidget(separator) toolbar.addWidget(self.search_button) toolbar.addWidget(self.messages_button) toolbar.addWidget(self.updates_button) toolbar.setMinimumHeight(30) toolbar.setContentsMargins(0, 0, 0, 0) toolbar.setStyleSheet("QToolBar { %s }; QToolButton { %s opacity: 128; }; QToolButton:hover { %s opacity: 255;}" % (style, style, style)) self.addPermanentWidget(toolbar, 1) self.setSizeGripEnabled(False) self.setContentsMargins(0, 0, 0, 0) self.setStyleSheet("QStatusBar { %s }" % style) self.loading()
def __init__(self, base): QStatusBar.__init__(self) self.base = base self.status = self.LOADING style = "background-color: %s; border: 0px solid %s;" % ( self.base.bgcolor, self.base.bgcolor) self.updates_button = ImageButton(base, 'dock-updates.png', i18n.get('update_status')) self.messages_button = ImageButton(base, 'dock-messages.png', i18n.get('send_direct_message')) self.search_button = ImageButton(base, 'dock-search.png', i18n.get('search')) self.settings_button = ImageButton(base, 'dock-preferences.png', i18n.get('settings')) self.updates_button.clicked.connect(self.__updates_clicked) self.messages_button.clicked.connect(self.__messages_clicked) self.search_button.clicked.connect(self.__search_clicked) self.settings_button.clicked.connect(self.__settings_clicked) separator = QWidget() separator.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) toolbar = QToolBar() toolbar.addWidget(self.settings_button) toolbar.addWidget(separator) toolbar.addWidget(self.search_button) toolbar.addWidget(self.messages_button) toolbar.addWidget(self.updates_button) toolbar.setMinimumHeight(30) toolbar.setContentsMargins(0, 0, 0, 0) toolbar.setStyleSheet( "QToolBar { %s }; QToolButton { %s opacity: 128; }; QToolButton:hover { %s opacity: 255;}" % (style, style, style)) self.addPermanentWidget(toolbar, 1) self.setSizeGripEnabled(False) self.setContentsMargins(0, 0, 0, 0) self.setStyleSheet("QStatusBar { %s }" % style) self.loading()
class Dock(QStatusBar): accounts_clicked = pyqtSignal() columns_clicked = pyqtSignal(QPoint) search_clicked = pyqtSignal() updates_clicked = pyqtSignal() messages_clicked = pyqtSignal() queue_clicked = pyqtSignal() filters_clicked = pyqtSignal() preferences_clicked = pyqtSignal() LOADING = -1 EMPTY = 0 WITH_ACCOUNTS = 1 NORMAL = 2 def __init__(self, base): QStatusBar.__init__(self) self.base = base self.status = self.LOADING style = "background-color: %s; border: 0px solid %s;" % (self.base.bgcolor, self.base.bgcolor) self.updates_button = ImageButton(base, 'dock-updates.png', i18n.get('update_status')) self.messages_button = ImageButton(base, 'dock-messages.png', i18n.get('send_direct_message')) self.search_button = ImageButton(base, 'dock-search.png', i18n.get('search')) self.settings_button = ImageButton(base, 'dock-preferences.png', i18n.get('settings')) self.updates_button.clicked.connect(self.__updates_clicked) self.messages_button.clicked.connect(self.__messages_clicked) self.search_button.clicked.connect(self.__search_clicked) self.settings_button.clicked.connect(self.__settings_clicked) separator = QWidget() separator.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) toolbar = QToolBar() toolbar.addWidget(self.settings_button) toolbar.addWidget(separator) toolbar.addWidget(self.search_button) toolbar.addWidget(self.messages_button) toolbar.addWidget(self.updates_button) toolbar.setMinimumHeight(30) toolbar.setContentsMargins(0, 0, 0, 0) toolbar.setStyleSheet("QToolBar { %s }; QToolButton { %s opacity: 128; }; QToolButton:hover { %s opacity: 255;}" % (style, style, style)) self.addPermanentWidget(toolbar, 1) self.setSizeGripEnabled(False) self.setContentsMargins(0, 0, 0, 0) self.setStyleSheet("QStatusBar { %s }" % style) self.loading() def __accounts_clicked(self): self.accounts_clicked.emit() def __columns_clicked(self): self.columns_clicked.emit(QCursor.pos()) def __search_clicked(self): self.search_clicked.emit() def __updates_clicked(self): self.updates_clicked.emit() def __messages_clicked(self): self.messages_clicked.emit() def __queue_clicked(self): self.queue_clicked.emit() def __filters_clicked(self): self.filters_clicked.emit() def __preferences_clicked(self): self.preferences_clicked.emit() def __about_clicked(self): self.base.show_about_dialog() def __settings_clicked(self): self.settings_menu = QMenu(self) accounts = QAction(i18n.get('accounts'), self) accounts.triggered.connect(partial(self.__accounts_clicked)) queue = QAction(i18n.get('messages_queue'), self) queue.triggered.connect(partial(self.__queue_clicked)) columns = QAction(i18n.get('columns'), self) filters = QAction(i18n.get('filters'), self) filters.triggered.connect(partial(self.__filters_clicked)) preferences = QAction(i18n.get('preferences'), self) preferences.triggered.connect(partial(self.__preferences_clicked)) about_turpial = QAction(i18n.get('about_turpial'), self) about_turpial.triggered.connect(partial(self.__about_clicked)) if self.status > self.EMPTY: columns_menu = self.base.build_columns_menu() columns.setMenu(columns_menu) elif self.status == self.EMPTY: queue.setEnabled(False) columns.setEnabled(False) elif self.status == self.LOADING: accounts.setEnabled(False) queue.setEnabled(False) columns.setEnabled(False) filters.setEnabled(False) preferences.setEnabled(False) self.settings_menu.addAction(accounts) self.settings_menu.addAction(columns) #self.settings_menu.addAction(filters) self.settings_menu.addAction(queue) self.settings_menu.addSeparator() self.settings_menu.addAction(preferences) self.settings_menu.addSeparator() self.settings_menu.addAction(about_turpial) self.settings_menu.exec_(QCursor.pos()) def loading(self): self.updates_button.setEnabled(False) self.messages_button.setEnabled(False) self.search_button.setEnabled(False) self.status = self.LOADING def empty(self, with_accounts=None): self.updates_button.setEnabled(False) self.messages_button.setEnabled(False) self.search_button.setEnabled(False) if with_accounts: self.status = self.WITH_ACCOUNTS else: self.status = self.EMPTY def normal(self): self.updates_button.setEnabled(True) self.messages_button.setEnabled(True) self.search_button.setEnabled(True) self.status = self.NORMAL
def __init__(self, base): Window.__init__(self, base, i18n.get('user_profile')) self.account_id = None self.setFixedSize(380, 450) self.username = QLabel('') self.username.setTextFormat(Qt.RichText) self.fullname = QLabel('') self.options = ImageButton(base, 'action-status-menu.png', i18n.get('')) self.options.clicked.connect(self.__options_clicked) self.verified_icon = QLabel() self.verified_icon.setPixmap(base.load_image('mark-verified.png', True)) self.protected_icon = QLabel() self.protected_icon.setPixmap( base.load_image('mark-protected.png', True)) self.avatar = ClickableLabel() self.avatar.setPixmap(base.load_image('unknown.png', True)) self.avatar.clicked.connect(self.__show_avatar) self.you_label = QLabel(i18n.get('this_is_you')) self.you_label.setVisible(False) info_line1 = QHBoxLayout() info_line1.setSpacing(5) info_line1.addWidget(self.username) info_line1.addSpacing(5) info_line1.addWidget(self.verified_icon) info_line1.addWidget(self.protected_icon) info_line1.addStretch(0) info_line2 = QHBoxLayout() info_line2.addWidget(self.fullname, 1) info_line2.addWidget(self.options) info_line2.addWidget(self.you_label) user_info = QVBoxLayout() user_info.addLayout(info_line1) user_info.addLayout(info_line2) self.loader = BarLoadIndicator() self.loader.setVisible(False) self.error_message = ErrorLabel() self.error_message.setVisible(False) header = QHBoxLayout() header.setContentsMargins(5, 10, 5, 0) header.addWidget(self.avatar) header.addSpacing(10) header.addLayout(user_info) # User Info self.bio = UserField(base, 'bio', 'icon-bio.png') self.bio.set_word_wrap(True) self.bio.set_info('') self.location = UserField(base, 'location', 'icon-location.png') self.location.set_info('') self.web = UserField(base, 'web', 'icon-home.png') self.web.set_info('') self.tweets = StatInfoBox('tweets', '') self.following = StatInfoBox('following', '') self.followers = StatInfoBox('followers', '') self.favorites = StatInfoBox('favorites', '') footer_layout = QHBoxLayout() footer_layout.setContentsMargins(0, 5, 0, 10) footer_layout.setSpacing(0) footer_layout.addLayout(self.tweets) footer_layout.addWidget(VLine()) footer_layout.addLayout(self.following) footer_layout.addWidget(VLine()) footer_layout.addLayout(self.followers) footer_layout.addWidget(VLine()) footer_layout.addLayout(self.favorites) footer = QWidget() footer.setLayout(footer_layout) footer.setStyleSheet( "QWidget { background-color: #333; color: white; }") body_layout = QVBoxLayout() body_layout.setSpacing(15) body_layout.setContentsMargins(0, 0, 0, 0) body_layout.addLayout(self.bio) body_layout.addLayout(self.location) body_layout.addLayout(self.web) body_layout.addWidget(footer) body = QWidget() body.setLayout(body_layout) self.last_statuses = StatusesColumn(self.base, None, False) self.tabs = QTabWidget(self) self.tabs.setTabsClosable(False) self.tabs.setMovable(False) self.tabs.addTab(body, i18n.get('info')) self.tabs.addTab(self.last_statuses, i18n.get('recent')) self.hline = HLine() self.hline.setMinimumHeight(2) layout = QVBoxLayout() layout.addLayout(header) layout.addSpacing(10) layout.addWidget(self.hline) layout.addWidget(self.loader) layout.addWidget(self.error_message) layout.addSpacing(10) layout.addWidget(self.tabs, 1) layout.setSpacing(0) layout.setContentsMargins(5, 5, 5, 5) self.setLayout(layout) self.__clear()
class ProfileDialog(Window): options_clicked = pyqtSignal(QPoint, object) def __init__(self, base): Window.__init__(self, base, i18n.get('user_profile')) self.account_id = None self.setFixedSize(380, 450) self.username = QLabel('') self.username.setTextFormat(Qt.RichText) self.fullname = QLabel('') self.options = ImageButton(base, 'action-status-menu.png', i18n.get('')) self.options.clicked.connect(self.__options_clicked) self.verified_icon = QLabel() self.verified_icon.setPixmap(base.load_image('mark-verified.png', True)) self.protected_icon = QLabel() self.protected_icon.setPixmap( base.load_image('mark-protected.png', True)) self.avatar = ClickableLabel() self.avatar.setPixmap(base.load_image('unknown.png', True)) self.avatar.clicked.connect(self.__show_avatar) self.you_label = QLabel(i18n.get('this_is_you')) self.you_label.setVisible(False) info_line1 = QHBoxLayout() info_line1.setSpacing(5) info_line1.addWidget(self.username) info_line1.addSpacing(5) info_line1.addWidget(self.verified_icon) info_line1.addWidget(self.protected_icon) info_line1.addStretch(0) info_line2 = QHBoxLayout() info_line2.addWidget(self.fullname, 1) info_line2.addWidget(self.options) info_line2.addWidget(self.you_label) user_info = QVBoxLayout() user_info.addLayout(info_line1) user_info.addLayout(info_line2) self.loader = BarLoadIndicator() self.loader.setVisible(False) self.error_message = ErrorLabel() self.error_message.setVisible(False) header = QHBoxLayout() header.setContentsMargins(5, 10, 5, 0) header.addWidget(self.avatar) header.addSpacing(10) header.addLayout(user_info) # User Info self.bio = UserField(base, 'bio', 'icon-bio.png') self.bio.set_word_wrap(True) self.bio.set_info('') self.location = UserField(base, 'location', 'icon-location.png') self.location.set_info('') self.web = UserField(base, 'web', 'icon-home.png') self.web.set_info('') self.tweets = StatInfoBox('tweets', '') self.following = StatInfoBox('following', '') self.followers = StatInfoBox('followers', '') self.favorites = StatInfoBox('favorites', '') footer_layout = QHBoxLayout() footer_layout.setContentsMargins(0, 5, 0, 10) footer_layout.setSpacing(0) footer_layout.addLayout(self.tweets) footer_layout.addWidget(VLine()) footer_layout.addLayout(self.following) footer_layout.addWidget(VLine()) footer_layout.addLayout(self.followers) footer_layout.addWidget(VLine()) footer_layout.addLayout(self.favorites) footer = QWidget() footer.setLayout(footer_layout) footer.setStyleSheet( "QWidget { background-color: #333; color: white; }") body_layout = QVBoxLayout() body_layout.setSpacing(15) body_layout.setContentsMargins(0, 0, 0, 0) body_layout.addLayout(self.bio) body_layout.addLayout(self.location) body_layout.addLayout(self.web) body_layout.addWidget(footer) body = QWidget() body.setLayout(body_layout) self.last_statuses = StatusesColumn(self.base, None, False) self.tabs = QTabWidget(self) self.tabs.setTabsClosable(False) self.tabs.setMovable(False) self.tabs.addTab(body, i18n.get('info')) self.tabs.addTab(self.last_statuses, i18n.get('recent')) self.hline = HLine() self.hline.setMinimumHeight(2) layout = QVBoxLayout() layout.addLayout(header) layout.addSpacing(10) layout.addWidget(self.hline) layout.addWidget(self.loader) layout.addWidget(self.error_message) layout.addSpacing(10) layout.addWidget(self.tabs, 1) layout.setSpacing(0) layout.setContentsMargins(5, 5, 5, 5) self.setLayout(layout) self.__clear() def __clear(self): self.profile = None self.showed = False self.account_id = None self.verified_icon.setVisible(False) self.protected_icon.setVisible(False) self.you_label.setVisible(False) self.options.setVisible(False) self.loader.setVisible(False) self.error_message.setVisible(False) self.avatar.setPixmap(self.base.load_image('unknown.png', True)) self.bio.set_info('') self.location.set_info('') self.web.set_info('') self.tweets.set_value('') self.following.set_value('') self.followers.set_value('') self.favorites.set_value('') self.last_statuses.id_ = None self.last_statuses.clear() self.tabs.setCurrentIndex(0) def __options_clicked(self): self.options_clicked.emit(QCursor.pos(), self.profile) def __show_avatar(self): self.base.show_profile_image(self.account_id, self.profile.username) def __on_timeout(self): self.error_message.setText('') self.error_message.setVisible(False) def closeEvent(self, event=None): if event: event.ignore() self.__clear() self.hide() def start_loading(self, profile_username): self.__clear() self.hline.setVisible(False) self.loader.setVisible(True) self.username.setText('<b>%s</b>' % profile_username) self.fullname.setText(i18n.get('loading')) self.show() self.raise_() self.showed = True def loading_finished(self, profile, account_id): self.profile = profile self.account_id = str(account_id) self.loader.setVisible(False) self.hline.setVisible(False) self.username.setText('<b>%s</b>' % profile.username) self.fullname.setText(profile.fullname) if get_username_from(account_id) == profile.username: self.you_label.setVisible(True) self.options.setVisible(False) else: self.you_label.setVisible(False) self.options.setVisible(True) self.verified_icon.setVisible(profile.verified) self.protected_icon.setVisible(profile.protected) self.avatar.setPixmap(self.base.load_image('unknown.png', True)) self.bio.set_info(profile.bio) self.location.set_info(profile.location) self.web.set_info(profile.url) self.tweets.set_value(str(profile.statuses_count)) self.following.set_value(str(profile.friends_count)) self.followers.set_value(str(profile.followers_count)) self.favorites.set_value(str(profile.favorites_count)) column_id = "%s-profile_recent" % self.account_id self.last_statuses.set_column_id(column_id) self.last_statuses.update_statuses(profile.recent_updates) self.show() self.raise_() def is_for_profile(self, column_id): if column_id.find('profile_recent') > 0: return True return False def update_avatar(self, image_path, username): if username != self.profile.username or not self.showed: return self.avatar.setPixmap(self.base.load_image(image_path, True)) def update_following(self, username, following): if username != self.profile.username or not self.showed: return self.profile.following = following def error(self, message): self.loader.setVisible(False) self.hline.setVisible(False) self.fullname.setText('') self.error_message.setText(message) self.error_message.setVisible(True) self.timer = QTimer() self.timer.timeout.connect(self.__on_timeout) self.timer.start(5000) self.show() self.raise_() def error_marking_status_as_favorite(self, status_id): self.last_statuses.release_status(status_id) self.last_statuses.notify_error( status_id, i18n.get('error_marking_status_as_favorite')) def error_unmarking_status_as_favorite(self, status_id): self.last_statuses.release_status(status_id) self.last_statuses.notify_error( status_id, i18n.get('error_unmarking_status_as_favorite')) def error_repeating_status(self, status_id): self.last_statuses.release_status(status_id) self.last_statuses.notify_error(status_id, i18n.get('error_repeating_status')) def error_loading_conversation(self, status_root_id): self.last_statuses.error_in_conversation(status_root_id) self.last_statuses.notify_error(self.base.random_id(), i18n.get('error_loading_conversation'))
class Dock(QStatusBar): accounts_clicked = pyqtSignal() columns_clicked = pyqtSignal(QPoint) search_clicked = pyqtSignal() updates_clicked = pyqtSignal() messages_clicked = pyqtSignal() queue_clicked = pyqtSignal() filters_clicked = pyqtSignal() preferences_clicked = pyqtSignal() LOADING = -1 EMPTY = 0 WITH_ACCOUNTS = 1 NORMAL = 2 def __init__(self, base): QStatusBar.__init__(self) self.base = base self.status = self.LOADING style = "background-color: %s; border: 0px solid %s;" % ( self.base.bgcolor, self.base.bgcolor) self.updates_button = ImageButton(base, 'dock-updates.png', i18n.get('update_status')) self.messages_button = ImageButton(base, 'dock-messages.png', i18n.get('send_direct_message')) self.search_button = ImageButton(base, 'dock-search.png', i18n.get('search')) self.settings_button = ImageButton(base, 'dock-preferences.png', i18n.get('settings')) self.updates_button.clicked.connect(self.__updates_clicked) self.messages_button.clicked.connect(self.__messages_clicked) self.search_button.clicked.connect(self.__search_clicked) self.settings_button.clicked.connect(self.__settings_clicked) separator = QWidget() separator.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) toolbar = QToolBar() toolbar.addWidget(self.settings_button) toolbar.addWidget(separator) toolbar.addWidget(self.search_button) toolbar.addWidget(self.messages_button) toolbar.addWidget(self.updates_button) toolbar.setMinimumHeight(30) toolbar.setContentsMargins(0, 0, 0, 0) toolbar.setStyleSheet( "QToolBar { %s }; QToolButton { %s opacity: 128; }; QToolButton:hover { %s opacity: 255;}" % (style, style, style)) self.addPermanentWidget(toolbar, 1) self.setSizeGripEnabled(False) self.setContentsMargins(0, 0, 0, 0) self.setStyleSheet("QStatusBar { %s }" % style) self.loading() def __accounts_clicked(self): self.accounts_clicked.emit() def __columns_clicked(self): self.columns_clicked.emit(QCursor.pos()) def __search_clicked(self): self.search_clicked.emit() def __updates_clicked(self): self.updates_clicked.emit() def __messages_clicked(self): self.messages_clicked.emit() def __queue_clicked(self): self.queue_clicked.emit() def __filters_clicked(self): self.filters_clicked.emit() def __preferences_clicked(self): self.preferences_clicked.emit() def __about_clicked(self): self.base.show_about_dialog() def __settings_clicked(self): self.settings_menu = QMenu(self) accounts = QAction(i18n.get('accounts'), self) accounts.triggered.connect(partial(self.__accounts_clicked)) queue = QAction(i18n.get('messages_queue'), self) queue.triggered.connect(partial(self.__queue_clicked)) columns = QAction(i18n.get('columns'), self) filters = QAction(i18n.get('filters'), self) filters.triggered.connect(partial(self.__filters_clicked)) preferences = QAction(i18n.get('preferences'), self) preferences.triggered.connect(partial(self.__preferences_clicked)) about_turpial = QAction(i18n.get('about_turpial'), self) about_turpial.triggered.connect(partial(self.__about_clicked)) if self.status > self.EMPTY: columns_menu = self.base.build_columns_menu() columns.setMenu(columns_menu) elif self.status == self.EMPTY: queue.setEnabled(False) columns.setEnabled(False) elif self.status == self.LOADING: accounts.setEnabled(False) queue.setEnabled(False) columns.setEnabled(False) filters.setEnabled(False) preferences.setEnabled(False) self.settings_menu.addAction(accounts) self.settings_menu.addAction(columns) #self.settings_menu.addAction(filters) self.settings_menu.addAction(queue) self.settings_menu.addSeparator() self.settings_menu.addAction(preferences) self.settings_menu.addSeparator() self.settings_menu.addAction(about_turpial) self.settings_menu.exec_(QCursor.pos()) def loading(self): self.updates_button.setEnabled(False) self.messages_button.setEnabled(False) self.search_button.setEnabled(False) self.status = self.LOADING def empty(self, with_accounts=None): self.updates_button.setEnabled(False) self.messages_button.setEnabled(False) self.search_button.setEnabled(False) if with_accounts: self.status = self.WITH_ACCOUNTS else: self.status = self.EMPTY def normal(self): self.updates_button.setEnabled(True) self.messages_button.setEnabled(True) self.search_button.setEnabled(True) self.status = self.NORMAL
class UpdateBox(QWidget): def __init__(self, base): QWidget.__init__(self) self.base = base self.showed = False self.setFixedSize(500, 120) self.text_edit = CompletionTextEdit() self.upload_button = ImageButton(base, 'action-upload.png', i18n.get('upload_image')) self.short_button = ImageButton(base, 'action-shorten.png', i18n.get('short_urls')) font = QFont() font.setPointSize(18) font.setBold(True) self.char_count = QLabel('140') self.char_count.setFont(font) self.update_button = QPushButton(i18n.get('update')) self.update_button.setToolTip(self.base.get_shortcut_string('Enter')) self.queue_button = QPushButton(i18n.get('add_to_queue')) self.queue_button.setToolTip(self.base.get_shortcut_string('P')) self.accounts_combo = QComboBox() buttons = QHBoxLayout() buttons.setSpacing(4) buttons.addWidget(self.accounts_combo) buttons.addWidget(self.upload_button) buttons.addWidget(self.short_button) buttons.addStretch(0) buttons.addWidget(self.char_count) buttons.addWidget(self.queue_button) buttons.addWidget(self.update_button) self.loader = BarLoadIndicator() self.error_message = ErrorLabel() self.update_button.clicked.connect(self.__update_status) self.queue_button.clicked.connect(self.__queue_status) self.short_button.clicked.connect(self.__short_urls) self.upload_button.clicked.connect(self.__upload_image) self.text_edit.textChanged.connect(self.__update_count) self.text_edit.quit.connect(self.closeEvent) self.text_edit.activated.connect(self.__update_status) self.text_edit.enqueued.connect(self.__queue_status) layout = QVBoxLayout() layout.setSpacing(0) layout.addWidget(self.text_edit) layout.addWidget(self.loader) layout.addSpacing(5) layout.addWidget(self.error_message) layout.addLayout(buttons) layout.setContentsMargins(5, 5, 5, 5) self.setLayout(layout) self.__clear() def __count_chars(self): message = self.text_edit.toPlainText() urls = [str(url) for url in get_urls(message) if len(url) > 23] for url in urls: message = message.replace(url, '0' * 23) return MAX_CHAR - len(message) def __update_count(self): remaining_chars = self.__count_chars() if remaining_chars <= 10: self.char_count.setStyleSheet("QLabel { color: #D40D12 }") elif remaining_chars > 10 and remaining_chars <= 20: self.char_count.setStyleSheet("QLabel { color: #D4790D }") else: self.char_count.setStyleSheet("QLabel { color: #000000 }") self.char_count.setText(str(remaining_chars)) def __validate(self, message, accounts, index): if len(message) == 0: self.error(i18n.get('you_can_not_submit_an_empty_message')) return False if index == 0 and len(accounts) > 1: self.error(i18n.get('select_an_account_before_post')) return False if self.__count_chars() < 0: self.error(i18n.get('message_too_long')) return False return True def __short_urls(self): self.enable(False) message = unicode(self.text_edit.toPlainText()) self.base.short_urls(message) def __upload_image(self): index = self.accounts_combo.currentIndex() accounts = self.base.core.get_registered_accounts() if index == 0 and len(accounts) > 1: self.error(i18n.get('select_an_account_before_post')) return False account_id = str(self.accounts_combo.itemData(index).toPyObject()) filename = str(QFileDialog.getOpenFileName(self, i18n.get('upload_image'), self.base.home_path)) if filename != '': self.enable(False) self.base.upload_media(account_id, filename) def __update_status(self): index = self.accounts_combo.currentIndex() accounts = self.base.core.get_registered_accounts() message = unicode(self.text_edit.toPlainText()) if not self.__validate(message, accounts, index): self.enable(True) return self.enable(False) account_id = str(self.accounts_combo.itemData(index).toPyObject()) if self.direct_message_to: self.base.send_direct_message(account_id, self.direct_message_to, message) else: if account_id == 'broadcast': self.base.broadcast_status(message) else: self.base.update_status(account_id, message, self.in_reply_to_id) def __queue_status(self): index = self.accounts_combo.currentIndex() accounts = self.base.core.get_registered_accounts() account_id = str(self.accounts_combo.itemData(index).toPyObject()) message = unicode(self.text_edit.toPlainText()) if not self.__validate(message, accounts, index): self.enable(True) return self.enable(False) self.base.push_status_to_queue(account_id, message) def __clear(self): self.account_id = None self.in_reply_to_id = None self.in_reply_to_user = None self.direct_message_to = None self.quoting = False self.message = None self.cursor_position = None self.text_edit.setText('') self.accounts_combo.setCurrentIndex(0) self.queue_button.setEnabled(True) self.loader.setVisible(False) self.error_message.setVisible(False) self.error_message.setText('') self.enable(True) self.showed = False def __show(self): self.update_friends_list() short_service = self.base.get_shorten_url_service() short_tooltip = "%s (%s)" % (i18n.get('short_url'), short_service) self.short_button.setToolTip(short_tooltip) upload_service = self.base.get_upload_media_service() upload_tooltip = "%s (%s)" % (i18n.get('upload_image'), upload_service) self.upload_button.setToolTip(upload_tooltip) self.accounts_combo.clear() accounts = self.base.core.get_registered_accounts() if len(accounts) > 1: self.accounts_combo.addItem('--', '') for account in accounts: protocol = get_protocol_from(account.id_) icon = QIcon(self.base.get_image_path('%s.png' % protocol)) self.accounts_combo.addItem(icon, get_username_from(account.id_), account.id_) if len(accounts) > 1: icon = QIcon(self.base.get_image_path('action-conversation.png')) self.accounts_combo.addItem(icon, i18n.get('broadcast'), 'broadcast') if self.account_id: index = self.accounts_combo.findData(self.account_id) if index > 0: self.accounts_combo.setCurrentIndex(index) self.accounts_combo.setEnabled(False) if self.message: self.text_edit.setText(self.message) cursor = self.text_edit.textCursor() cursor.movePosition(self.cursor_position, QTextCursor.MoveAnchor) self.text_edit.setTextCursor(cursor) QWidget.show(self) self.showed = True def __on_timeout(self): self.error_message.setText('') self.error_message.setVisible(False) def show(self): if self.showed: return self.raise_() self.setWindowTitle(i18n.get('whats_happening')) self.__show() def show_for_reply(self, account_id, status): if self.showed: return self.raise_() title = "%s @%s" % (i18n.get('reply_to'), status.username) self.setWindowTitle(title) self.account_id = account_id self.in_reply_to_id = status.id_ self.in_reply_to_user = status.username mentions = ' '.join(["@%s" % user for user in status.get_mentions()]) self.message = "%s " % mentions self.cursor_position = QTextCursor.End self.__show() def show_for_send_direct(self, account_id, username): if self.showed: return self.raise_() title = "%s @%s" % (i18n.get('send_message_to'), username) self.setWindowTitle(title) self.account_id = account_id self.direct_message_to = username self.__show() self.queue_button.setEnabled(False) def show_for_reply_direct(self, account_id, status): if self.showed: return self.raise_() title = "%s @%s" % (i18n.get('send_message_to'), status.username) self.setWindowTitle(title) self.account_id = account_id self.direct_message_to = status.username self.__show() self.queue_button.setEnabled(False) def show_for_quote(self, account_id, status): if self.showed: return self.raise_() self.setWindowTitle(i18n.get('quoting')) self.account_id = account_id self.message = " RT @%s %s" % (status.username, status.text) self.cursor_position = QTextCursor.Start self.quoting = True self.__show() self.queue_button.setEnabled(False) def closeEvent(self, event=None): message = unicode(self.text_edit.toPlainText()) if len(message) > 0: confirmation = self.base.show_confirmation_message(i18n.get('confirm_discard'), i18n.get('do_you_want_to_discard_message')) if not confirmation: return if event: event.ignore() self.__clear() self.hide() def enable(self, value): self.text_edit.setEnabled(value) if not self.account_id: self.accounts_combo.setEnabled(value) if self.in_reply_to_id or self.direct_message_to or self.quoting: self.queue_button.setEnabled(False) else: self.queue_button.setEnabled(value) self.upload_button.setEnabled(value) self.short_button.setEnabled(value) self.update_button.setEnabled(value) self.loader.setVisible(not value) def done(self): self.__clear() self.hide() def error(self, message): self.enable(True) self.error_message.setText(message) self.error_message.setVisible(True) self.timer = QTimer() self.timer.timeout.connect(self.__on_timeout) self.timer.start(5000) def after_short_url(self, message): if self.base.is_exception(message): self.error(i18n.get('error_shorting_url')) else: self.text_edit.setText(message) self.enable(True) def after_upload_media(self, media_url): if self.base.is_exception(media_url): self.error(i18n.get('error_uploading_image')) else: text_cursor = self.text_edit.textCursor() text_cursor.select(QTextCursor.WordUnderCursor) if text_cursor.selectedText() != '': media_url = " %s" % media_url text_cursor.clearSelection() text_cursor.insertText(media_url) self.text_edit.setTextCursor(text_cursor) self.enable(True) def update_friends_list(self): completer = QCompleter(self.base.load_friends_list_with_extras()) self.text_edit.setCompleter(completer)
def __init__(self, base): Window.__init__(self, base, i18n.get('user_profile')) self.account_id = None self.setFixedSize(380, 450) self.username = QLabel('') self.username.setTextFormat(Qt.RichText) self.fullname = QLabel('') self.options = ImageButton(base, 'action-status-menu.png', i18n.get('')) self.options.clicked.connect(self.__options_clicked) self.verified_icon = QLabel() self.verified_icon.setPixmap(base.load_image('mark-verified.png', True)) self.protected_icon = QLabel() self.protected_icon.setPixmap(base.load_image('mark-protected.png', True)) self.avatar = ClickableLabel() self.avatar.setPixmap(base.load_image('unknown.png', True)) self.avatar.clicked.connect(self.__show_avatar) self.you_label = QLabel(i18n.get('this_is_you')) self.you_label.setVisible(False) info_line1 = QHBoxLayout() info_line1.setSpacing(5) info_line1.addWidget(self.username) info_line1.addSpacing(5) info_line1.addWidget(self.verified_icon) info_line1.addWidget(self.protected_icon) info_line1.addStretch(0) info_line2 = QHBoxLayout() info_line2.addWidget(self.fullname, 1) info_line2.addWidget(self.options) info_line2.addWidget(self.you_label) user_info = QVBoxLayout() user_info.addLayout(info_line1) user_info.addLayout(info_line2) self.loader = BarLoadIndicator() self.loader.setVisible(False) self.error_message = ErrorLabel() self.error_message.setVisible(False) header = QHBoxLayout() header.setContentsMargins(5, 10, 5, 0) header.addWidget(self.avatar) header.addSpacing(10) header.addLayout(user_info) # User Info self.bio = UserField(base, 'bio', 'icon-bio.png') self.bio.set_word_wrap(True) self.bio.set_info('') self.location = UserField(base, 'location', 'icon-location.png') self.location.set_info('') self.web = UserField(base, 'web', 'icon-home.png') self.web.set_info('') self.tweets = StatInfoBox('tweets', '') self.following = StatInfoBox('following', '') self.followers = StatInfoBox('followers', '') self.favorites = StatInfoBox('favorites', '') footer_layout = QHBoxLayout() footer_layout.setContentsMargins(0, 5, 0, 10) footer_layout.setSpacing(0) footer_layout.addLayout(self.tweets) footer_layout.addWidget(VLine()) footer_layout.addLayout(self.following) footer_layout.addWidget(VLine()) footer_layout.addLayout(self.followers) footer_layout.addWidget(VLine()) footer_layout.addLayout(self.favorites) footer = QWidget() footer.setLayout(footer_layout) footer.setStyleSheet("QWidget { background-color: #333; color: white; }") body_layout = QVBoxLayout() body_layout.setSpacing(15) body_layout.setContentsMargins(0, 0, 0, 0) body_layout.addLayout(self.bio) body_layout.addLayout(self.location) body_layout.addLayout(self.web) body_layout.addWidget(footer) body = QWidget() body.setLayout(body_layout) self.last_statuses = StatusesColumn(self.base, None, False) self.tabs = QTabWidget(self) self.tabs.setTabsClosable(False) self.tabs.setMovable(False) self.tabs.addTab(body, i18n.get('info')) self.tabs.addTab(self.last_statuses, i18n.get('recent')) self.hline = HLine() self.hline.setMinimumHeight(2) layout = QVBoxLayout() layout.addLayout(header) layout.addSpacing(10) layout.addWidget(self.hline) layout.addWidget(self.loader) layout.addWidget(self.error_message) layout.addSpacing(10) layout.addWidget(self.tabs, 1) layout.setSpacing(0) layout.setContentsMargins(5, 5, 5, 5) self.setLayout(layout) self.__clear()
class ProfileDialog(Window): options_clicked = pyqtSignal(QPoint, object) def __init__(self, base): Window.__init__(self, base, i18n.get('user_profile')) self.account_id = None self.setFixedSize(380, 450) self.username = QLabel('') self.username.setTextFormat(Qt.RichText) self.fullname = QLabel('') self.options = ImageButton(base, 'action-status-menu.png', i18n.get('')) self.options.clicked.connect(self.__options_clicked) self.verified_icon = QLabel() self.verified_icon.setPixmap(base.load_image('mark-verified.png', True)) self.protected_icon = QLabel() self.protected_icon.setPixmap(base.load_image('mark-protected.png', True)) self.avatar = ClickableLabel() self.avatar.setPixmap(base.load_image('unknown.png', True)) self.avatar.clicked.connect(self.__show_avatar) self.you_label = QLabel(i18n.get('this_is_you')) self.you_label.setVisible(False) info_line1 = QHBoxLayout() info_line1.setSpacing(5) info_line1.addWidget(self.username) info_line1.addSpacing(5) info_line1.addWidget(self.verified_icon) info_line1.addWidget(self.protected_icon) info_line1.addStretch(0) info_line2 = QHBoxLayout() info_line2.addWidget(self.fullname, 1) info_line2.addWidget(self.options) info_line2.addWidget(self.you_label) user_info = QVBoxLayout() user_info.addLayout(info_line1) user_info.addLayout(info_line2) self.loader = BarLoadIndicator() self.loader.setVisible(False) self.error_message = ErrorLabel() self.error_message.setVisible(False) header = QHBoxLayout() header.setContentsMargins(5, 10, 5, 0) header.addWidget(self.avatar) header.addSpacing(10) header.addLayout(user_info) # User Info self.bio = UserField(base, 'bio', 'icon-bio.png') self.bio.set_word_wrap(True) self.bio.set_info('') self.location = UserField(base, 'location', 'icon-location.png') self.location.set_info('') self.web = UserField(base, 'web', 'icon-home.png') self.web.set_info('') self.tweets = StatInfoBox('tweets', '') self.following = StatInfoBox('following', '') self.followers = StatInfoBox('followers', '') self.favorites = StatInfoBox('favorites', '') footer_layout = QHBoxLayout() footer_layout.setContentsMargins(0, 5, 0, 10) footer_layout.setSpacing(0) footer_layout.addLayout(self.tweets) footer_layout.addWidget(VLine()) footer_layout.addLayout(self.following) footer_layout.addWidget(VLine()) footer_layout.addLayout(self.followers) footer_layout.addWidget(VLine()) footer_layout.addLayout(self.favorites) footer = QWidget() footer.setLayout(footer_layout) footer.setStyleSheet("QWidget { background-color: #333; color: white; }") body_layout = QVBoxLayout() body_layout.setSpacing(15) body_layout.setContentsMargins(0, 0, 0, 0) body_layout.addLayout(self.bio) body_layout.addLayout(self.location) body_layout.addLayout(self.web) body_layout.addWidget(footer) body = QWidget() body.setLayout(body_layout) self.last_statuses = StatusesColumn(self.base, None, False) self.tabs = QTabWidget(self) self.tabs.setTabsClosable(False) self.tabs.setMovable(False) self.tabs.addTab(body, i18n.get('info')) self.tabs.addTab(self.last_statuses, i18n.get('recent')) self.hline = HLine() self.hline.setMinimumHeight(2) layout = QVBoxLayout() layout.addLayout(header) layout.addSpacing(10) layout.addWidget(self.hline) layout.addWidget(self.loader) layout.addWidget(self.error_message) layout.addSpacing(10) layout.addWidget(self.tabs, 1) layout.setSpacing(0) layout.setContentsMargins(5, 5, 5, 5) self.setLayout(layout) self.__clear() def __clear(self): self.profile = None self.showed = False self.account_id = None self.verified_icon.setVisible(False) self.protected_icon.setVisible(False) self.you_label.setVisible(False) self.options.setVisible(False) self.loader.setVisible(False) self.error_message.setVisible(False) self.avatar.setPixmap(self.base.load_image('unknown.png', True)) self.bio.set_info('') self.location.set_info('') self.web.set_info('') self.tweets.set_value('') self.following.set_value('') self.followers.set_value('') self.favorites.set_value('') self.last_statuses.id_ = None self.last_statuses.clear() self.tabs.setCurrentIndex(0) def __options_clicked(self): self.options_clicked.emit(QCursor.pos(), self.profile) def __show_avatar(self): self.base.show_profile_image(self.account_id, self.profile.username) def __on_timeout(self): self.error_message.setText('') self.error_message.setVisible(False) def closeEvent(self, event=None): if event: event.ignore() self.__clear() self.hide() def start_loading(self, profile_username): self.__clear() self.hline.setVisible(False) self.loader.setVisible(True) self.username.setText('<b>%s</b>' % profile_username) self.fullname.setText(i18n.get('loading')) self.show() self.raise_() self.showed = True def loading_finished(self, profile, account_id): self.profile = profile self.account_id = str(account_id) self.loader.setVisible(False) self.hline.setVisible(False) self.username.setText('<b>%s</b>' % profile.username) self.fullname.setText(profile.fullname) if get_username_from(account_id) == profile.username: self.you_label.setVisible(True) self.options.setVisible(False) else: self.you_label.setVisible(False) self.options.setVisible(True) self.verified_icon.setVisible(profile.verified) self.protected_icon.setVisible(profile.protected) self.avatar.setPixmap(self.base.load_image('unknown.png', True)) self.bio.set_info(profile.bio) self.location.set_info(profile.location) self.web.set_info(profile.url) self.tweets.set_value(str(profile.statuses_count)) self.following.set_value(str(profile.friends_count)) self.followers.set_value(str(profile.followers_count)) self.favorites.set_value(str(profile.favorites_count)) column_id = "%s-profile_recent" % self.account_id self.last_statuses.set_column_id(column_id) self.last_statuses.update_statuses(profile.recent_updates) self.show() self.raise_() def is_for_profile(self, column_id): if column_id.find('profile_recent') > 0: return True return False def update_avatar(self, image_path, username): if username != self.profile.username or not self.showed: return self.avatar.setPixmap(self.base.load_image(image_path, True)) def update_following(self, username, following): if username != self.profile.username or not self.showed: return self.profile.following = following def error(self, message): self.loader.setVisible(False) self.hline.setVisible(False) self.fullname.setText('') self.error_message.setText(message) self.error_message.setVisible(True) self.timer = QTimer() self.timer.timeout.connect(self.__on_timeout) self.timer.start(5000) self.show() self.raise_() def error_marking_status_as_favorite(self, status_id): self.last_statuses.release_status(status_id) self.last_statuses.notify_error(status_id, i18n.get('error_marking_status_as_favorite')) def error_unmarking_status_as_favorite(self, status_id): self.last_statuses.release_status(status_id) self.last_statuses.notify_error(status_id, i18n.get('error_unmarking_status_as_favorite')) def error_repeating_status(self, status_id): self.last_statuses.release_status(status_id) self.last_statuses.notify_error(status_id, i18n.get('error_repeating_status')) def error_loading_conversation(self, status_root_id): self.last_statuses.error_in_conversation(status_root_id) self.last_statuses.notify_error(self.base.random_id(), i18n.get('error_loading_conversation'))