Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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()
Exemplo n.º 3
0
    def __init__(self, base):
        Window.__init__(self, base, i18n.get('image_preview'))

        self.loader = BarLoadIndicator()

        self.view = QLabel()
        self.view.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        self.view.setScaledContents(True)

        scroll_area = QScrollArea()
        scroll_area.setBackgroundRole(QPalette.Dark)
        scroll_area.setWidget(self.view)
        scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        self.error_label = QLabel(i18n.get('error_loading_image'))
        self.error_label.setAlignment(Qt.AlignHCenter)
        self.error_label.setStyleSheet("QLabel {background-color: #ffecec;}")

        layout = QVBoxLayout()
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.loader)
        layout.addWidget(self.error_label)
        layout.addWidget(scroll_area)

        self.setLayout(layout)
        self.__clear()
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
class ImageView(Window):
    def __init__(self, base):
        Window.__init__(self, base, i18n.get('image_preview'))

        self.loader = BarLoadIndicator()

        self.view = QLabel()
        self.view.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        self.view.setScaledContents(True)

        scroll_area = QScrollArea()
        scroll_area.setBackgroundRole(QPalette.Dark)
        scroll_area.setWidget(self.view)
        scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        self.error_label = QLabel(i18n.get('error_loading_image'))
        self.error_label.setAlignment(Qt.AlignHCenter)
        self.error_label.setStyleSheet("QLabel {background-color: #ffecec;}")

        layout = QVBoxLayout()
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.loader)
        layout.addWidget(self.error_label)
        layout.addWidget(scroll_area)

        self.setLayout(layout)
        self.__clear()

    def __clear(self):
        self.resize(350, 350)
        self.view.setPixmap(QPixmap())

    def closeEvent(self, event):
        event.ignore()
        self.__clear()
        self.hide()

    def start_loading(self):
        self.loader.setVisible(True)
        self.error_label.setVisible(False)
        self.show()

    def loading_finished(self, url):
        self.loader.setVisible(False)
        pix = self.base.load_image(url, True)
        self.view.setPixmap(pix)
        self.view.adjustSize()
        self.resize(pix.width() + 2, pix.height() + 2)
        self.show()

    def error(self):
        self.loader.setVisible(False)
        self.error_label.setVisible(True)
Exemplo n.º 6
0
    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
Exemplo n.º 7
0
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)
Exemplo n.º 8
0
    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()
Exemplo n.º 9
0
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'))
Exemplo n.º 10
0
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)
Exemplo n.º 11
0
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)
Exemplo n.º 12
0
    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()
Exemplo n.º 13
0
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'))