def __init__(self, base, column_id, include_header=True): QWidget.__init__(self) self.base = base self.setMinimumWidth(280) self.statuses = [] self.conversations = {} self.id_ = None #self.fgcolor = "#e3e3e3" #self.fgcolor = "#f9a231" #self.updating = False self.last_id = None self.loader = BarLoadIndicator() self.loader.setVisible(False) self.webview = StatusesWebView(self.base, self.id_) self.webview.link_clicked.connect(self.__link_clicked) self.webview.hashtag_clicked.connect(self.__hashtag_clicked) self.webview.profile_clicked.connect(self.__profile_clicked) self.webview.cmd_clicked.connect(self.__cmd_clicked) layout = QVBoxLayout() layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) if include_header: header = self.__build_header(column_id) layout.addWidget(header) layout.addWidget(self.loader) layout.addWidget(self.webview, 1) self.setLayout(layout)
class StatusesColumn(QWidget): NOTIFICATION_ERROR = 'error' NOTIFICATION_SUCCESS = 'success' NOTIFICATION_WARNING = 'warning' NOTIFICATION_INFO = 'notice' def __init__(self, base, column_id, include_header=True): QWidget.__init__(self) self.base = base self.setMinimumWidth(280) self.statuses = [] self.conversations = {} self.id_ = None #self.fgcolor = "#e3e3e3" #self.fgcolor = "#f9a231" #self.updating = False self.last_id = None self.loader = BarLoadIndicator() self.loader.setVisible(False) self.webview = StatusesWebView(self.base, self.id_) self.webview.link_clicked.connect(self.__link_clicked) self.webview.hashtag_clicked.connect(self.__hashtag_clicked) self.webview.profile_clicked.connect(self.__profile_clicked) self.webview.cmd_clicked.connect(self.__cmd_clicked) layout = QVBoxLayout() layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) if include_header: header = self.__build_header(column_id) layout.addWidget(header) layout.addWidget(self.loader) layout.addWidget(self.webview, 1) self.setLayout(layout) 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 __delete_column(self): self.base.core.delete_column(self.id_) def __link_clicked(self, url): url = str(url) preview_service = get_preview_service_from_url(url) self.base.open_url(url) def __hashtag_clicked(self, hashtag): self.base.add_search_column(self.account_id, str(hashtag)) def __profile_clicked(self, username): self.base.show_profile_dialog(self.account_id, str(username)) def __cmd_clicked(self, url): status_id = str(url.split(':')[1]) cmd = url.split(':')[0] status = None try: print 'Seeking for status in self array' for status_ in self.statuses: if status_.id_ == status_id: status = status_ break if status is None: raise KeyError except KeyError: print 'Seeking for status in conversations array' for status_root, statuses in self.conversations.iteritems(): for item in statuses: if item.id_ == status_id: status = item break if status is not None: break if status is None: self.notify_error(status_id, i18n.get('try_again')) if cmd == 'reply': self.__reply_status(status) elif cmd == 'quote': self.__quote_status(status) elif cmd == 'repeat': self.__repeat_status(status) elif cmd == 'delete': self.__delete_status(status) elif cmd == 'favorite': self.__mark_status_as_favorite(status) elif cmd == 'unfavorite': self.__unmark_status_as_favorite(status) elif cmd == 'delete_direct': self.__delete_direct_message(status) elif cmd == 'reply_direct': self.__reply_direct_message(status) elif cmd == 'view_conversation': self.__view_conversation(status) elif cmd == 'hide_conversation': self.__hide_conversation(status) elif cmd == 'show_avatar': self.__show_avatar(status) def __reply_status(self, status): self.base.show_update_box_for_reply(self.account_id, status) def __quote_status(self, status): self.base.show_update_box_for_quote(self.account_id, status) def __repeat_status(self, status): confirmation = self.base.show_confirmation_message(i18n.get('confirm_retweet'), i18n.get('do_you_want_to_retweet_status')) if confirmation: self.lock_status(status.id_) self.base.repeat_status(self.id_, self.account_id, status) def __delete_status(self, status): confirmation = self.base.show_confirmation_message(i18n.get('confirm_delete'), i18n.get('do_you_want_to_delete_status')) if confirmation: self.lock_status(status.id_) self.base.delete_status(self.id_, self.account_id, status) def __delete_direct_message(self, status): confirmation = self.base.show_confirmation_message(i18n.get('confirm_delete'), i18n.get('do_you_want_to_delete_direct_message')) if confirmation: self.base.delete_direct_message(self.id_, self.account_id, status) def __reply_direct_message(self, status): self.base.show_update_box_for_reply_direct(self.account_id, status) def __mark_status_as_favorite(self, status): self.lock_status(status.id_) self.base.mark_status_as_favorite(self.id_, self.account_id, status) def __unmark_status_as_favorite(self, status): self.lock_status(status.id_) self.base.unmark_status_as_favorite(self.id_, self.account_id, status) def __view_conversation(self, status): self.webview.view_conversation(status.id_) self.base.get_conversation(self.account_id, status, self.id_, status.id_) def __hide_conversation(self, status): del self.conversations[status.id_] self.webview.clear_conversation(status.id_) def __show_avatar(self, status): self.base.show_profile_image(self.account_id, status.username) def __set_last_status_id(self, statuses): if statuses[0].repeated_by: self.last_id = statuses[0].original_status_id else: self.last_id = statuses[0].id_ def set_column_id(self, column_id): self.id_ = column_id self.account_id = get_account_id_from(column_id) self.protocol_id = get_protocol_from(self.account_id) self.webview.column_id = column_id def clear(self): self.webview.clear() def start_updating(self): self.loader.setVisible(True) return self.last_id def stop_updating(self): self.loader.setVisible(False) def update_timestamps(self): self.webview.sync_timestamps(self.statuses) def update_statuses(self, statuses): self.__set_last_status_id(statuses) self.update_timestamps() self.webview.update_statuses(statuses) # Filter repeated statuses # FIXME: This should be done with list comprehension using comparation methods on status.py unique_statuses = [] for s1 in statuses: exist = False for s2 in self.statuses: if s1.id_ == s2.id_: exist = True break if not exist: unique_statuses.append(s1) # Remove old conversations to_remove = self.statuses[-(len(unique_statuses)):] self.statuses = statuses + self.statuses[: -(len(unique_statuses))] for status in to_remove: if self.conversations.has_key(status.id_): del self.conversations[status.id_] def update_conversation(self, status, status_root_id): status_root_id = str(status_root_id) self.webview.update_conversation(status, status_root_id) if status_root_id in self.conversations: self.conversations[status_root_id].append(status) else: self.conversations[status_root_id] = [status] def error_in_conversation(self, status_root_id): self.webview.clear_conversation(status_root_id) def mark_status_as_favorite(self, status_id): mark = "setFavorite('%s')" % status_id self.webview.execute_javascript(mark) def unmark_status_as_favorite(self, status_id): mark = "unsetFavorite('%s');" % status_id self.webview.execute_javascript(mark) def mark_status_as_repeated(self, status_id): mark = "setRepeated('%s');" % status_id self.webview.execute_javascript(mark) def remove_status(self, status_id): operation = "removeStatus('%s');" % status_id self.webview.execute_javascript(operation) def lock_status(self, status_id): operation = "lockStatus('%s');" % status_id self.webview.execute_javascript(operation) def release_status(self, status_id): operation = "releaseStatus('%s');" % status_id self.webview.execute_javascript(operation) def notify(self, id_, type_, message): message = message.replace("'", "\"") notification = "addNotify('%s', '%s', '%s');" % (id_, type_, message) self.webview.execute_javascript(notification) def notify_error(self, id_, message): self.notify(id_, self.NOTIFICATION_ERROR, message) def notify_success(self, id_, message): self.notify(id_, self.NOTIFICATION_SUCCESS, message) def notify_warning(self, id_, message): self.notify(id_, self.NOTIFICATION_WARNING, message) def notify_info(self, id_, message): self.notify(id_, self.NOTIFICATION_INFO, message)
class StatusesColumn(QWidget): NOTIFICATION_ERROR = 'error' NOTIFICATION_SUCCESS = 'success' NOTIFICATION_WARNING = 'warning' NOTIFICATION_INFO = 'notice' def __init__(self, base, column_id, include_header=True): QWidget.__init__(self) self.base = base self.setMinimumWidth(280) self.statuses = [] self.conversations = {} self.id_ = None #self.fgcolor = "#e3e3e3" #self.fgcolor = "#f9a231" #self.updating = False self.last_id = None self.loader = BarLoadIndicator() self.loader.setVisible(False) self.webview = StatusesWebView(self.base, self.id_) self.webview.link_clicked.connect(self.__link_clicked) self.webview.hashtag_clicked.connect(self.__hashtag_clicked) self.webview.profile_clicked.connect(self.__profile_clicked) self.webview.cmd_clicked.connect(self.__cmd_clicked) layout = QVBoxLayout() layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) if include_header: header = self.__build_header(column_id) layout.addWidget(header) layout.addWidget(self.loader) layout.addWidget(self.webview, 1) self.setLayout(layout) 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 __delete_column(self): self.base.core.delete_column(self.id_) def __link_clicked(self, url): url = str(url) preview_service = get_preview_service_from_url(url) self.base.open_url(url) def __hashtag_clicked(self, hashtag): self.base.add_search_column(self.account_id, str(hashtag)) def __profile_clicked(self, username): self.base.show_profile_dialog(self.account_id, str(username)) def __cmd_clicked(self, url): status_id = str(url.split(':')[1]) cmd = url.split(':')[0] status = None try: print 'Seeking for status in self array' for status_ in self.statuses: if status_.id_ == status_id: status = status_ break if status is None: raise KeyError except KeyError: print 'Seeking for status in conversations array' for status_root, statuses in self.conversations.iteritems(): for item in statuses: if item.id_ == status_id: status = item break if status is not None: break if status is None: self.notify_error(status_id, i18n.get('try_again')) if cmd == 'reply': self.__reply_status(status) elif cmd == 'quote': self.__quote_status(status) elif cmd == 'repeat': self.__repeat_status(status) elif cmd == 'delete': self.__delete_status(status) elif cmd == 'favorite': self.__mark_status_as_favorite(status) elif cmd == 'unfavorite': self.__unmark_status_as_favorite(status) elif cmd == 'delete_direct': self.__delete_direct_message(status) elif cmd == 'reply_direct': self.__reply_direct_message(status) elif cmd == 'view_conversation': self.__view_conversation(status) elif cmd == 'hide_conversation': self.__hide_conversation(status) elif cmd == 'show_avatar': self.__show_avatar(status) def __reply_status(self, status): self.base.show_update_box_for_reply(self.account_id, status) def __quote_status(self, status): self.base.show_update_box_for_quote(self.account_id, status) def __repeat_status(self, status): confirmation = self.base.show_confirmation_message( i18n.get('confirm_retweet'), i18n.get('do_you_want_to_retweet_status')) if confirmation: self.lock_status(status.id_) self.base.repeat_status(self.id_, self.account_id, status) def __delete_status(self, status): confirmation = self.base.show_confirmation_message( i18n.get('confirm_delete'), i18n.get('do_you_want_to_delete_status')) if confirmation: self.lock_status(status.id_) self.base.delete_status(self.id_, self.account_id, status) def __delete_direct_message(self, status): confirmation = self.base.show_confirmation_message( i18n.get('confirm_delete'), i18n.get('do_you_want_to_delete_direct_message')) if confirmation: self.base.delete_direct_message(self.id_, self.account_id, status) def __reply_direct_message(self, status): self.base.show_update_box_for_reply_direct(self.account_id, status) def __mark_status_as_favorite(self, status): self.lock_status(status.id_) self.base.mark_status_as_favorite(self.id_, self.account_id, status) def __unmark_status_as_favorite(self, status): self.lock_status(status.id_) self.base.unmark_status_as_favorite(self.id_, self.account_id, status) def __view_conversation(self, status): self.webview.view_conversation(status.id_) self.base.get_conversation(self.account_id, status, self.id_, status.id_) def __hide_conversation(self, status): del self.conversations[status.id_] self.webview.clear_conversation(status.id_) def __show_avatar(self, status): self.base.show_profile_image(self.account_id, status.username) def __set_last_status_id(self, statuses): if statuses[0].repeated_by: self.last_id = statuses[0].original_status_id else: self.last_id = statuses[0].id_ def set_column_id(self, column_id): self.id_ = column_id self.account_id = get_account_id_from(column_id) self.protocol_id = get_protocol_from(self.account_id) self.webview.column_id = column_id def clear(self): self.webview.clear() def start_updating(self): self.loader.setVisible(True) return self.last_id def stop_updating(self): self.loader.setVisible(False) def update_timestamps(self): self.webview.sync_timestamps(self.statuses) def update_statuses(self, statuses): self.__set_last_status_id(statuses) self.update_timestamps() self.webview.update_statuses(statuses) # Filter repeated statuses # FIXME: This should be done with list comprehension using comparation methods on status.py unique_statuses = [] for s1 in statuses: exist = False for s2 in self.statuses: if s1.id_ == s2.id_: exist = True break if not exist: unique_statuses.append(s1) # Remove old conversations to_remove = self.statuses[-(len(unique_statuses)):] self.statuses = statuses + self.statuses[:-(len(unique_statuses))] for status in to_remove: if self.conversations.has_key(status.id_): del self.conversations[status.id_] def update_conversation(self, status, status_root_id): status_root_id = str(status_root_id) self.webview.update_conversation(status, status_root_id) if status_root_id in self.conversations: self.conversations[status_root_id].append(status) else: self.conversations[status_root_id] = [status] def error_in_conversation(self, status_root_id): self.webview.clear_conversation(status_root_id) def mark_status_as_favorite(self, status_id): mark = "setFavorite('%s')" % status_id self.webview.execute_javascript(mark) def unmark_status_as_favorite(self, status_id): mark = "unsetFavorite('%s');" % status_id self.webview.execute_javascript(mark) def mark_status_as_repeated(self, status_id): mark = "setRepeated('%s');" % status_id self.webview.execute_javascript(mark) def remove_status(self, status_id): operation = "removeStatus('%s');" % status_id self.webview.execute_javascript(operation) def lock_status(self, status_id): operation = "lockStatus('%s');" % status_id self.webview.execute_javascript(operation) def release_status(self, status_id): operation = "releaseStatus('%s');" % status_id self.webview.execute_javascript(operation) def notify(self, id_, type_, message): message = message.replace("'", "\"") notification = "addNotify('%s', '%s', '%s');" % (id_, type_, message) self.webview.execute_javascript(notification) def notify_error(self, id_, message): self.notify(id_, self.NOTIFICATION_ERROR, message) def notify_success(self, id_, message): self.notify(id_, self.NOTIFICATION_SUCCESS, message) def notify_warning(self, id_, message): self.notify(id_, self.NOTIFICATION_WARNING, message) def notify_info(self, id_, message): self.notify(id_, self.NOTIFICATION_INFO, message)