Ejemplo n.º 1
0
class SetProfilePasswordScreen(CenteredWidget):

    def __init__(self, encrypt):
        super(SetProfilePasswordScreen, self).__init__()
        self._encrypt = encrypt
        self.initUI()
        self.retranslateUi()
        self.center()

    def initUI(self):
        self.setMinimumSize(QtCore.QSize(700, 200))
        self.setMaximumSize(QtCore.QSize(700, 200))
        self.password = LineEdit(self)
        self.password.setGeometry(QtCore.QRect(40, 10, 300, 30))
        self.password.setEchoMode(QtGui.QLineEdit.EchoMode.Password)
        self.confirm_password = LineEdit(self)
        self.confirm_password.setGeometry(QtCore.QRect(40, 50, 300, 30))
        self.confirm_password.setEchoMode(QtGui.QLineEdit.EchoMode.Password)
        self.set_password = QtGui.QPushButton(self)
        self.set_password.setGeometry(QtCore.QRect(40, 100, 300, 30))
        self.set_password.clicked.connect(self.new_password)
        self.not_match = QtGui.QLabel(self)
        self.not_match.setGeometry(QtCore.QRect(350, 50, 300, 30))
        self.not_match.setVisible(False)
        self.not_match.setStyleSheet('QLabel { color: #BC1C1C; }')
        self.warning = QtGui.QLabel(self)
        self.warning.setGeometry(QtCore.QRect(40, 160, 500, 30))
        self.warning.setStyleSheet('QLabel { color: #BC1C1C; }')

    def retranslateUi(self):
        self.setWindowTitle(QtGui.QApplication.translate("PasswordScreen", "Profile password", None,
                                                              QtGui.QApplication.UnicodeUTF8))
        self.password.setPlaceholderText(
            QtGui.QApplication.translate("PasswordScreen", "Password (at least 8 symbols)", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.confirm_password.setPlaceholderText(
            QtGui.QApplication.translate("PasswordScreen", "Confirm password", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.set_password.setText(
            QtGui.QApplication.translate("PasswordScreen", "Set password", None, QtGui.QApplication.UnicodeUTF8))
        self.not_match.setText(QtGui.QApplication.translate("PasswordScreen", "Passwords do not match", None,
                                                            QtGui.QApplication.UnicodeUTF8))
        self.warning.setText(
            QtGui.QApplication.translate("PasswordScreen", "There is no way to recover lost passwords", None,
                                         QtGui.QApplication.UnicodeUTF8))

    def new_password(self):
        if self.password.text() == self.confirm_password.text():
            if len(self.password.text()) >= 8:
                self._encrypt.set_password(self.password.text())
                self.close()
            else:
                self.not_match.setText(
                    QtGui.QApplication.translate("PasswordScreen", "Password must be at least 8 symbols", None,
                                                 QtGui.QApplication.UnicodeUTF8))
            self.not_match.setVisible(True)
        else:
            self.not_match.setText(QtGui.QApplication.translate("PasswordScreen", "Passwords do not match", None,
                                                                QtGui.QApplication.UnicodeUTF8))
            self.not_match.setVisible(True)
Ejemplo n.º 2
0
class SetProfilePasswordScreen(CenteredWidget):

    def __init__(self, encrypt):
        super(SetProfilePasswordScreen, self).__init__()
        self._encrypt = encrypt
        self.initUI()
        self.retranslateUi()
        self.center()

    def initUI(self):
        self.setMinimumSize(QtCore.QSize(700, 200))
        self.setMaximumSize(QtCore.QSize(700, 200))
        self.password = LineEdit(self)
        self.password.setGeometry(QtCore.QRect(40, 10, 300, 30))
        self.password.setEchoMode(QtWidgets.QLineEdit.Password)
        self.confirm_password = LineEdit(self)
        self.confirm_password.setGeometry(QtCore.QRect(40, 50, 300, 30))
        self.confirm_password.setEchoMode(QtWidgets.QLineEdit.Password)
        self.set_password = QtWidgets.QPushButton(self)
        self.set_password.setGeometry(QtCore.QRect(40, 100, 300, 30))
        self.set_password.clicked.connect(self.new_password)
        self.not_match = QtWidgets.QLabel(self)
        self.not_match.setGeometry(QtCore.QRect(350, 50, 300, 30))
        self.not_match.setVisible(False)
        self.not_match.setStyleSheet('QLabel { color: #BC1C1C; }')
        self.warning = QtWidgets.QLabel(self)
        self.warning.setGeometry(QtCore.QRect(40, 160, 500, 30))
        self.warning.setStyleSheet('QLabel { color: #BC1C1C; }')

    def retranslateUi(self):
        self.setWindowTitle(QtWidgets.QApplication.translate("PasswordScreen", "Profile password"))
        self.password.setPlaceholderText(
            QtWidgets.QApplication.translate("PasswordScreen", "Password (at least 8 symbols)"))
        self.confirm_password.setPlaceholderText(
            QtWidgets.QApplication.translate("PasswordScreen", "Confirm password"))
        self.set_password.setText(
            QtWidgets.QApplication.translate("PasswordScreen", "Set password"))
        self.not_match.setText(QtWidgets.QApplication.translate("PasswordScreen", "Passwords do not match"))
        self.warning.setText(
            QtWidgets.QApplication.translate("PasswordScreen", "There is no way to recover lost passwords"))

    def new_password(self):
        if self.password.text() == self.confirm_password.text():
            if len(self.password.text()) >= 8:
                self._encrypt.set_password(self.password.text())
                self.close()
            else:
                self.not_match.setText(
                    QtWidgets.QApplication.translate("PasswordScreen", "Password must be at least 8 symbols"))
            self.not_match.setVisible(True)
        else:
            self.not_match.setText(QtWidgets.QApplication.translate("PasswordScreen", "Passwords do not match"))
            self.not_match.setVisible(True)
Ejemplo n.º 3
0
class SearchScreen(QtGui.QWidget):
    def __init__(self, messages, width, *args):
        super().__init__(*args)
        self.setMaximumSize(width, 40)
        self.setMinimumSize(width, 40)
        self._messages = messages

        self.search_text = LineEdit(self)
        self.search_text.setGeometry(0, 0, width - 160, 40)

        self.search_button = ClickableLabel(self)
        self.search_button.setGeometry(width - 160, 0, 40, 40)
        pixmap = QtGui.QPixmap()
        pixmap.load(util.curr_directory() + '/images/search.png')
        self.search_button.setScaledContents(False)
        self.search_button.setAlignment(QtCore.Qt.AlignCenter)
        self.search_button.setPixmap(pixmap)
        self.connect(self.search_button, QtCore.SIGNAL('clicked()'),
                     self.search)

        font = QtGui.QFont()
        font.setPointSize(32)
        font.setBold(True)

        self.prev_button = QtGui.QPushButton(self)
        self.prev_button.setGeometry(width - 120, 0, 40, 40)
        self.prev_button.clicked.connect(self.prev)
        self.prev_button.setText('\u25B2')

        self.next_button = QtGui.QPushButton(self)
        self.next_button.setGeometry(width - 80, 0, 40, 40)
        self.next_button.clicked.connect(self.next)
        self.next_button.setText('\u25BC')

        self.close_button = QtGui.QPushButton(self)
        self.close_button.setGeometry(width - 40, 0, 40, 40)
        self.close_button.clicked.connect(self.close)
        self.close_button.setText('×')
        self.close_button.setFont(font)

        font.setPointSize(18)
        self.next_button.setFont(font)
        self.prev_button.setFont(font)

        self.retranslateUi()

    def retranslateUi(self):
        self.search_text.setPlaceholderText(
            QtGui.QApplication.translate("MainWindow", "Search", None,
                                         QtGui.QApplication.UnicodeUTF8))

    def show(self):
        super().show()
        self.search_text.setFocus()

    def search(self):
        Profile.get_instance().update()
        text = self.search_text.text()
        friend = Profile.get_instance().get_curr_friend()
        if text and friend and util.is_re_valid(text):
            index = friend.search_string(text)
            self.load_messages(index)

    def prev(self):
        friend = Profile.get_instance().get_curr_friend()
        if friend is not None:
            index = friend.search_prev()
            self.load_messages(index)

    def next(self):
        friend = Profile.get_instance().get_curr_friend()
        text = self.search_text.text()
        if friend is not None:
            index = friend.search_next()
            if index is not None:
                count = self._messages.count()
                index += count
                item = self._messages.item(index)
                self._messages.scrollToItem(item)
                self._messages.itemWidget(item).select_text(text)
            else:
                self.not_found(text)

    def load_messages(self, index):
        text = self.search_text.text()
        if index is not None:
            profile = Profile.get_instance()
            count = self._messages.count()
            while count + index < 0:
                profile.load_history()
                count = self._messages.count()
            index += count
            item = self._messages.item(index)
            self._messages.scrollToItem(item)
            self._messages.itemWidget(item).select_text(text)
        else:
            self.not_found(text)

    def closeEvent(self, *args):
        Profile.get_instance().update()
        self._messages.setGeometry(0, 0, self._messages.width(),
                                   self._messages.height() + 40)
        super().closeEvent(*args)

    @staticmethod
    def not_found(text):
        mbox = QtGui.QMessageBox()
        mbox_text = QtGui.QApplication.translate(
            "MainWindow", 'Text "{}" was not found', None,
            QtGui.QApplication.UnicodeUTF8)

        mbox.setText(mbox_text.format(text))
        mbox.setWindowTitle(
            QtGui.QApplication.translate("MainWindow", 'Not found', None,
                                         QtGui.QApplication.UnicodeUTF8))
        mbox.exec_()
Ejemplo n.º 4
0
class ProfileSettings(CenteredWidget):
    """Form with profile settings such as name, status, TOX ID"""
    def __init__(self):
        super(ProfileSettings, self).__init__()
        self.initUI()
        self.center()

    def initUI(self):
        self.setObjectName("ProfileSettingsForm")
        self.setMinimumSize(QtCore.QSize(700, 600))
        self.setMaximumSize(QtCore.QSize(700, 600))
        self.nick = LineEdit(self)
        self.nick.setGeometry(QtCore.QRect(30, 60, 350, 27))
        profile = Profile.get_instance()
        self.nick.setText(profile.name)
        self.status = QtGui.QComboBox(self)
        self.status.setGeometry(QtCore.QRect(400, 60, 200, 27))
        self.status_message = LineEdit(self)
        self.status_message.setGeometry(QtCore.QRect(30, 130, 350, 27))
        self.status_message.setText(profile.status_message)
        self.label = QtGui.QLabel(self)
        self.label.setGeometry(QtCore.QRect(40, 30, 91, 25))
        font = QtGui.QFont()
        font.setPointSize(18)
        font.setWeight(75)
        font.setBold(True)
        self.label.setFont(font)
        self.label_2 = QtGui.QLabel(self)
        self.label_2.setGeometry(QtCore.QRect(40, 100, 100, 25))
        self.label_2.setFont(font)
        self.label_3 = QtGui.QLabel(self)
        self.label_3.setGeometry(QtCore.QRect(40, 180, 100, 25))
        self.label_3.setFont(font)
        self.tox_id = QtGui.QLabel(self)
        self.tox_id.setGeometry(QtCore.QRect(15, 210, 685, 21))
        font.setPointSize(10)
        self.tox_id.setFont(font)
        s = profile.tox_id
        self.tox_id.setText(s)
        self.copyId = QtGui.QPushButton(self)
        self.copyId.setGeometry(QtCore.QRect(40, 250, 180, 30))
        self.copyId.clicked.connect(self.copy)
        self.export = QtGui.QPushButton(self)
        self.export.setGeometry(QtCore.QRect(230, 250, 180, 30))
        self.export.clicked.connect(self.export_profile)
        self.new_nospam = QtGui.QPushButton(self)
        self.new_nospam.setGeometry(QtCore.QRect(420, 250, 180, 30))
        self.new_nospam.clicked.connect(self.new_no_spam)

        self.new_avatar = QtGui.QPushButton(self)
        self.new_avatar.setGeometry(QtCore.QRect(40, 300, 180, 30))
        self.delete_avatar = QtGui.QPushButton(self)
        self.delete_avatar.setGeometry(QtCore.QRect(230, 300, 180, 30))
        self.delete_avatar.clicked.connect(self.reset_avatar)
        self.new_avatar.clicked.connect(self.set_avatar)
        self.profile_pass = QtGui.QLabel(self)
        self.profile_pass.setGeometry(QtCore.QRect(40, 340, 300, 30))
        font.setPointSize(18)
        self.profile_pass.setFont(font)
        self.password = LineEdit(self)
        self.password.setGeometry(QtCore.QRect(40, 380, 300, 30))
        self.password.setEchoMode(QtGui.QLineEdit.EchoMode.Password)
        self.leave_blank = QtGui.QLabel(self)
        self.leave_blank.setGeometry(QtCore.QRect(350, 380, 300, 30))
        self.confirm_password = LineEdit(self)
        self.confirm_password.setGeometry(QtCore.QRect(40, 420, 300, 30))
        self.confirm_password.setEchoMode(QtGui.QLineEdit.EchoMode.Password)
        self.set_password = QtGui.QPushButton(self)
        self.set_password.setGeometry(QtCore.QRect(40, 470, 300, 30))
        self.set_password.clicked.connect(self.new_password)
        self.not_match = QtGui.QLabel(self)
        self.not_match.setGeometry(QtCore.QRect(350, 420, 300, 30))
        self.not_match.setVisible(False)
        self.not_match.setStyleSheet('QLabel { color: #BC1C1C; }')
        self.warning = QtGui.QLabel(self)
        self.warning.setGeometry(QtCore.QRect(40, 510, 500, 30))
        self.warning.setStyleSheet('QLabel { color: #BC1C1C; }')
        self.default = QtGui.QPushButton(self)
        self.default.setGeometry(QtCore.QRect(40, 550, 620, 30))
        path, name = Settings.get_auto_profile()
        self.auto = path + name == ProfileHelper.get_path(
        ) + Settings.get_instance().name
        self.default.clicked.connect(self.auto_profile)
        self.retranslateUi()
        if profile.status is not None:
            self.status.setCurrentIndex(profile.status)
        else:
            self.status.setVisible(False)
        QtCore.QMetaObject.connectSlotsByName(self)

    def retranslateUi(self):
        self.export.setText(
            QtGui.QApplication.translate("ProfileSettingsForm",
                                         "Export profile", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.setWindowTitle(
            QtGui.QApplication.translate("ProfileSettingsForm",
                                         "Profile settings", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.label.setText(
            QtGui.QApplication.translate("ProfileSettingsForm", "Name:", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.label_2.setText(
            QtGui.QApplication.translate("ProfileSettingsForm", "Status:",
                                         None, QtGui.QApplication.UnicodeUTF8))
        self.label_3.setText(
            QtGui.QApplication.translate("ProfileSettingsForm", "TOX ID:",
                                         None, QtGui.QApplication.UnicodeUTF8))
        self.copyId.setText(
            QtGui.QApplication.translate("ProfileSettingsForm", "Copy TOX ID",
                                         None, QtGui.QApplication.UnicodeUTF8))
        self.new_avatar.setText(
            QtGui.QApplication.translate("ProfileSettingsForm", "New avatar",
                                         None, QtGui.QApplication.UnicodeUTF8))
        self.delete_avatar.setText(
            QtGui.QApplication.translate("ProfileSettingsForm", "Reset avatar",
                                         None, QtGui.QApplication.UnicodeUTF8))
        self.new_nospam.setText(
            QtGui.QApplication.translate("ProfileSettingsForm", "New NoSpam",
                                         None, QtGui.QApplication.UnicodeUTF8))
        self.profile_pass.setText(
            QtGui.QApplication.translate("ProfileSettingsForm",
                                         "Profile password", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.password.setPlaceholderText(
            QtGui.QApplication.translate("ProfileSettingsForm",
                                         "Password (at least 8 symbols)", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.confirm_password.setPlaceholderText(
            QtGui.QApplication.translate("ProfileSettingsForm",
                                         "Confirm password", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.set_password.setText(
            QtGui.QApplication.translate("ProfileSettingsForm", "Set password",
                                         None, QtGui.QApplication.UnicodeUTF8))
        self.not_match.setText(
            QtGui.QApplication.translate("ProfileSettingsForm",
                                         "Passwords do not match", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.leave_blank.setText(
            QtGui.QApplication.translate(
                "ProfileSettingsForm",
                "Leaving blank will reset current password", None,
                QtGui.QApplication.UnicodeUTF8))
        self.warning.setText(
            QtGui.QApplication.translate(
                "ProfileSettingsForm",
                "There is no way to recover lost passwords", None,
                QtGui.QApplication.UnicodeUTF8))
        self.status.addItem(
            QtGui.QApplication.translate("ProfileSettingsForm", "Online", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.status.addItem(
            QtGui.QApplication.translate("ProfileSettingsForm", "Away", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.status.addItem(
            QtGui.QApplication.translate("ProfileSettingsForm", "Busy", None,
                                         QtGui.QApplication.UnicodeUTF8))
        if self.auto:
            self.default.setText(
                QtGui.QApplication.translate("ProfileSettingsForm",
                                             "Mark as not default profile",
                                             None,
                                             QtGui.QApplication.UnicodeUTF8))
        else:
            self.default.setText(
                QtGui.QApplication.translate("ProfileSettingsForm",
                                             "Mark as default profile", None,
                                             QtGui.QApplication.UnicodeUTF8))

    def auto_profile(self):
        if self.auto:
            Settings.reset_auto_profile()
        else:
            Settings.set_auto_profile(ProfileHelper.get_path(),
                                      Settings.get_instance().name)
        self.auto = not self.auto
        if self.auto:
            self.default.setText(
                QtGui.QApplication.translate("ProfileSettingsForm",
                                             "Mark as not default profile",
                                             None,
                                             QtGui.QApplication.UnicodeUTF8))
        else:
            self.default.setText(
                QtGui.QApplication.translate("ProfileSettingsForm",
                                             "Mark as default profile", None,
                                             QtGui.QApplication.UnicodeUTF8))

    def new_password(self):
        if self.password.text() == self.confirm_password.text():
            if not len(self.password.text()) or len(self.password.text()) >= 8:
                e = toxencryptsave.LibToxEncryptSave.get_instance()
                e.set_password(self.password.text())
                self.close()
            else:
                self.not_match.setText(
                    QtGui.QApplication.translate(
                        "ProfileSettingsForm",
                        "Password must be at least 8 symbols", None,
                        QtGui.QApplication.UnicodeUTF8))
            self.not_match.setVisible(True)
        else:
            self.not_match.setText(
                QtGui.QApplication.translate("ProfileSettingsForm",
                                             "Passwords do not match", None,
                                             QtGui.QApplication.UnicodeUTF8))
            self.not_match.setVisible(True)

    def copy(self):
        clipboard = QtGui.QApplication.clipboard()
        profile = Profile.get_instance()
        clipboard.setText(profile.tox_id)
        pixmap = QtGui.QPixmap(curr_directory() + '/images/accept.png')
        icon = QtGui.QIcon(pixmap)
        self.copyId.setIcon(icon)
        self.copyId.setIconSize(QtCore.QSize(10, 10))

    def new_no_spam(self):
        self.tox_id.setText(Profile.get_instance().new_nospam())

    def reset_avatar(self):
        Profile.get_instance().reset_avatar()

    def set_avatar(self):
        choose = QtGui.QApplication.translate("ProfileSettingsForm",
                                              "Choose avatar", None,
                                              QtGui.QApplication.UnicodeUTF8)
        name = QtGui.QFileDialog.getOpenFileName(self, choose, None,
                                                 'Images (*.png)')
        if name[0]:
            bitmap = QtGui.QPixmap(name[0])
            bitmap.scaled(QtCore.QSize(128, 128),
                          aspectMode=QtCore.Qt.KeepAspectRatio,
                          mode=QtCore.Qt.SmoothTransformation)

            byte_array = QtCore.QByteArray()
            buffer = QtCore.QBuffer(byte_array)
            buffer.open(QtCore.QIODevice.WriteOnly)
            bitmap.save(buffer, 'PNG')
            Profile.get_instance().set_avatar(str(byte_array.data()))

    def export_profile(self):
        directory = QtGui.QFileDialog.getExistingDirectory() + '/'
        if directory != '/':
            ProfileHelper.get_instance().export_profile(directory)
            settings = Settings.get_instance()
            settings.export(directory)
            profile = Profile.get_instance()
            profile.export_history(directory)

    def closeEvent(self, event):
        profile = Profile.get_instance()
        profile.set_name(self.nick.text())
        profile.set_status_message(self.status_message.text().encode('utf-8'))
        profile.set_status(self.status.currentIndex())
Ejemplo n.º 5
0
class NetworkSettings(CenteredWidget):
    """Network settings form: UDP, Ipv6 and proxy"""
    def __init__(self, reset):
        super(NetworkSettings, self).__init__()
        self.reset = reset
        self.initUI()
        self.center()

    def initUI(self):
        self.setObjectName("NetworkSettings")
        self.resize(300, 330)
        self.setMinimumSize(QtCore.QSize(300, 330))
        self.setMaximumSize(QtCore.QSize(300, 330))
        self.setBaseSize(QtCore.QSize(300, 330))
        self.ipv = QtGui.QCheckBox(self)
        self.ipv.setGeometry(QtCore.QRect(20, 10, 97, 22))
        self.ipv.setObjectName("ipv")
        self.udp = QtGui.QCheckBox(self)
        self.udp.setGeometry(QtCore.QRect(150, 10, 97, 22))
        self.udp.setObjectName("udp")
        self.proxy = QtGui.QCheckBox(self)
        self.proxy.setGeometry(QtCore.QRect(20, 40, 97, 22))
        self.http = QtGui.QCheckBox(self)
        self.http.setGeometry(QtCore.QRect(20, 70, 97, 22))
        self.proxy.setObjectName("proxy")
        self.proxyip = LineEdit(self)
        self.proxyip.setGeometry(QtCore.QRect(40, 130, 231, 27))
        self.proxyip.setObjectName("proxyip")
        self.proxyport = LineEdit(self)
        self.proxyport.setGeometry(QtCore.QRect(40, 190, 231, 27))
        self.proxyport.setObjectName("proxyport")
        self.label = QtGui.QLabel(self)
        self.label.setGeometry(QtCore.QRect(40, 100, 66, 17))
        self.label_2 = QtGui.QLabel(self)
        self.label_2.setGeometry(QtCore.QRect(40, 165, 66, 17))
        self.reconnect = QtGui.QPushButton(self)
        self.reconnect.setGeometry(QtCore.QRect(40, 230, 231, 30))
        self.reconnect.clicked.connect(self.restart_core)
        settings = Settings.get_instance()
        self.ipv.setChecked(settings['ipv6_enabled'])
        self.udp.setChecked(settings['udp_enabled'])
        self.proxy.setChecked(settings['proxy_type'])
        self.proxyip.setText(settings['proxy_host'])
        self.proxyport.setText(str(settings['proxy_port']))
        self.http.setChecked(settings['proxy_type'] == 1)
        self.warning = QtGui.QLabel(self)
        self.warning.setGeometry(QtCore.QRect(5, 270, 290, 60))
        self.warning.setStyleSheet('QLabel { color: #BC1C1C; }')
        self.retranslateUi()
        self.proxy.stateChanged.connect(lambda x: self.activate())
        self.activate()
        QtCore.QMetaObject.connectSlotsByName(self)

    def retranslateUi(self):
        self.setWindowTitle(
            QtGui.QApplication.translate("NetworkSettings", "Network settings",
                                         None, QtGui.QApplication.UnicodeUTF8))
        self.ipv.setText(
            QtGui.QApplication.translate("Form", "IPv6", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.udp.setText(
            QtGui.QApplication.translate("Form", "UDP", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.proxy.setText(
            QtGui.QApplication.translate("Form", "Proxy", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.label.setText(
            QtGui.QApplication.translate("Form", "IP:", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.label_2.setText(
            QtGui.QApplication.translate("Form", "Port:", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.reconnect.setText(
            QtGui.QApplication.translate("NetworkSettings", "Restart TOX core",
                                         None, QtGui.QApplication.UnicodeUTF8))
        self.http.setText(
            QtGui.QApplication.translate("Form", "HTTP", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.warning.setText(
            QtGui.QApplication.translate(
                "Form",
                "WARNING:\nusing proxy with enabled UDP\ncan produce IP leak",
                None, QtGui.QApplication.UnicodeUTF8))

    def activate(self):
        bl = self.proxy.isChecked()
        self.proxyip.setEnabled(bl)
        self.http.setEnabled(bl)
        self.proxyport.setEnabled(bl)

    def restart_core(self):
        try:
            settings = Settings.get_instance()
            settings['ipv6_enabled'] = self.ipv.isChecked()
            settings['udp_enabled'] = self.udp.isChecked()
            settings['proxy_type'] = 2 - int(
                self.http.isChecked()) if self.proxy.isChecked() else 0
            settings['proxy_host'] = str(self.proxyip.text())
            settings['proxy_port'] = int(self.proxyport.text())
            settings.save()
            # recreate tox instance
            Profile.get_instance().reset(self.reset)
            self.close()
        except Exception as ex:
            log('Exception in restart: ' + str(ex))
Ejemplo n.º 6
0
class AddContact(CenteredWidget):
    """Add contact form"""
    def __init__(self, tox_id=''):
        super(AddContact, self).__init__()
        self.initUI(tox_id)

    def initUI(self, tox_id):
        self.setObjectName('AddContact')
        self.resize(568, 306)
        self.sendRequestButton = QtGui.QPushButton(self)
        self.sendRequestButton.setGeometry(QtCore.QRect(50, 270, 471, 31))
        self.sendRequestButton.setMinimumSize(QtCore.QSize(0, 0))
        self.sendRequestButton.setBaseSize(QtCore.QSize(0, 0))
        self.sendRequestButton.setObjectName("sendRequestButton")
        self.sendRequestButton.clicked.connect(self.add_friend)
        self.tox_id = LineEdit(self)
        self.tox_id.setGeometry(QtCore.QRect(50, 40, 471, 27))
        self.tox_id.setObjectName("lineEdit")
        self.tox_id.setText(tox_id)
        self.label = QtGui.QLabel(self)
        self.label.setGeometry(QtCore.QRect(50, 10, 80, 20))
        self.error_label = DataLabel(self)
        self.error_label.setGeometry(QtCore.QRect(120, 10, 420, 20))
        font = QtGui.QFont()
        font.setPointSize(10)
        font.setWeight(30)
        self.error_label.setFont(font)
        self.error_label.setStyleSheet("QLabel { color: #BC1C1C; }")
        self.label.setObjectName("label")
        self.message_edit = QtGui.QTextEdit(self)
        self.message_edit.setGeometry(QtCore.QRect(50, 110, 471, 151))
        self.message_edit.setObjectName("textEdit")
        self.message = QtGui.QLabel(self)
        self.message.setGeometry(QtCore.QRect(50, 70, 101, 31))
        self.message.setFont(font)
        self.message.setObjectName("label_2")
        self.retranslateUi()
        self.message_edit.setText('Hello! Add me to your contact list please')
        font = QtGui.QFont()
        font.setPointSize(12)
        font.setBold(True)
        self.label.setFont(font)
        self.message.setFont(font)
        QtCore.QMetaObject.connectSlotsByName(self)

    def add_friend(self):
        profile = Profile.get_instance()
        send = profile.send_friend_request(self.tox_id.text(),
                                           self.message_edit.toPlainText())
        if send is True:
            # request was successful
            self.close()
        else:  # print error data
            self.error_label.setText(send)

    def retranslateUi(self):
        self.setWindowTitle(
            QtGui.QApplication.translate('AddContact', "Add contact", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.sendRequestButton.setText(
            QtGui.QApplication.translate("Form", "Send request", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.label.setText(
            QtGui.QApplication.translate('AddContact', "TOX ID:", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.message.setText(
            QtGui.QApplication.translate('AddContact', "Message:", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.tox_id.setPlaceholderText(
            QtGui.QApplication.translate('AddContact',
                                         "TOX ID or public key of contact",
                                         None, QtGui.QApplication.UnicodeUTF8))
Ejemplo n.º 7
0
class MainWindow(QtGui.QMainWindow, Singleton):
    def __init__(self, tox, reset, tray):
        super().__init__()
        Singleton.__init__(self)
        self.reset = reset
        self.tray = tray
        self.setAcceptDrops(True)
        self.initUI(tox)
        if settings.Settings.get_instance()['show_welcome_screen']:
            self.ws = WelcomeScreen()

    def setup_menu(self, MainWindow):
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setObjectName("menubar")
        self.menubar.setNativeMenuBar(False)
        self.menubar.setMinimumSize(self.width(), 25)
        self.menubar.setMaximumSize(self.width(), 25)
        self.menubar.setBaseSize(self.width(), 25)

        self.menuProfile = QtGui.QMenu(self.menubar)
        self.menuProfile.setObjectName("menuProfile")
        self.menuSettings = QtGui.QMenu(self.menubar)
        self.menuSettings.setObjectName("menuSettings")
        self.menuPlugins = QtGui.QMenu(self.menubar)
        self.menuPlugins.setObjectName("menuPlugins")
        self.menuAbout = QtGui.QMenu(self.menubar)
        self.menuAbout.setObjectName("menuAbout")

        self.actionAdd_friend = QtGui.QAction(MainWindow)
        self.actionAdd_friend.setObjectName("actionAdd_friend")
        self.actionprofilesettings = QtGui.QAction(MainWindow)
        self.actionprofilesettings.setObjectName("actionprofilesettings")
        self.actionPrivacy_settings = QtGui.QAction(MainWindow)
        self.actionPrivacy_settings.setObjectName("actionPrivacy_settings")
        self.actionInterface_settings = QtGui.QAction(MainWindow)
        self.actionInterface_settings.setObjectName("actionInterface_settings")
        self.actionNotifications = QtGui.QAction(MainWindow)
        self.actionNotifications.setObjectName("actionNotifications")
        self.actionNetwork = QtGui.QAction(MainWindow)
        self.actionNetwork.setObjectName("actionNetwork")
        self.actionAbout_program = QtGui.QAction(MainWindow)
        self.actionAbout_program.setObjectName("actionAbout_program")
        self.actionSettings = QtGui.QAction(MainWindow)
        self.actionSettings.setObjectName("actionSettings")
        self.audioSettings = QtGui.QAction(MainWindow)
        self.pluginData = QtGui.QAction(MainWindow)
        self.importPlugin = QtGui.QAction(MainWindow)
        self.lockApp = QtGui.QAction(MainWindow)
        self.menuProfile.addAction(self.actionAdd_friend)
        self.menuProfile.addAction(self.actionSettings)
        self.menuProfile.addAction(self.lockApp)
        self.menuSettings.addAction(self.actionPrivacy_settings)
        self.menuSettings.addAction(self.actionInterface_settings)
        self.menuSettings.addAction(self.actionNotifications)
        self.menuSettings.addAction(self.actionNetwork)
        self.menuSettings.addAction(self.audioSettings)
        self.menuPlugins.addAction(self.pluginData)
        self.menuPlugins.addAction(self.importPlugin)
        self.menuAbout.addAction(self.actionAbout_program)
        self.menubar.addAction(self.menuProfile.menuAction())
        self.menubar.addAction(self.menuSettings.menuAction())
        self.menubar.addAction(self.menuPlugins.menuAction())
        self.menubar.addAction(self.menuAbout.menuAction())

        self.actionAbout_program.triggered.connect(self.about_program)
        self.actionNetwork.triggered.connect(self.network_settings)
        self.actionAdd_friend.triggered.connect(self.add_contact)
        self.actionSettings.triggered.connect(self.profile_settings)
        self.actionPrivacy_settings.triggered.connect(self.privacy_settings)
        self.actionInterface_settings.triggered.connect(
            self.interface_settings)
        self.actionNotifications.triggered.connect(self.notification_settings)
        self.audioSettings.triggered.connect(self.audio_settings)
        self.pluginData.triggered.connect(self.plugins_menu)
        self.lockApp.triggered.connect(self.lock_app)
        self.importPlugin.triggered.connect(self.import_plugin)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def languageChange(self, *args, **kwargs):
        self.retranslateUi()

    def event(self, event):
        if event.type() == QtCore.QEvent.WindowActivate:
            self.tray.setIcon(
                QtGui.QIcon(curr_directory() + '/images/icon.png'))
            self.messages.repaint()
        return super(MainWindow, self).event(event)

    def retranslateUi(self):
        self.lockApp.setText(
            QtGui.QApplication.translate("MainWindow", "Lock", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.menuPlugins.setTitle(
            QtGui.QApplication.translate("MainWindow", "Plugins", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.pluginData.setText(
            QtGui.QApplication.translate("MainWindow", "List of plugins", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.menuProfile.setTitle(
            QtGui.QApplication.translate("MainWindow", "Profile", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.menuSettings.setTitle(
            QtGui.QApplication.translate("MainWindow", "Settings", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.menuAbout.setTitle(
            QtGui.QApplication.translate("MainWindow", "About", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.actionAdd_friend.setText(
            QtGui.QApplication.translate("MainWindow", "Add contact", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.actionprofilesettings.setText(
            QtGui.QApplication.translate("MainWindow", "Profile", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.actionPrivacy_settings.setText(
            QtGui.QApplication.translate("MainWindow", "Privacy", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.actionInterface_settings.setText(
            QtGui.QApplication.translate("MainWindow", "Interface", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.actionNotifications.setText(
            QtGui.QApplication.translate("MainWindow", "Notifications", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.actionNetwork.setText(
            QtGui.QApplication.translate("MainWindow", "Network", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.actionAbout_program.setText(
            QtGui.QApplication.translate("MainWindow", "About program", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.actionSettings.setText(
            QtGui.QApplication.translate("MainWindow", "Settings", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.audioSettings.setText(
            QtGui.QApplication.translate("MainWindow", "Audio", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.contact_name.setPlaceholderText(
            QtGui.QApplication.translate("MainWindow", "Search", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.sendMessageButton.setToolTip(
            QtGui.QApplication.translate("MainWindow", "Send message", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.callButton.setToolTip(
            QtGui.QApplication.translate("MainWindow",
                                         "Start audio call with friend", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.online_contacts.clear()
        self.online_contacts.addItem(
            QtGui.QApplication.translate("MainWindow", "All", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.online_contacts.addItem(
            QtGui.QApplication.translate("MainWindow", "Online", None,
                                         QtGui.QApplication.UnicodeUTF8))
        self.online_contacts.setCurrentIndex(
            int(Settings.get_instance()['show_online_friends']))
        self.importPlugin.setText(
            QtGui.QApplication.translate("MainWindow", "Import plugin", None,
                                         QtGui.QApplication.UnicodeUTF8))

    def setup_right_bottom(self, Form):
        Form.resize(650, 60)
        self.messageEdit = MessageArea(Form, self)
        self.messageEdit.setGeometry(QtCore.QRect(0, 3, 450, 55))
        self.messageEdit.setObjectName("messageEdit")
        font = QtGui.QFont()
        font.setPointSize(11)
        font.setFamily(settings.Settings.get_instance()['font'])
        self.messageEdit.setFont(font)

        self.sendMessageButton = QtGui.QPushButton(Form)
        self.sendMessageButton.setGeometry(QtCore.QRect(565, 3, 60, 55))
        self.sendMessageButton.setObjectName("sendMessageButton")

        self.menuButton = MenuButton(Form, self.show_menu)
        self.menuButton.setGeometry(QtCore.QRect(QtCore.QRect(455, 3, 55, 55)))

        pixmap = QtGui.QPixmap('send.png')
        icon = QtGui.QIcon(pixmap)
        self.sendMessageButton.setIcon(icon)
        self.sendMessageButton.setIconSize(QtCore.QSize(45, 60))

        pixmap = QtGui.QPixmap('menu.png')
        icon = QtGui.QIcon(pixmap)
        self.menuButton.setIcon(icon)
        self.menuButton.setIconSize(QtCore.QSize(40, 40))

        self.sendMessageButton.clicked.connect(self.send_message)

        QtCore.QMetaObject.connectSlotsByName(Form)

    def setup_left_center_menu(self, Form):
        Form.resize(270, 25)
        self.search_label = QtGui.QLabel(Form)
        self.search_label.setGeometry(QtCore.QRect(3, 2, 20, 20))
        pixmap = QtGui.QPixmap()
        pixmap.load(curr_directory() + '/images/search.png')
        self.search_label.setScaledContents(False)
        self.search_label.setPixmap(pixmap)

        self.contact_name = LineEdit(Form)
        self.contact_name.setGeometry(QtCore.QRect(0, 0, 150, 25))
        self.contact_name.setObjectName("contact_name")
        self.contact_name.textChanged.connect(self.filtering)

        self.online_contacts = QtGui.QComboBox(Form)
        self.online_contacts.setGeometry(QtCore.QRect(150, 0, 120, 25))
        self.online_contacts.activated[int].connect(lambda x: self.filtering())
        self.search_label.raise_()

        QtCore.QMetaObject.connectSlotsByName(Form)

    def setup_left_top(self, Form):
        Form.setCursor(QtCore.Qt.PointingHandCursor)
        Form.setMinimumSize(QtCore.QSize(270, 100))
        Form.setMaximumSize(QtCore.QSize(270, 100))
        Form.setBaseSize(QtCore.QSize(270, 100))
        self.avatar_label = Form.avatar_label = QtGui.QLabel(Form)
        self.avatar_label.setGeometry(QtCore.QRect(5, 30, 64, 64))
        self.avatar_label.setScaledContents(False)
        self.avatar_label.setAlignment(QtCore.Qt.AlignCenter)
        self.name = Form.name = DataLabel(Form)
        Form.name.setGeometry(QtCore.QRect(75, 40, 150, 25))
        font = QtGui.QFont()
        font.setFamily(settings.Settings.get_instance()['font'])
        font.setPointSize(14)
        font.setBold(True)
        Form.name.setFont(font)
        Form.name.setObjectName("name")
        self.status_message = Form.status_message = DataLabel(Form)
        Form.status_message.setGeometry(QtCore.QRect(75, 60, 170, 25))
        font.setPointSize(12)
        font.setBold(False)
        Form.status_message.setFont(font)
        Form.status_message.setObjectName("status_message")
        self.connection_status = Form.connection_status = StatusCircle(Form)
        Form.connection_status.setGeometry(QtCore.QRect(230, 35, 32, 32))
        self.avatar_label.mouseReleaseEvent = self.profile_settings
        self.status_message.mouseReleaseEvent = self.profile_settings
        self.name.mouseReleaseEvent = self.profile_settings
        self.connection_status.raise_()
        Form.connection_status.setObjectName("connection_status")

    def setup_right_top(self, Form):
        Form.resize(650, 100)
        self.account_avatar = QtGui.QLabel(Form)
        self.account_avatar.setGeometry(QtCore.QRect(10, 30, 64, 64))
        self.account_avatar.setScaledContents(False)
        self.account_name = DataLabel(Form)
        self.account_name.setGeometry(QtCore.QRect(100, 25, 400, 25))
        self.account_name.setTextInteractionFlags(
            QtCore.Qt.LinksAccessibleByMouse)
        font = QtGui.QFont()
        font.setFamily(settings.Settings.get_instance()['font'])
        font.setPointSize(14)
        font.setBold(True)
        self.account_name.setFont(font)
        self.account_name.setObjectName("account_name")
        self.account_status = DataLabel(Form)
        self.account_status.setGeometry(QtCore.QRect(100, 45, 400, 25))
        self.account_status.setTextInteractionFlags(
            QtCore.Qt.LinksAccessibleByMouse)
        font.setPointSize(12)
        font.setBold(False)
        self.account_status.setFont(font)
        self.account_status.setObjectName("account_status")
        self.callButton = QtGui.QPushButton(Form)
        self.callButton.setGeometry(QtCore.QRect(550, 30, 50, 50))
        self.callButton.setObjectName("callButton")
        self.callButton.clicked.connect(lambda: self.profile.call_click(True))
        self.videocallButton = QtGui.QPushButton(Form)
        self.videocallButton.setGeometry(QtCore.QRect(550, 30, 50, 50))
        self.videocallButton.setObjectName("videocallButton")
        self.videocallButton.clicked.connect(
            lambda: self.profile.call_click(True, True))
        self.update_call_state('call')
        self.typing = QtGui.QLabel(Form)
        self.typing.setGeometry(QtCore.QRect(500, 50, 50, 30))
        pixmap = QtGui.QPixmap(QtCore.QSize(50, 30))
        pixmap.load(curr_directory() + '/images/typing.png')
        self.typing.setScaledContents(False)
        self.typing.setPixmap(pixmap.scaled(50, 30, QtCore.Qt.KeepAspectRatio))
        self.typing.setVisible(False)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def setup_left_center(self, widget):
        self.friends_list = QtGui.QListWidget(widget)
        self.friends_list.setObjectName("friends_list")
        self.friends_list.setGeometry(0, 0, 270, 310)
        self.friends_list.clicked.connect(self.friend_click)
        self.friends_list.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.friends_list.connect(
            self.friends_list,
            QtCore.SIGNAL("customContextMenuRequested(QPoint)"),
            self.friend_right_click)
        self.friends_list.setVerticalScrollMode(
            QtGui.QAbstractItemView.ScrollPerPixel)

    def setup_right_center(self, widget):
        self.messages = QtGui.QListWidget(widget)
        self.messages.setGeometry(0, 0, 620, 310)
        self.messages.setObjectName("messages")
        self.messages.setSpacing(1)
        self.messages.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.messages.setHorizontalScrollBarPolicy(
            QtCore.Qt.ScrollBarAlwaysOff)
        self.messages.focusOutEvent = lambda event: self.messages.clearSelection(
        )

        def load(pos):
            if not pos:
                self.profile.load_history()
                self.messages.verticalScrollBar().setValue(1)

        self.messages.verticalScrollBar().valueChanged.connect(load)
        self.messages.setVerticalScrollMode(
            QtGui.QAbstractItemView.ScrollPerPixel)
        self.messages.setSelectionMode(
            QtGui.QAbstractItemView.ExtendedSelection)

    def initUI(self, tox):
        self.setMinimumSize(920, 500)
        s = Settings.get_instance()
        self.setGeometry(s['x'], s['y'], s['width'], s['height'])
        self.setWindowTitle('Toxygen')
        os.chdir(curr_directory() + '/images/')
        main = QtGui.QWidget()
        grid = QtGui.QGridLayout()
        search = QtGui.QWidget()
        name = QtGui.QWidget()
        info = QtGui.QWidget()
        main_list = QtGui.QWidget()
        messages = QtGui.QWidget()
        message_buttons = QtGui.QWidget()
        self.setup_left_center_menu(search)
        self.setup_left_top(name)
        self.setup_right_center(messages)
        self.setup_right_top(info)
        self.setup_right_bottom(message_buttons)
        self.setup_left_center(main_list)
        if not Settings.get_instance()['mirror_mode']:
            grid.addWidget(search, 1, 0)
            grid.addWidget(name, 0, 0)
            grid.addWidget(messages, 1, 1, 2, 1)
            grid.addWidget(info, 0, 1)
            grid.addWidget(message_buttons, 3, 1)
            grid.addWidget(main_list, 2, 0, 2, 1)
            grid.setColumnMinimumWidth(1, 500)
            grid.setColumnMinimumWidth(0, 270)
        else:
            grid.addWidget(search, 1, 1)
            grid.addWidget(name, 0, 1)
            grid.addWidget(messages, 1, 0, 2, 1)
            grid.addWidget(info, 0, 0)
            grid.addWidget(message_buttons, 3, 0)
            grid.addWidget(main_list, 2, 1, 2, 1)
            grid.setColumnMinimumWidth(0, 500)
            grid.setColumnMinimumWidth(1, 270)
        grid.setSpacing(0)
        grid.setContentsMargins(0, 0, 0, 0)
        grid.setRowMinimumHeight(0, 100)
        grid.setRowMinimumHeight(1, 25)
        grid.setRowMinimumHeight(2, 320)
        grid.setRowMinimumHeight(3, 55)
        grid.setColumnStretch(1, 1)
        grid.setRowStretch(2, 1)
        main.setLayout(grid)
        self.setCentralWidget(main)
        self.setup_menu(self)
        self.messageEdit.setFocus()
        self.user_info = name
        self.friend_info = info
        self.retranslateUi()
        self.profile = Profile(tox, self)

    def closeEvent(self, event):
        s = Settings.get_instance()
        if not s['close_to_tray'] or s.closing:
            self.profile.save_history()
            self.profile.close()
            s['x'] = self.geometry().x()
            s['y'] = self.geometry().y()
            s['width'] = self.width()
            s['height'] = self.height()
            s.save()
            QtGui.QApplication.closeAllWindows()
            event.accept()
        else:
            event.ignore()
            self.hide()

    def resizeEvent(self, *args, **kwargs):
        self.messages.setGeometry(0, 0,
                                  self.width() - 270,
                                  self.height() - 155)
        self.friends_list.setGeometry(0, 0, 270, self.height() - 125)

        self.videocallButton.setGeometry(
            QtCore.QRect(self.width() - 330, 40, 50, 50))
        self.callButton.setGeometry(
            QtCore.QRect(self.width() - 390, 40, 50, 50))
        self.typing.setGeometry(QtCore.QRect(self.width() - 450, 50, 50, 30))

        self.messageEdit.setGeometry(
            QtCore.QRect(55, 0,
                         self.width() - 395, 55))
        self.menuButton.setGeometry(QtCore.QRect(0, 0, 55, 55))
        self.sendMessageButton.setGeometry(
            QtCore.QRect(self.width() - 340, 0, 70, 55))

        self.account_name.setGeometry(
            QtCore.QRect(100, 40,
                         self.width() - 560, 25))
        self.account_status.setGeometry(
            QtCore.QRect(100, 60,
                         self.width() - 560, 25))
        self.messageEdit.setFocus()
        self.profile.update()

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Escape:
            self.hide()
        elif event.key() == QtCore.Qt.Key_C and event.modifiers(
        ) & QtCore.Qt.ControlModifier and self.messages.selectedIndexes():
            rows = list(
                map(lambda x: self.messages.row(x),
                    self.messages.selectedItems()))
            indexes = (rows[0] - self.messages.count(),
                       rows[-1] - self.messages.count())
            s = self.profile.export_history(self.profile.active_friend, True,
                                            indexes)
            clipboard = QtGui.QApplication.clipboard()
            clipboard.setText(s)
        elif event.key() == QtCore.Qt.Key_Z and event.modifiers(
        ) & QtCore.Qt.ControlModifier and self.messages.selectedIndexes():
            self.messages.clearSelection()
        else:
            super(MainWindow, self).keyPressEvent(event)

    # -----------------------------------------------------------------------------------------------------------------
    # Functions which called when user click in menu
    # -----------------------------------------------------------------------------------------------------------------

    def about_program(self):
        import util
        msgBox = QtGui.QMessageBox()
        msgBox.setWindowTitle(
            QtGui.QApplication.translate("MainWindow", "About", None,
                                         QtGui.QApplication.UnicodeUTF8))
        text = (QtGui.QApplication.translate(
            "MainWindow",
            'Toxygen is Tox client written on Python.\nVersion: ', None,
            QtGui.QApplication.UnicodeUTF8))
        msgBox.setText(text + util.program_version +
                       '\nGitHub: https://github.com/toxygen-project/toxygen/')
        msgBox.exec_()

    def network_settings(self):
        self.n_s = NetworkSettings(self.reset)
        self.n_s.show()

    def plugins_menu(self):
        self.p_s = PluginsSettings()
        self.p_s.show()

    def add_contact(self, link=''):
        self.a_c = AddContact(link or '')
        self.a_c.show()

    def profile_settings(self, *args):
        self.p_s = ProfileSettings()
        self.p_s.show()

    def privacy_settings(self):
        self.priv_s = PrivacySettings()
        self.priv_s.show()

    def notification_settings(self):
        self.notif_s = NotificationsSettings()
        self.notif_s.show()

    def interface_settings(self):
        self.int_s = InterfaceSettings()
        self.int_s.show()

    def audio_settings(self):
        self.audio_s = AudioSettings()
        self.audio_s.show()

    def import_plugin(self):
        import util
        directory = QtGui.QFileDialog.getExistingDirectory(
            self,
            QtGui.QApplication.translate("MainWindow",
                                         'Choose folder with plugin', None,
                                         QtGui.QApplication.UnicodeUTF8),
            util.curr_directory(), QtGui.QFileDialog.ShowDirsOnly
            | QtGui.QFileDialog.DontUseNativeDialog)
        if directory:
            src = directory + '/'
            dest = curr_directory() + '/plugins/'
            util.copy(src, dest)
            msgBox = QtGui.QMessageBox()
            msgBox.setWindowTitle(
                QtGui.QApplication.translate("MainWindow", "Restart Toxygen",
                                             None,
                                             QtGui.QApplication.UnicodeUTF8))
            msgBox.setText(
                QtGui.QApplication.translate(
                    "MainWindow", 'Plugin will be loaded after restart', None,
                    QtGui.QApplication.UnicodeUTF8))
            msgBox.exec_()

    def lock_app(self):
        if toxencryptsave.ToxEncryptSave.get_instance().has_password():
            Settings.get_instance().locked = True
            self.hide()
        else:
            msgBox = QtGui.QMessageBox()
            msgBox.setWindowTitle(
                QtGui.QApplication.translate("MainWindow", "Cannot lock app",
                                             None,
                                             QtGui.QApplication.UnicodeUTF8))
            msgBox.setText(
                QtGui.QApplication.translate(
                    "MainWindow", 'Error. Profile password is not set.', None,
                    QtGui.QApplication.UnicodeUTF8))
            msgBox.exec_()

    def show_menu(self):
        if not hasattr(self, 'menu'):
            self.menu = DropdownMenu(self)
        self.menu.setGeometry(
            QtCore.QRect(0 if Settings.get_instance()['mirror_mode'] else 270,
                         self.height() - 120, 180, 120))
        self.menu.show()

    # -----------------------------------------------------------------------------------------------------------------
    # Messages, calls and file transfers
    # -----------------------------------------------------------------------------------------------------------------

    def send_message(self):
        text = self.messageEdit.toPlainText()
        self.profile.send_message(text)

    def send_file(self):
        self.menu.hide()
        if self.profile.active_friend + 1:
            choose = QtGui.QApplication.translate(
                "MainWindow", 'Choose file', None,
                QtGui.QApplication.UnicodeUTF8)
            name = QtGui.QFileDialog.getOpenFileName(
                self, choose, options=QtGui.QFileDialog.DontUseNativeDialog)
            if name[0]:
                self.profile.send_file(name[0])

    def send_screenshot(self, hide=False):
        self.menu.hide()
        if self.profile.active_friend + 1:
            self.sw = ScreenShotWindow(self)
            self.sw.show()
            if hide:
                self.hide()

    def send_smiley(self):
        self.menu.hide()
        if self.profile.active_friend + 1:
            self.smiley = SmileyWindow(self)
            self.smiley.setGeometry(
                QtCore.QRect(
                    self.x() if Settings.get_instance()['mirror_mode'] else
                    270 + self.x(),
                    self.y() + self.height() - 200, self.smiley.width(),
                    self.smiley.height()))
            self.smiley.show()

    def send_sticker(self):
        self.menu.hide()
        if self.profile.active_friend + 1:
            self.sticker = StickerWindow(self)
            self.sticker.setGeometry(
                QtCore.QRect(
                    self.x() if Settings.get_instance()['mirror_mode'] else
                    270 + self.x(),
                    self.y() + self.height() - 200, self.sticker.width(),
                    self.sticker.height()))
            self.sticker.show()

    def active_call(self):
        self.update_call_state('finish_call')

    def incoming_call(self):
        self.update_call_state('incoming_call')

    def call_finished(self):
        self.update_call_state('call')

    def update_call_state(self, fl):
        # TODO: do smth with video call button
        os.chdir(curr_directory() + '/images/')
        pixmap = QtGui.QPixmap(curr_directory() + '/images/{}.png'.format(fl))
        icon = QtGui.QIcon(pixmap)
        self.callButton.setIcon(icon)
        self.callButton.setIconSize(QtCore.QSize(50, 50))
        pixmap = QtGui.QPixmap(curr_directory() + '/images/videocall.png')
        icon = QtGui.QIcon(pixmap)
        self.videocallButton.setIcon(icon)
        self.videocallButton.setIconSize(QtCore.QSize(35, 35))

    # -----------------------------------------------------------------------------------------------------------------
    # Functions which called when user open context menu in friends list
    # -----------------------------------------------------------------------------------------------------------------

    def friend_right_click(self, pos):
        item = self.friends_list.itemAt(pos)
        num = self.friends_list.indexFromItem(item).row()
        friend = Profile.get_instance().get_friend(num)
        settings = Settings.get_instance()
        allowed = friend.tox_id in settings['auto_accept_from_friends']
        auto = QtGui.QApplication.translate(
            "MainWindow", 'Disallow auto accept', None, QtGui.QApplication.
            UnicodeUTF8) if allowed else QtGui.QApplication.translate(
                "MainWindow", 'Allow auto accept', None,
                QtGui.QApplication.UnicodeUTF8)
        if item is not None:
            self.listMenu = QtGui.QMenu()
            set_alias_item = self.listMenu.addAction(
                QtGui.QApplication.translate("MainWindow", 'Set alias', None,
                                             QtGui.QApplication.UnicodeUTF8))

            history_menu = self.listMenu.addMenu(
                QtGui.QApplication.translate("MainWindow", 'Chat history',
                                             None,
                                             QtGui.QApplication.UnicodeUTF8))
            clear_history_item = history_menu.addAction(
                QtGui.QApplication.translate("MainWindow", 'Clear history',
                                             None,
                                             QtGui.QApplication.UnicodeUTF8))
            export_to_text_item = history_menu.addAction(
                QtGui.QApplication.translate("MainWindow", 'Export as text',
                                             None,
                                             QtGui.QApplication.UnicodeUTF8))
            export_to_html_item = history_menu.addAction(
                QtGui.QApplication.translate("MainWindow", 'Export as HTML',
                                             None,
                                             QtGui.QApplication.UnicodeUTF8))

            copy_menu = self.listMenu.addMenu(
                QtGui.QApplication.translate("MainWindow", 'Copy', None,
                                             QtGui.QApplication.UnicodeUTF8))
            copy_name_item = copy_menu.addAction(
                QtGui.QApplication.translate("MainWindow", 'Name', None,
                                             QtGui.QApplication.UnicodeUTF8))
            copy_status_item = copy_menu.addAction(
                QtGui.QApplication.translate("MainWindow", 'Status message',
                                             None,
                                             QtGui.QApplication.UnicodeUTF8))
            copy_key_item = copy_menu.addAction(
                QtGui.QApplication.translate("MainWindow", 'Public key', None,
                                             QtGui.QApplication.UnicodeUTF8))

            auto_accept_item = self.listMenu.addAction(auto)
            remove_item = self.listMenu.addAction(
                QtGui.QApplication.translate("MainWindow", 'Remove friend',
                                             None,
                                             QtGui.QApplication.UnicodeUTF8))
            notes_item = self.listMenu.addAction(
                QtGui.QApplication.translate("MainWindow", 'Notes', None,
                                             QtGui.QApplication.UnicodeUTF8))

            submenu = plugin_support.PluginLoader.get_instance().get_menu(
                self.listMenu, num)
            if len(submenu):
                plug = self.listMenu.addMenu(
                    QtGui.QApplication.translate(
                        "MainWindow", 'Plugins', None,
                        QtGui.QApplication.UnicodeUTF8))
                plug.addActions(submenu)
            self.connect(set_alias_item, QtCore.SIGNAL("triggered()"),
                         lambda: self.set_alias(num))
            self.connect(remove_item, QtCore.SIGNAL("triggered()"),
                         lambda: self.remove_friend(num))
            self.connect(copy_key_item, QtCore.SIGNAL("triggered()"),
                         lambda: self.copy_friend_key(num))
            self.connect(clear_history_item, QtCore.SIGNAL("triggered()"),
                         lambda: self.clear_history(num))
            self.connect(auto_accept_item, QtCore.SIGNAL("triggered()"),
                         lambda: self.auto_accept(num, not allowed))
            self.connect(notes_item, QtCore.SIGNAL("triggered()"),
                         lambda: self.show_note(friend))
            self.connect(copy_name_item, QtCore.SIGNAL("triggered()"),
                         lambda: self.copy_name(friend))
            self.connect(copy_status_item, QtCore.SIGNAL("triggered()"),
                         lambda: self.copy_status(friend))
            self.connect(export_to_text_item, QtCore.SIGNAL("triggered()"),
                         lambda: self.export_history(num))
            self.connect(export_to_html_item, QtCore.SIGNAL("triggered()"),
                         lambda: self.export_history(num, False))
            parent_position = self.friends_list.mapToGlobal(QtCore.QPoint(
                0, 0))
            self.listMenu.move(parent_position + pos)
            self.listMenu.show()

    def show_note(self, friend):
        s = Settings.get_instance()
        note = s['notes'][friend.tox_id] if friend.tox_id in s['notes'] else ''
        user = QtGui.QApplication.translate("MainWindow", 'Notes about user',
                                            None,
                                            QtGui.QApplication.UnicodeUTF8)
        user = '******'.format(user, friend.name)

        def save_note(text):
            if friend.tox_id in s['notes']:
                del s['notes'][friend.tox_id]
            if text:
                s['notes'][friend.tox_id] = text
            s.save()

        self.note = MultilineEdit(user, note, save_note)
        self.note.show()

    def export_history(self, num, as_text=True):
        s = self.profile.export_history(num, as_text)
        directory = QtGui.QFileDialog.getExistingDirectory(
            None,
            QtGui.QApplication.translate("MainWindow", 'Choose folder', None,
                                         QtGui.QApplication.UnicodeUTF8),
            curr_directory(), QtGui.QFileDialog.ShowDirsOnly
            | QtGui.QFileDialog.DontUseNativeDialog)

        if directory:
            name = 'exported_history_{}.{}'.format(
                convert_time(time.time()), 'txt' if as_text else 'html')
            with open(directory + '/' + name, 'wt') as fl:
                fl.write(s)

    def set_alias(self, num):
        self.profile.set_alias(num)

    def remove_friend(self, num):
        self.profile.delete_friend(num)

    def copy_friend_key(self, num):
        tox_id = self.profile.friend_public_key(num)
        clipboard = QtGui.QApplication.clipboard()
        clipboard.setText(tox_id)

    def copy_name(self, friend):
        clipboard = QtGui.QApplication.clipboard()
        clipboard.setText(friend.name)

    def copy_status(self, friend):
        clipboard = QtGui.QApplication.clipboard()
        clipboard.setText(friend.status_message)

    def clear_history(self, num):
        self.profile.clear_history(num)

    def auto_accept(self, num, value):
        settings = Settings.get_instance()
        tox_id = self.profile.friend_public_key(num)
        if value:
            settings['auto_accept_from_friends'].append(tox_id)
        else:
            settings['auto_accept_from_friends'].remove(tox_id)
        settings.save()

    # -----------------------------------------------------------------------------------------------------------------
    # Functions which called when user click somewhere else
    # -----------------------------------------------------------------------------------------------------------------

    def friend_click(self, index):
        num = index.row()
        self.profile.set_active(num)

    def mouseReleaseEvent(self, event):
        pos = self.connection_status.pos()
        x, y = pos.x() + self.user_info.pos().x(), pos.y(
        ) + self.user_info.pos().y()
        if (x < event.x() < x + 32) and (y < event.y() < y + 32):
            self.profile.change_status()
        else:
            super(MainWindow, self).mouseReleaseEvent(event)

    def filtering(self):
        self.profile.filtration(self.online_contacts.currentIndex() == 1,
                                self.contact_name.text())
Ejemplo n.º 8
0
class MainWindow(QtGui.QMainWindow):

    def __init__(self, tox, reset, tray):
        super(MainWindow, self).__init__()
        self.reset = reset
        self.tray = tray
        self.setAcceptDrops(True)
        self.initUI(tox)
        if settings.Settings.get_instance()['show_welcome_screen']:
            self.ws = WelcomeScreen()

    def setup_menu(self, MainWindow):
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setObjectName("menubar")
        self.menubar.setNativeMenuBar(False)
        self.menubar.setMinimumSize(self.width(), 25)
        self.menubar.setMaximumSize(self.width(), 25)
        self.menubar.setBaseSize(self.width(), 25)

        self.menuProfile = QtGui.QMenu(self.menubar)
        self.menuProfile.setObjectName("menuProfile")
        self.menuSettings = QtGui.QMenu(self.menubar)
        self.menuSettings.setObjectName("menuSettings")
        self.menuPlugins = QtGui.QMenu(self.menubar)
        self.menuPlugins.setObjectName("menuPlugins")
        self.menuAbout = QtGui.QMenu(self.menubar)
        self.menuAbout.setObjectName("menuAbout")

        self.actionAdd_friend = QtGui.QAction(MainWindow)
        self.actionAdd_friend.setObjectName("actionAdd_friend")
        self.actionprofilesettings = QtGui.QAction(MainWindow)
        self.actionprofilesettings.setObjectName("actionprofilesettings")
        self.actionPrivacy_settings = QtGui.QAction(MainWindow)
        self.actionPrivacy_settings.setObjectName("actionPrivacy_settings")
        self.actionInterface_settings = QtGui.QAction(MainWindow)
        self.actionInterface_settings.setObjectName("actionInterface_settings")
        self.actionNotifications = QtGui.QAction(MainWindow)
        self.actionNotifications.setObjectName("actionNotifications")
        self.actionNetwork = QtGui.QAction(MainWindow)
        self.actionNetwork.setObjectName("actionNetwork")
        self.actionAbout_program = QtGui.QAction(MainWindow)
        self.actionAbout_program.setObjectName("actionAbout_program")
        self.actionSettings = QtGui.QAction(MainWindow)
        self.actionSettings.setObjectName("actionSettings")
        self.audioSettings = QtGui.QAction(MainWindow)
        self.pluginData = QtGui.QAction(MainWindow)
        self.importPlugin = QtGui.QAction(MainWindow)
        self.lockApp = QtGui.QAction(MainWindow)
        self.menuProfile.addAction(self.actionAdd_friend)
        self.menuProfile.addAction(self.actionSettings)
        self.menuProfile.addAction(self.lockApp)
        self.menuSettings.addAction(self.actionPrivacy_settings)
        self.menuSettings.addAction(self.actionInterface_settings)
        self.menuSettings.addAction(self.actionNotifications)
        self.menuSettings.addAction(self.actionNetwork)
        self.menuSettings.addAction(self.audioSettings)
        self.menuPlugins.addAction(self.pluginData)
        self.menuPlugins.addAction(self.importPlugin)
        self.menuAbout.addAction(self.actionAbout_program)
        self.menubar.addAction(self.menuProfile.menuAction())
        self.menubar.addAction(self.menuSettings.menuAction())
        self.menubar.addAction(self.menuPlugins.menuAction())
        self.menubar.addAction(self.menuAbout.menuAction())

        self.actionAbout_program.triggered.connect(self.about_program)
        self.actionNetwork.triggered.connect(self.network_settings)
        self.actionAdd_friend.triggered.connect(self.add_contact)
        self.actionSettings.triggered.connect(self.profilesettings)
        self.actionPrivacy_settings.triggered.connect(self.privacy_settings)
        self.actionInterface_settings.triggered.connect(self.interface_settings)
        self.actionNotifications.triggered.connect(self.notification_settings)
        self.audioSettings.triggered.connect(self.audio_settings)
        self.pluginData.triggered.connect(self.plugins_menu)
        self.lockApp.triggered.connect(self.lock_app)
        self.importPlugin.triggered.connect(self.import_plugin)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def languageChange(self, *args, **kwargs):
        self.retranslateUi()

    def event(self, event):
        if event.type() == QtCore.QEvent.WindowActivate:
            self.tray.setIcon(QtGui.QIcon(curr_directory() + '/images/icon.png'))
        return super(MainWindow, self).event(event)

    def retranslateUi(self):
        self.lockApp.setText(QtGui.QApplication.translate("MainWindow", "Lock", None, QtGui.QApplication.UnicodeUTF8))
        self.menuPlugins.setTitle(QtGui.QApplication.translate("MainWindow", "Plugins", None, QtGui.QApplication.UnicodeUTF8))
        self.pluginData.setText(QtGui.QApplication.translate("MainWindow", "List of plugins", None, QtGui.QApplication.UnicodeUTF8))
        self.menuProfile.setTitle(QtGui.QApplication.translate("MainWindow", "Profile", None, QtGui.QApplication.UnicodeUTF8))
        self.menuSettings.setTitle(QtGui.QApplication.translate("MainWindow", "Settings", None, QtGui.QApplication.UnicodeUTF8))
        self.menuAbout.setTitle(QtGui.QApplication.translate("MainWindow", "About", None, QtGui.QApplication.UnicodeUTF8))
        self.actionAdd_friend.setText(QtGui.QApplication.translate("MainWindow", "Add contact", None, QtGui.QApplication.UnicodeUTF8))
        self.actionprofilesettings.setText(QtGui.QApplication.translate("MainWindow", "Profile", None, QtGui.QApplication.UnicodeUTF8))
        self.actionPrivacy_settings.setText(QtGui.QApplication.translate("MainWindow", "Privacy", None, QtGui.QApplication.UnicodeUTF8))
        self.actionInterface_settings.setText(QtGui.QApplication.translate("MainWindow", "Interface", None, QtGui.QApplication.UnicodeUTF8))
        self.actionNotifications.setText(QtGui.QApplication.translate("MainWindow", "Notifications", None, QtGui.QApplication.UnicodeUTF8))
        self.actionNetwork.setText(QtGui.QApplication.translate("MainWindow", "Network", None, QtGui.QApplication.UnicodeUTF8))
        self.actionAbout_program.setText(QtGui.QApplication.translate("MainWindow", "About program", None, QtGui.QApplication.UnicodeUTF8))
        self.actionSettings.setText(QtGui.QApplication.translate("MainWindow", "Settings", None, QtGui.QApplication.UnicodeUTF8))
        self.audioSettings.setText(QtGui.QApplication.translate("MainWindow", "Audio", None, QtGui.QApplication.UnicodeUTF8))
        self.contact_name.setPlaceholderText(QtGui.QApplication.translate("MainWindow", "Search", None, QtGui.QApplication.UnicodeUTF8))
        self.sendMessageButton.setToolTip(QtGui.QApplication.translate("MainWindow", "Send message", None, QtGui.QApplication.UnicodeUTF8))
        self.callButton.setToolTip(QtGui.QApplication.translate("MainWindow", "Start audio call with friend", None, QtGui.QApplication.UnicodeUTF8))
        self.online_contacts.clear()
        self.online_contacts.addItem(QtGui.QApplication.translate("MainWindow", "All", None, QtGui.QApplication.UnicodeUTF8))
        self.online_contacts.addItem(QtGui.QApplication.translate("MainWindow", "Online", None, QtGui.QApplication.UnicodeUTF8))
        self.online_contacts.setCurrentIndex(int(Settings.get_instance()['show_online_friends']))
        self.importPlugin.setText(QtGui.QApplication.translate("MainWindow", "Import plugin", None, QtGui.QApplication.UnicodeUTF8))

    def setup_right_bottom(self, Form):
        Form.resize(650, 60)
        self.messageEdit = MessageArea(Form, self)
        self.messageEdit.setGeometry(QtCore.QRect(0, 3, 450, 55))
        self.messageEdit.setObjectName("messageEdit")
        font = QtGui.QFont()
        font.setPointSize(10)
        self.messageEdit.setFont(font)

        self.sendMessageButton = QtGui.QPushButton(Form)
        self.sendMessageButton.setGeometry(QtCore.QRect(565, 3, 60, 55))
        self.sendMessageButton.setObjectName("sendMessageButton")

        self.menuButton = MenuButton(Form, self.show_menu)
        self.menuButton.setGeometry(QtCore.QRect(QtCore.QRect(455, 3, 55, 55)))

        pixmap = QtGui.QPixmap('send.png')
        icon = QtGui.QIcon(pixmap)
        self.sendMessageButton.setIcon(icon)
        self.sendMessageButton.setIconSize(QtCore.QSize(45, 60))

        pixmap = QtGui.QPixmap('menu.png')
        icon = QtGui.QIcon(pixmap)
        self.menuButton.setIcon(icon)
        self.menuButton.setIconSize(QtCore.QSize(40, 40))

        self.sendMessageButton.clicked.connect(self.send_message)

        QtCore.QMetaObject.connectSlotsByName(Form)

    def setup_left_center_menu(self, Form):
        Form.resize(270, 25)
        self.search_label = QtGui.QLabel(Form)
        self.search_label.setGeometry(QtCore.QRect(3, 2, 20, 20))
        pixmap = QtGui.QPixmap()
        pixmap.load(curr_directory() + '/images/search.png')
        self.search_label.setScaledContents(False)
        self.search_label.setPixmap(pixmap)

        self.contact_name = LineEdit(Form)
        self.contact_name.setGeometry(QtCore.QRect(0, 0, 150, 25))
        self.contact_name.setObjectName("contact_name")
        self.contact_name.textChanged.connect(self.filtering)

        self.online_contacts = QtGui.QComboBox(Form)
        self.online_contacts.setGeometry(QtCore.QRect(150, 0, 120, 25))
        self.online_contacts.activated[int].connect(lambda x: self.filtering())
        self.search_label.raise_()

        QtCore.QMetaObject.connectSlotsByName(Form)

    def setup_left_top(self, Form):
        Form.setCursor(QtCore.Qt.PointingHandCursor)
        Form.setMinimumSize(QtCore.QSize(270, 100))
        Form.setMaximumSize(QtCore.QSize(270, 100))
        Form.setBaseSize(QtCore.QSize(270, 100))
        self.avatar_label = Form.avatar_label = QtGui.QLabel(Form)
        self.avatar_label.setGeometry(QtCore.QRect(5, 30, 64, 64))
        self.avatar_label.setScaledContents(True)
        self.avatar_label.setAlignment(QtCore.Qt.AlignCenter)
        self.name = Form.name = DataLabel(Form)
        Form.name.setGeometry(QtCore.QRect(75, 40, 150, 25))
        font = QtGui.QFont()
        font.setFamily("Times New Roman")
        font.setPointSize(14)
        font.setBold(True)
        Form.name.setFont(font)
        Form.name.setObjectName("name")
        self.status_message = Form.status_message = DataLabel(Form)
        Form.status_message.setGeometry(QtCore.QRect(75, 60, 170, 25))
        font.setPointSize(12)
        font.setBold(False)
        Form.status_message.setFont(font)
        Form.status_message.setObjectName("status_message")
        self.connection_status = Form.connection_status = StatusCircle(Form)
        Form.connection_status.setGeometry(QtCore.QRect(230, 35, 32, 32))
        self.avatar_label.mouseReleaseEvent = self.profilesettings
        self.status_message.mouseReleaseEvent = self.profilesettings
        self.name.mouseReleaseEvent = self.profilesettings
        self.connection_status.raise_()
        Form.connection_status.setObjectName("connection_status")

    def setup_right_top(self, Form):
        Form.resize(650, 100)
        self.account_avatar = QtGui.QLabel(Form)
        self.account_avatar.setGeometry(QtCore.QRect(10, 30, 64, 64))
        self.account_avatar.setScaledContents(True)
        self.account_name = DataLabel(Form)
        self.account_name.setGeometry(QtCore.QRect(100, 25, 400, 25))
        self.account_name.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse)
        font = QtGui.QFont()
        font.setFamily("Times New Roman")
        font.setPointSize(14)
        font.setBold(True)
        self.account_name.setFont(font)
        self.account_name.setObjectName("account_name")
        self.account_status = DataLabel(Form)
        self.account_status.setGeometry(QtCore.QRect(100, 45, 400, 25))
        self.account_status.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse)
        font.setPointSize(12)
        font.setBold(False)
        self.account_status.setFont(font)
        self.account_status.setObjectName("account_status")
        self.callButton = QtGui.QPushButton(Form)
        self.callButton.setGeometry(QtCore.QRect(550, 30, 50, 50))
        self.callButton.setObjectName("callButton")
        self.callButton.clicked.connect(lambda: self.profile.call_click(True))
        self.videocallButton = QtGui.QPushButton(Form)
        self.videocallButton.setGeometry(QtCore.QRect(550, 30, 50, 50))
        self.videocallButton.setObjectName("videocallButton")
        self.videocallButton.clicked.connect(lambda: self.profile.call_click(True, True))
        self.update_call_state('call')
        self.typing = QtGui.QLabel(Form)
        self.typing.setGeometry(QtCore.QRect(500, 50, 50, 30))
        pixmap = QtGui.QPixmap(QtCore.QSize(50, 30))
        pixmap.load(curr_directory() + '/images/typing.png')
        self.typing.setScaledContents(False)
        self.typing.setPixmap(pixmap.scaled(50, 30, QtCore.Qt.KeepAspectRatio))
        self.typing.setVisible(False)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def setup_left_center(self, widget):
        self.friends_list = QtGui.QListWidget(widget)
        self.friends_list.setObjectName("friends_list")
        self.friends_list.setGeometry(0, 0, 270, 310)
        self.friends_list.clicked.connect(self.friend_click)
        self.friends_list.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.friends_list.connect(self.friends_list, QtCore.SIGNAL("customContextMenuRequested(QPoint)"),
                                  self.friend_right_click)
        self.friends_list.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)

    def setup_right_center(self, widget):
        self.messages = QtGui.QListWidget(widget)
        self.messages.setGeometry(0, 0, 620, 310)
        self.messages.setObjectName("messages")
        self.messages.setSpacing(1)
        self.messages.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.messages.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.messages.setFocusPolicy(QtCore.Qt.NoFocus)

        def load(pos):
            if not pos:
                self.profile.load_history()
                self.messages.verticalScrollBar().setValue(1)
        self.messages.verticalScrollBar().valueChanged.connect(load)
        self.messages.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)

    def initUI(self, tox):
        self.setMinimumSize(920, 500)
        s = Settings.get_instance()
        self.setGeometry(s['x'], s['y'], s['width'], s['height'])
        self.setWindowTitle('Toxygen')
        os.chdir(curr_directory() + '/images/')
        main = QtGui.QWidget()
        grid = QtGui.QGridLayout()
        search = QtGui.QWidget()
        name = QtGui.QWidget()
        info = QtGui.QWidget()
        main_list = QtGui.QWidget()
        messages = QtGui.QWidget()
        message_buttons = QtGui.QWidget()
        self.setup_left_center_menu(search)
        self.setup_left_top(name)
        self.setup_right_center(messages)
        self.setup_right_top(info)
        self.setup_right_bottom(message_buttons)
        self.setup_left_center(main_list)
        if not Settings.get_instance()['mirror_mode']:
            grid.addWidget(search, 1, 0)
            grid.addWidget(name, 0, 0)
            grid.addWidget(messages, 1, 1, 2, 1)
            grid.addWidget(info, 0, 1)
            grid.addWidget(message_buttons, 3, 1)
            grid.addWidget(main_list, 2, 0, 2, 1)
            grid.setColumnMinimumWidth(1, 500)
            grid.setColumnMinimumWidth(0, 270)
        else:
            grid.addWidget(search, 1, 1)
            grid.addWidget(name, 0, 1)
            grid.addWidget(messages, 1, 0, 2, 1)
            grid.addWidget(info, 0, 0)
            grid.addWidget(message_buttons, 3, 0)
            grid.addWidget(main_list, 2, 1, 2, 1)
            grid.setColumnMinimumWidth(0, 500)
            grid.setColumnMinimumWidth(1, 270)
        grid.setSpacing(0)
        grid.setContentsMargins(0, 0, 0, 0)
        grid.setRowMinimumHeight(0, 100)
        grid.setRowMinimumHeight(1, 25)
        grid.setRowMinimumHeight(2, 320)
        grid.setRowMinimumHeight(3, 55)
        grid.setColumnStretch(1, 1)
        grid.setRowStretch(2, 1)
        main.setLayout(grid)
        self.setCentralWidget(main)
        self.setup_menu(self)
        self.messageEdit.setFocus()
        self.user_info = name
        self.friend_info = info
        self.retranslateUi()
        self.profile = Profile(tox, self)

    def closeEvent(self, *args, **kwargs):
        self.profile.save_history()
        self.profile.close()
        s = Settings.get_instance()
        s['x'] = self.pos().x()
        s['y'] = self.pos().y()
        s['width'] = self.width()
        s['height'] = self.height()
        s.save()
        QtGui.QApplication.closeAllWindows()

    def resizeEvent(self, *args, **kwargs):
        self.messages.setGeometry(0, 0, self.width() - 270, self.height() - 155)
        self.friends_list.setGeometry(0, 0, 270, self.height() - 125)

        self.videocallButton.setGeometry(QtCore.QRect(self.width() - 330, 40, 50, 50))
        self.callButton.setGeometry(QtCore.QRect(self.width() - 390, 40, 50, 50))
        self.typing.setGeometry(QtCore.QRect(self.width() - 450, 50, 50, 30))

        self.messageEdit.setGeometry(QtCore.QRect(55, 0, self.width() - 395, 55))
        self.menuButton.setGeometry(QtCore.QRect(0, 0, 55, 55))
        self.sendMessageButton.setGeometry(QtCore.QRect(self.width() - 340, 0, 70, 55))

        self.account_name.setGeometry(QtCore.QRect(100, 40, self.width() - 560, 25))
        self.account_status.setGeometry(QtCore.QRect(100, 60, self.width() - 560, 25))
        self.messageEdit.setFocus()
        self.profile.update()

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Escape:
            self.hide()
        else:
            super(MainWindow, self).keyPressEvent(event)

    # -----------------------------------------------------------------------------------------------------------------
    # Functions which called when user click in menu
    # -----------------------------------------------------------------------------------------------------------------

    def about_program(self):
        import util
        msgBox = QtGui.QMessageBox()
        msgBox.setWindowTitle(QtGui.QApplication.translate("MainWindow", "About", None, QtGui.QApplication.UnicodeUTF8))
        text = (QtGui.QApplication.translate("MainWindow", 'Toxygen is Tox client written on Python.\nVersion: ', None, QtGui.QApplication.UnicodeUTF8))
        msgBox.setText(text + util.program_version + '\nGitHub: github.com/xveduk/toxygen/')
        msgBox.exec_()

    def network_settings(self):
        self.n_s = NetworkSettings(self.reset)
        self.n_s.show()

    def plugins_menu(self):
        self.p_s = PluginsSettings()
        self.p_s.show()

    def add_contact(self, link=''):
        self.a_c = AddContact(link)
        self.a_c.show()

    def profilesettings(self, *args):
        self.p_s = ProfileSettings()
        self.p_s.show()

    def privacy_settings(self):
        self.priv_s = PrivacySettings()
        self.priv_s.show()

    def notification_settings(self):
        self.notif_s = NotificationsSettings()
        self.notif_s.show()

    def interface_settings(self):
        self.int_s = InterfaceSettings()
        self.int_s.show()

    def audio_settings(self):
        self.audio_s = AudioSettings()
        self.audio_s.show()

    def import_plugin(self):
        import util
        directory = QtGui.QFileDialog.getExistingDirectory(self,
                                                           QtGui.QApplication.translate("MainWindow", 'Choose folder with plugin',
                                                                                        None,
                                                                                        QtGui.QApplication.UnicodeUTF8),
                                                           util.curr_directory(),
                                                           QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontUseNativeDialog)
        if directory:
            src = directory + '/'
            dest = curr_directory() + '/plugins/'
            util.copy(src, dest)
            msgBox = QtGui.QMessageBox()
            msgBox.setWindowTitle(
                QtGui.QApplication.translate("MainWindow", "Restart Toxygen", None, QtGui.QApplication.UnicodeUTF8))
            msgBox.setText(
                QtGui.QApplication.translate("MainWindow", 'Plugin will be loaded after restart', None,
                                             QtGui.QApplication.UnicodeUTF8))
            msgBox.exec_()

    def lock_app(self):
        if toxencryptsave.ToxEncryptSave.get_instance().has_password():
            Settings.get_instance().locked = True
            self.hide()
        else:
            msgBox = QtGui.QMessageBox()
            msgBox.setWindowTitle(
                QtGui.QApplication.translate("MainWindow", "Cannot lock app", None, QtGui.QApplication.UnicodeUTF8))
            msgBox.setText(
                QtGui.QApplication.translate("MainWindow", 'Error. Profile password is not set.', None,
                                             QtGui.QApplication.UnicodeUTF8))
            msgBox.exec_()

    def show_menu(self):
        if not hasattr(self, 'menu'):
            self.menu = DropdownMenu(self)
        self.menu.setGeometry(QtCore.QRect(0 if Settings.get_instance()['mirror_mode'] else 270,
                                           self.height() - 120,
                                           180,
                                           120))
        self.menu.show()

    # -----------------------------------------------------------------------------------------------------------------
    # Messages, calls and file transfers
    # -----------------------------------------------------------------------------------------------------------------

    def send_message(self):
        text = self.messageEdit.toPlainText()
        self.profile.send_message(text)

    def send_file(self):
        self.menu.hide()
        if self.profile.active_friend + 1:
            choose = QtGui.QApplication.translate("MainWindow", 'Choose file', None, QtGui.QApplication.UnicodeUTF8)
            name = QtGui.QFileDialog.getOpenFileName(self, choose, options=QtGui.QFileDialog.DontUseNativeDialog)
            if name[0]:
                self.profile.send_file(name[0])

    def send_screenshot(self, hide=False):
        self.menu.hide()
        if self.profile.active_friend + 1:
            self.sw = ScreenShotWindow(self)
            self.sw.show()
            if hide:
                self.hide()

    def send_smiley(self):
        self.menu.hide()
        if self.profile.active_friend + 1:
            self.smiley = SmileyWindow(self)
            self.smiley.setGeometry(QtCore.QRect(self.x() if Settings.get_instance()['mirror_mode'] else 270 + self.x(),
                                                 self.y() + self.height() - 200,
                                                 self.smiley.width(),
                                                 self.smiley.height()))
            self.smiley.show()

    def send_sticker(self):
        self.menu.hide()
        if self.profile.active_friend + 1:
            self.sticker = StickerWindow(self)
            self.sticker.setGeometry(QtCore.QRect(self.x() if Settings.get_instance()['mirror_mode'] else 270 + self.x(),
                                                 self.y() + self.height() - 200,
                                                 self.sticker.width(),
                                                 self.sticker.height()))
            self.sticker.show()

    def active_call(self):
        self.update_call_state('finish_call')

    def incoming_call(self):
        self.update_call_state('incoming_call')

    def call_finished(self):
        self.update_call_state('call')

    def update_call_state(self, fl):
        # TODO: do smth with video call button
        os.chdir(curr_directory() + '/images/')
        pixmap = QtGui.QPixmap(curr_directory() + '/images/{}.png'.format(fl))
        icon = QtGui.QIcon(pixmap)
        self.callButton.setIcon(icon)
        self.callButton.setIconSize(QtCore.QSize(50, 50))
        pixmap = QtGui.QPixmap(curr_directory() + '/images/videocall.png')
        icon = QtGui.QIcon(pixmap)
        self.videocallButton.setIcon(icon)
        self.videocallButton.setIconSize(QtCore.QSize(35, 35))

    # -----------------------------------------------------------------------------------------------------------------
    # Functions which called when user open context menu in friends list
    # -----------------------------------------------------------------------------------------------------------------

    def friend_right_click(self, pos):
        item = self.friends_list.itemAt(pos)
        num = self.friends_list.indexFromItem(item).row()
        friend = Profile.get_instance().get_friend(num)
        settings = Settings.get_instance()
        allowed = friend.tox_id in settings['auto_accept_from_friends']
        auto = QtGui.QApplication.translate("MainWindow", 'Disallow auto accept', None, QtGui.QApplication.UnicodeUTF8) if allowed else QtGui.QApplication.translate("MainWindow", 'Allow auto accept', None, QtGui.QApplication.UnicodeUTF8)
        if item is not None:
            self.listMenu = QtGui.QMenu()
            set_alias_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Set alias', None, QtGui.QApplication.UnicodeUTF8))
            clear_history_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Clear history', None, QtGui.QApplication.UnicodeUTF8))
            copy_menu = self.listMenu.addMenu(QtGui.QApplication.translate("MainWindow", 'Copy', None, QtGui.QApplication.UnicodeUTF8))
            copy_name_item = copy_menu.addAction(QtGui.QApplication.translate("MainWindow", 'Name', None, QtGui.QApplication.UnicodeUTF8))
            copy_status_item = copy_menu.addAction(QtGui.QApplication.translate("MainWindow", 'Status message', None, QtGui.QApplication.UnicodeUTF8))
            copy_key_item = copy_menu.addAction(QtGui.QApplication.translate("MainWindow", 'Public key', None, QtGui.QApplication.UnicodeUTF8))

            auto_accept_item = self.listMenu.addAction(auto)
            remove_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Remove friend', None, QtGui.QApplication.UnicodeUTF8))
            notes_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Notes', None, QtGui.QApplication.UnicodeUTF8))

            submenu = plugin_support.PluginLoader.get_instance().get_menu(self.listMenu, num)
            if len(submenu):
                plug = self.listMenu.addMenu(QtGui.QApplication.translate("MainWindow", 'Plugins', None, QtGui.QApplication.UnicodeUTF8))
                plug.addActions(submenu)
            self.connect(set_alias_item, QtCore.SIGNAL("triggered()"), lambda: self.set_alias(num))
            self.connect(remove_item, QtCore.SIGNAL("triggered()"), lambda: self.remove_friend(num))
            self.connect(copy_key_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_friend_key(num))
            self.connect(clear_history_item, QtCore.SIGNAL("triggered()"), lambda: self.clear_history(num))
            self.connect(auto_accept_item, QtCore.SIGNAL("triggered()"), lambda: self.auto_accept(num, not allowed))
            self.connect(notes_item, QtCore.SIGNAL("triggered()"), lambda: self.show_note(friend))
            self.connect(copy_name_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_name(friend))
            self.connect(copy_status_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_status(friend))
            parent_position = self.friends_list.mapToGlobal(QtCore.QPoint(0, 0))
            self.listMenu.move(parent_position + pos)
            self.listMenu.show()

    def show_note(self, friend):
        s = Settings.get_instance()
        note = s['notes'][friend.tox_id] if friend.tox_id in s['notes'] else ''
        user = QtGui.QApplication.translate("MainWindow", 'Notes about user', None, QtGui.QApplication.UnicodeUTF8)
        user = '******'.format(user, friend.name)

        def save_note(text):
            if friend.tox_id in s['notes']:
                del s['notes'][friend.tox_id]
            if text:
                s['notes'][friend.tox_id] = text
            s.save()
        self.note = MultilineEdit(user, note, save_note)
        self.note.show()

    def set_alias(self, num):
        self.profile.set_alias(num)

    def remove_friend(self, num):
        self.profile.delete_friend(num)

    def copy_friend_key(self, num):
        tox_id = self.profile.friend_public_key(num)
        clipboard = QtGui.QApplication.clipboard()
        clipboard.setText(tox_id)

    def copy_name(self, friend):
        clipboard = QtGui.QApplication.clipboard()
        clipboard.setText(friend.name)

    def copy_status(self, friend):
        clipboard = QtGui.QApplication.clipboard()
        clipboard.setText(friend.status_message)

    def clear_history(self, num):
        self.profile.clear_history(num)

    def auto_accept(self, num, value):
        settings = Settings.get_instance()
        tox_id = self.profile.friend_public_key(num)
        if value:
            settings['auto_accept_from_friends'].append(tox_id)
        else:
            settings['auto_accept_from_friends'].remove(tox_id)
        settings.save()

    # -----------------------------------------------------------------------------------------------------------------
    # Functions which called when user click somewhere else
    # -----------------------------------------------------------------------------------------------------------------

    def friend_click(self, index):
        num = index.row()
        self.profile.set_active(num)

    def mouseReleaseEvent(self, event):
        pos = self.connection_status.pos()
        x, y = pos.x() + self.user_info.pos().x(), pos.y() + self.user_info.pos().y()
        if (x < event.x() < x + 32) and (y < event.y() < y + 32):
            self.profile.change_status()
        else:
            super(MainWindow, self).mouseReleaseEvent(event)

    def filtering(self):
        self.profile.filtration(self.online_contacts.currentIndex() == 1, self.contact_name.text())
Ejemplo n.º 9
0
class MainWindow(QtGui.QMainWindow, Singleton):
    def __init__(self, tox, reset, tray):
        super().__init__()
        Singleton.__init__(self)
        self.reset = reset
        self.tray = tray
        self.setAcceptDrops(True)
        self.initUI(tox)
        self._saved = False
        if settings.Settings.get_instance()["show_welcome_screen"]:
            self.ws = WelcomeScreen()

    def setup_menu(self, Form):
        box = QtGui.QHBoxLayout()
        box.setContentsMargins(0, 0, 0, 0)
        box.setAlignment(QtCore.Qt.AlignLeft)
        self.profile_button = MainMenuButton(Form)
        box.addWidget(self.profile_button)
        self.settings_button = MainMenuButton(Form)
        box.addWidget(self.settings_button)
        self.plugins_button = MainMenuButton(Form)
        box.addWidget(self.plugins_button)
        self.about_button = MainMenuButton(Form)
        box.addWidget(self.about_button)
        box.setSpacing(0)

        self.menuProfile = QtGui.QMenu()
        self.menuProfile.setObjectName("menuProfile")
        self.menuSettings = QtGui.QMenu()
        self.menuSettings.setObjectName("menuSettings")
        self.menuPlugins = QtGui.QMenu()
        self.menuPlugins.setObjectName("menuPlugins")
        self.menuAbout = QtGui.QMenu()
        self.menuAbout.setObjectName("menuAbout")

        self.actionAdd_friend = QtGui.QAction(Form)
        self.actionAdd_friend.setObjectName("actionAdd_friend")
        self.actionprofilesettings = QtGui.QAction(Form)
        self.actionprofilesettings.setObjectName("actionprofilesettings")
        self.actionPrivacy_settings = QtGui.QAction(Form)
        self.actionPrivacy_settings.setObjectName("actionPrivacy_settings")
        self.actionInterface_settings = QtGui.QAction(Form)
        self.actionInterface_settings.setObjectName("actionInterface_settings")
        self.actionNotifications = QtGui.QAction(Form)
        self.actionNotifications.setObjectName("actionNotifications")
        self.actionNetwork = QtGui.QAction(Form)
        self.actionNetwork.setObjectName("actionNetwork")
        self.actionAbout_program = QtGui.QAction(Form)
        self.actionAbout_program.setObjectName("actionAbout_program")
        self.updateSettings = QtGui.QAction(Form)
        self.actionSettings = QtGui.QAction(Form)
        self.actionSettings.setObjectName("actionSettings")
        self.audioSettings = QtGui.QAction(Form)
        self.pluginData = QtGui.QAction(Form)
        self.importPlugin = QtGui.QAction(Form)
        self.lockApp = QtGui.QAction(Form)
        self.menuProfile.addAction(self.actionAdd_friend)
        self.menuProfile.addAction(self.actionSettings)
        self.menuProfile.addAction(self.lockApp)
        self.menuSettings.addAction(self.actionPrivacy_settings)
        self.menuSettings.addAction(self.actionInterface_settings)
        self.menuSettings.addAction(self.actionNotifications)
        self.menuSettings.addAction(self.actionNetwork)
        self.menuSettings.addAction(self.audioSettings)
        self.menuSettings.addAction(self.updateSettings)
        self.menuPlugins.addAction(self.pluginData)
        self.menuPlugins.addAction(self.importPlugin)
        self.menuAbout.addAction(self.actionAbout_program)

        self.profile_button.setMenu(self.menuProfile)
        self.settings_button.setMenu(self.menuSettings)
        self.plugins_button.setMenu(self.menuPlugins)
        self.about_button.setMenu(self.menuAbout)

        self.actionAbout_program.triggered.connect(self.about_program)
        self.actionNetwork.triggered.connect(self.network_settings)
        self.actionAdd_friend.triggered.connect(self.add_contact)
        self.actionSettings.triggered.connect(self.profile_settings)
        self.actionPrivacy_settings.triggered.connect(self.privacy_settings)
        self.actionInterface_settings.triggered.connect(self.interface_settings)
        self.actionNotifications.triggered.connect(self.notification_settings)
        self.audioSettings.triggered.connect(self.audio_settings)
        self.updateSettings.triggered.connect(self.update_settings)
        self.pluginData.triggered.connect(self.plugins_menu)
        self.lockApp.triggered.connect(self.lock_app)
        self.importPlugin.triggered.connect(self.import_plugin)

        Form.setLayout(box)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def languageChange(self, *args, **kwargs):
        self.retranslateUi()

    def event(self, event):
        if event.type() == QtCore.QEvent.WindowActivate:
            self.tray.setIcon(QtGui.QIcon(curr_directory() + "/images/icon.png"))
            self.messages.repaint()
        return super(MainWindow, self).event(event)

    def retranslateUi(self):
        self.lockApp.setText(QtGui.QApplication.translate("MainWindow", "Lock", None, QtGui.QApplication.UnicodeUTF8))
        self.plugins_button.setText(
            QtGui.QApplication.translate("MainWindow", "Plugins", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.pluginData.setText(
            QtGui.QApplication.translate("MainWindow", "List of plugins", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.profile_button.setText(
            QtGui.QApplication.translate("MainWindow", "Profile", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.settings_button.setText(
            QtGui.QApplication.translate("MainWindow", "Settings", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.about_button.setText(
            QtGui.QApplication.translate("MainWindow", "About", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.actionAdd_friend.setText(
            QtGui.QApplication.translate("MainWindow", "Add contact", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.actionprofilesettings.setText(
            QtGui.QApplication.translate("MainWindow", "Profile", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.actionPrivacy_settings.setText(
            QtGui.QApplication.translate("MainWindow", "Privacy", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.actionInterface_settings.setText(
            QtGui.QApplication.translate("MainWindow", "Interface", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.actionNotifications.setText(
            QtGui.QApplication.translate("MainWindow", "Notifications", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.actionNetwork.setText(
            QtGui.QApplication.translate("MainWindow", "Network", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.actionAbout_program.setText(
            QtGui.QApplication.translate("MainWindow", "About program", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.actionSettings.setText(
            QtGui.QApplication.translate("MainWindow", "Settings", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.audioSettings.setText(
            QtGui.QApplication.translate("MainWindow", "Audio", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.updateSettings.setText(
            QtGui.QApplication.translate("MainWindow", "Updates", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.contact_name.setPlaceholderText(
            QtGui.QApplication.translate("MainWindow", "Search", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.sendMessageButton.setToolTip(
            QtGui.QApplication.translate("MainWindow", "Send message", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.callButton.setToolTip(
            QtGui.QApplication.translate(
                "MainWindow", "Start audio call with friend", None, QtGui.QApplication.UnicodeUTF8
            )
        )
        self.online_contacts.clear()
        self.online_contacts.addItem(
            QtGui.QApplication.translate("MainWindow", "All", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.online_contacts.addItem(
            QtGui.QApplication.translate("MainWindow", "Online", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.online_contacts.addItem(
            QtGui.QApplication.translate("MainWindow", "Online first", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.online_contacts.addItem(
            QtGui.QApplication.translate("MainWindow", "Name", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.online_contacts.addItem(
            QtGui.QApplication.translate("MainWindow", "Online and by name", None, QtGui.QApplication.UnicodeUTF8)
        )
        self.online_contacts.addItem(
            QtGui.QApplication.translate("MainWindow", "Online first and by name", None, QtGui.QApplication.UnicodeUTF8)
        )
        ind = Settings.get_instance()["sorting"]
        d = {0: 0, 1: 1, 2: 2, 3: 4, 1 | 4: 4, 2 | 4: 5}
        self.online_contacts.setCurrentIndex(d[ind])
        self.importPlugin.setText(
            QtGui.QApplication.translate("MainWindow", "Import plugin", None, QtGui.QApplication.UnicodeUTF8)
        )

    def setup_right_bottom(self, Form):
        Form.resize(650, 60)
        self.messageEdit = MessageArea(Form, self)
        self.messageEdit.setGeometry(QtCore.QRect(0, 3, 450, 55))
        self.messageEdit.setObjectName("messageEdit")
        font = QtGui.QFont()
        font.setPointSize(11)
        font.setFamily(settings.Settings.get_instance()["font"])
        self.messageEdit.setFont(font)

        self.sendMessageButton = QtGui.QPushButton(Form)
        self.sendMessageButton.setGeometry(QtCore.QRect(565, 3, 60, 55))
        self.sendMessageButton.setObjectName("sendMessageButton")

        self.menuButton = MenuButton(Form, self.show_menu)
        self.menuButton.setGeometry(QtCore.QRect(QtCore.QRect(455, 3, 55, 55)))

        pixmap = QtGui.QPixmap("send.png")
        icon = QtGui.QIcon(pixmap)
        self.sendMessageButton.setIcon(icon)
        self.sendMessageButton.setIconSize(QtCore.QSize(45, 60))

        pixmap = QtGui.QPixmap("menu.png")
        icon = QtGui.QIcon(pixmap)
        self.menuButton.setIcon(icon)
        self.menuButton.setIconSize(QtCore.QSize(40, 40))

        self.sendMessageButton.clicked.connect(self.send_message)

        QtCore.QMetaObject.connectSlotsByName(Form)

    def setup_left_center_menu(self, Form):
        Form.resize(270, 25)
        self.search_label = QtGui.QLabel(Form)
        self.search_label.setGeometry(QtCore.QRect(3, 2, 20, 20))
        pixmap = QtGui.QPixmap()
        pixmap.load(curr_directory() + "/images/search.png")
        self.search_label.setScaledContents(False)
        self.search_label.setPixmap(pixmap)

        self.contact_name = LineEdit(Form)
        self.contact_name.setGeometry(QtCore.QRect(0, 0, 150, 25))
        self.contact_name.setObjectName("contact_name")
        self.contact_name.textChanged.connect(self.filtering)

        self.online_contacts = ComboBox(Form)
        self.online_contacts.setGeometry(QtCore.QRect(150, 0, 120, 25))
        self.online_contacts.activated[int].connect(lambda x: self.filtering())
        self.search_label.raise_()

        QtCore.QMetaObject.connectSlotsByName(Form)

    def setup_left_top(self, Form):
        Form.setCursor(QtCore.Qt.PointingHandCursor)
        Form.setMinimumSize(QtCore.QSize(270, 75))
        Form.setMaximumSize(QtCore.QSize(270, 75))
        Form.setBaseSize(QtCore.QSize(270, 75))
        self.avatar_label = Form.avatar_label = QtGui.QLabel(Form)
        self.avatar_label.setGeometry(QtCore.QRect(5, 5, 64, 64))
        self.avatar_label.setScaledContents(False)
        self.avatar_label.setAlignment(QtCore.Qt.AlignCenter)
        self.name = Form.name = DataLabel(Form)
        Form.name.setGeometry(QtCore.QRect(75, 15, 150, 25))
        font = QtGui.QFont()
        font.setFamily(settings.Settings.get_instance()["font"])
        font.setPointSize(14)
        font.setBold(True)
        Form.name.setFont(font)
        Form.name.setObjectName("name")
        self.status_message = Form.status_message = DataLabel(Form)
        Form.status_message.setGeometry(QtCore.QRect(75, 35, 170, 25))
        font.setPointSize(12)
        font.setBold(False)
        Form.status_message.setFont(font)
        Form.status_message.setObjectName("status_message")
        self.connection_status = Form.connection_status = StatusCircle(Form)
        Form.connection_status.setGeometry(QtCore.QRect(230, 10, 32, 32))
        self.avatar_label.mouseReleaseEvent = self.profile_settings
        self.status_message.mouseReleaseEvent = self.profile_settings
        self.name.mouseReleaseEvent = self.profile_settings
        self.connection_status.raise_()
        Form.connection_status.setObjectName("connection_status")

    def setup_right_top(self, Form):
        Form.resize(650, 75)
        self.account_avatar = QtGui.QLabel(Form)
        self.account_avatar.setGeometry(QtCore.QRect(10, 5, 64, 64))
        self.account_avatar.setScaledContents(False)
        self.account_name = DataLabel(Form)
        self.account_name.setGeometry(QtCore.QRect(100, 0, 400, 25))
        self.account_name.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse)
        font = QtGui.QFont()
        font.setFamily(settings.Settings.get_instance()["font"])
        font.setPointSize(14)
        font.setBold(True)
        self.account_name.setFont(font)
        self.account_name.setObjectName("account_name")
        self.account_status = DataLabel(Form)
        self.account_status.setGeometry(QtCore.QRect(100, 20, 400, 25))
        self.account_status.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse)
        font.setPointSize(12)
        font.setBold(False)
        self.account_status.setFont(font)
        self.account_status.setObjectName("account_status")
        self.callButton = QtGui.QPushButton(Form)
        self.callButton.setGeometry(QtCore.QRect(550, 5, 50, 50))
        self.callButton.setObjectName("callButton")
        self.callButton.clicked.connect(lambda: self.profile.call_click(True))
        self.videocallButton = QtGui.QPushButton(Form)
        self.videocallButton.setGeometry(QtCore.QRect(550, 5, 50, 50))
        self.videocallButton.setObjectName("videocallButton")
        self.videocallButton.clicked.connect(lambda: self.profile.call_click(True, True))
        self.update_call_state("call")
        self.typing = QtGui.QLabel(Form)
        self.typing.setGeometry(QtCore.QRect(500, 25, 50, 30))
        pixmap = QtGui.QPixmap(QtCore.QSize(50, 30))
        pixmap.load(curr_directory() + "/images/typing.png")
        self.typing.setScaledContents(False)
        self.typing.setPixmap(pixmap.scaled(50, 30, QtCore.Qt.KeepAspectRatio))
        self.typing.setVisible(False)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def setup_left_center(self, widget):
        self.friends_list = QtGui.QListWidget(widget)
        self.friends_list.setObjectName("friends_list")
        self.friends_list.setGeometry(0, 0, 270, 310)
        self.friends_list.clicked.connect(self.friend_click)
        self.friends_list.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.friends_list.connect(
            self.friends_list, QtCore.SIGNAL("customContextMenuRequested(QPoint)"), self.friend_right_click
        )
        self.friends_list.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
        self.friends_list.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.friends_list.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.friends_list.verticalScrollBar().setContextMenuPolicy(QtCore.Qt.NoContextMenu)

    def setup_right_center(self, widget):
        self.messages = QtGui.QListWidget(widget)
        self.messages.setGeometry(0, 0, 620, 310)
        self.messages.setObjectName("messages")
        self.messages.setSpacing(1)
        self.messages.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.messages.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.messages.focusOutEvent = lambda event: self.messages.clearSelection()
        self.messages.verticalScrollBar().setContextMenuPolicy(QtCore.Qt.NoContextMenu)

        def load(pos):
            if not pos:
                self.profile.load_history()
                self.messages.verticalScrollBar().setValue(1)

        self.messages.verticalScrollBar().valueChanged.connect(load)
        self.messages.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
        self.messages.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)

    def initUI(self, tox):
        self.setMinimumSize(920, 500)
        s = Settings.get_instance()
        self.setGeometry(s["x"], s["y"], s["width"], s["height"])
        self.setWindowTitle("Toxygen")
        os.chdir(curr_directory() + "/images/")
        menu = QtGui.QWidget()
        main = QtGui.QWidget()
        grid = QtGui.QGridLayout()
        search = QtGui.QWidget()
        name = QtGui.QWidget()
        info = QtGui.QWidget()
        main_list = QtGui.QWidget()
        messages = QtGui.QWidget()
        message_buttons = QtGui.QWidget()
        self.setup_left_center_menu(search)
        self.setup_left_top(name)
        self.setup_right_center(messages)
        self.setup_right_top(info)
        self.setup_right_bottom(message_buttons)
        self.setup_left_center(main_list)
        self.setup_menu(menu)
        if not Settings.get_instance()["mirror_mode"]:
            grid.addWidget(search, 2, 0)
            grid.addWidget(name, 1, 0)
            grid.addWidget(messages, 2, 1, 2, 1)
            grid.addWidget(info, 1, 1)
            grid.addWidget(message_buttons, 4, 1)
            grid.addWidget(main_list, 3, 0, 2, 1)
            grid.setColumnMinimumWidth(1, 500)
            grid.setColumnMinimumWidth(0, 270)
        else:
            grid.addWidget(search, 2, 1)
            grid.addWidget(name, 1, 1)
            grid.addWidget(messages, 2, 0, 2, 1)
            grid.addWidget(info, 1, 0)
            grid.addWidget(message_buttons, 4, 0)
            grid.addWidget(main_list, 3, 1, 2, 1)
            grid.setColumnMinimumWidth(0, 500)
            grid.setColumnMinimumWidth(1, 270)

        grid.addWidget(menu, 0, 0, 1, 2)
        grid.setSpacing(0)
        grid.setContentsMargins(0, 0, 0, 0)
        grid.setRowMinimumHeight(0, 25)
        grid.setRowMinimumHeight(1, 75)
        grid.setRowMinimumHeight(2, 25)
        grid.setRowMinimumHeight(3, 320)
        grid.setRowMinimumHeight(4, 55)
        grid.setColumnStretch(1, 1)
        grid.setRowStretch(3, 1)
        main.setLayout(grid)
        self.setCentralWidget(main)
        self.messageEdit.setFocus()
        self.user_info = name
        self.friend_info = info
        self.retranslateUi()
        self.profile = Profile(tox, self)

    def closeEvent(self, event):
        s = Settings.get_instance()
        if not s["close_to_tray"] or s.closing:
            if not self._saved:
                self._saved = True
                self.profile.save_history()
                self.profile.close()
                s["x"] = self.geometry().x()
                s["y"] = self.geometry().y()
                s["width"] = self.width()
                s["height"] = self.height()
                s.save()
                QtGui.QApplication.closeAllWindows()
                event.accept()
        elif QtGui.QSystemTrayIcon.isSystemTrayAvailable():
            event.ignore()
            self.hide()

    def close_window(self):
        Settings.get_instance().closing = True
        self.close()

    def resizeEvent(self, *args, **kwargs):
        self.messages.setGeometry(0, 0, self.width() - 270, self.height() - 159)
        self.friends_list.setGeometry(0, 0, 270, self.height() - 129)

        self.videocallButton.setGeometry(QtCore.QRect(self.width() - 330, 10, 50, 50))
        self.callButton.setGeometry(QtCore.QRect(self.width() - 390, 10, 50, 50))
        self.typing.setGeometry(QtCore.QRect(self.width() - 450, 20, 50, 30))

        self.messageEdit.setGeometry(QtCore.QRect(55, 0, self.width() - 395, 55))
        self.menuButton.setGeometry(QtCore.QRect(0, 0, 55, 55))
        self.sendMessageButton.setGeometry(QtCore.QRect(self.width() - 340, 0, 70, 55))

        self.account_name.setGeometry(QtCore.QRect(100, 15, self.width() - 560, 25))
        self.account_status.setGeometry(QtCore.QRect(100, 35, self.width() - 560, 25))
        self.messageEdit.setFocus()
        self.profile.update()

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Escape and QtGui.QSystemTrayIcon.isSystemTrayAvailable():
            self.hide()
        elif (
            event.key() == QtCore.Qt.Key_C
            and event.modifiers() & QtCore.Qt.ControlModifier
            and self.messages.selectedIndexes()
        ):
            rows = list(map(lambda x: self.messages.row(x), self.messages.selectedItems()))
            indexes = (rows[0] - self.messages.count(), rows[-1] - self.messages.count())
            s = self.profile.export_history(self.profile.active_friend, True, indexes)
            clipboard = QtGui.QApplication.clipboard()
            clipboard.setText(s)
        elif (
            event.key() == QtCore.Qt.Key_Z
            and event.modifiers() & QtCore.Qt.ControlModifier
            and self.messages.selectedIndexes()
        ):
            self.messages.clearSelection()
        else:
            super(MainWindow, self).keyPressEvent(event)

    # -----------------------------------------------------------------------------------------------------------------
    # Functions which called when user click in menu
    # -----------------------------------------------------------------------------------------------------------------

    def about_program(self):
        import util

        msgBox = QtGui.QMessageBox()
        msgBox.setWindowTitle(QtGui.QApplication.translate("MainWindow", "About", None, QtGui.QApplication.UnicodeUTF8))
        text = QtGui.QApplication.translate(
            "MainWindow", "Toxygen is Tox client written on Python.\nVersion: ", None, QtGui.QApplication.UnicodeUTF8
        )
        msgBox.setText(text + util.program_version + "\nGitHub: https://github.com/toxygen-project/toxygen/")
        msgBox.exec_()

    def network_settings(self):
        self.n_s = NetworkSettings(self.reset)
        self.n_s.show()

    def plugins_menu(self):
        self.p_s = PluginsSettings()
        self.p_s.show()

    def add_contact(self, link=""):
        self.a_c = AddContact(link or "")
        self.a_c.show()

    def profile_settings(self, *args):
        self.p_s = ProfileSettings()
        self.p_s.show()

    def privacy_settings(self):
        self.priv_s = PrivacySettings()
        self.priv_s.show()

    def notification_settings(self):
        self.notif_s = NotificationsSettings()
        self.notif_s.show()

    def interface_settings(self):
        self.int_s = InterfaceSettings()
        self.int_s.show()

    def audio_settings(self):
        self.audio_s = AudioSettings()
        self.audio_s.show()

    def update_settings(self):
        self.update_s = UpdateSettings()
        self.update_s.show()

    def import_plugin(self):
        import util

        directory = QtGui.QFileDialog.getExistingDirectory(
            self,
            QtGui.QApplication.translate(
                "MainWindow", "Choose folder with plugin", None, QtGui.QApplication.UnicodeUTF8
            ),
            util.curr_directory(),
            QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontUseNativeDialog,
        )
        if directory:
            src = directory + "/"
            dest = curr_directory() + "/plugins/"
            util.copy(src, dest)
            msgBox = QtGui.QMessageBox()
            msgBox.setWindowTitle(
                QtGui.QApplication.translate("MainWindow", "Restart Toxygen", None, QtGui.QApplication.UnicodeUTF8)
            )
            msgBox.setText(
                QtGui.QApplication.translate(
                    "MainWindow", "Plugin will be loaded after restart", None, QtGui.QApplication.UnicodeUTF8
                )
            )
            msgBox.exec_()

    def lock_app(self):
        if toxencryptsave.ToxEncryptSave.get_instance().has_password():
            Settings.get_instance().locked = True
            self.hide()
        else:
            msgBox = QtGui.QMessageBox()
            msgBox.setWindowTitle(
                QtGui.QApplication.translate("MainWindow", "Cannot lock app", None, QtGui.QApplication.UnicodeUTF8)
            )
            msgBox.setText(
                QtGui.QApplication.translate(
                    "MainWindow", "Error. Profile password is not set.", None, QtGui.QApplication.UnicodeUTF8
                )
            )
            msgBox.exec_()

    def show_menu(self):
        if not hasattr(self, "menu"):
            self.menu = DropdownMenu(self)
        self.menu.setGeometry(
            QtCore.QRect(0 if Settings.get_instance()["mirror_mode"] else 270, self.height() - 120, 180, 120)
        )
        self.menu.show()

    # -----------------------------------------------------------------------------------------------------------------
    # Messages, calls and file transfers
    # -----------------------------------------------------------------------------------------------------------------

    def send_message(self):
        text = self.messageEdit.toPlainText()
        self.profile.send_message(text)

    def send_file(self):
        self.menu.hide()
        if self.profile.active_friend + 1:
            choose = QtGui.QApplication.translate("MainWindow", "Choose file", None, QtGui.QApplication.UnicodeUTF8)
            name = QtGui.QFileDialog.getOpenFileName(self, choose, options=QtGui.QFileDialog.DontUseNativeDialog)
            if name[0]:
                self.profile.send_file(name[0])

    def send_screenshot(self, hide=False):
        self.menu.hide()
        if self.profile.active_friend + 1:
            self.sw = ScreenShotWindow(self)
            self.sw.show()
            if hide:
                self.hide()

    def send_smiley(self):
        self.menu.hide()
        if self.profile.active_friend + 1:
            self.smiley = SmileyWindow(self)
            self.smiley.setGeometry(
                QtCore.QRect(
                    self.x() if Settings.get_instance()["mirror_mode"] else 270 + self.x(),
                    self.y() + self.height() - 200,
                    self.smiley.width(),
                    self.smiley.height(),
                )
            )
            self.smiley.show()

    def send_sticker(self):
        self.menu.hide()
        if self.profile.active_friend + 1:
            self.sticker = StickerWindow(self)
            self.sticker.setGeometry(
                QtCore.QRect(
                    self.x() if Settings.get_instance()["mirror_mode"] else 270 + self.x(),
                    self.y() + self.height() - 200,
                    self.sticker.width(),
                    self.sticker.height(),
                )
            )
            self.sticker.show()

    def active_call(self):
        self.update_call_state("finish_call")

    def incoming_call(self):
        self.update_call_state("incoming_call")

    def call_finished(self):
        self.update_call_state("call")

    def update_call_state(self, fl):
        # TODO: do smth with video call button
        os.chdir(curr_directory() + "/images/")
        pixmap = QtGui.QPixmap(curr_directory() + "/images/{}.png".format(fl))
        icon = QtGui.QIcon(pixmap)
        self.callButton.setIcon(icon)
        self.callButton.setIconSize(QtCore.QSize(50, 50))
        pixmap = QtGui.QPixmap(curr_directory() + "/images/videocall.png")
        icon = QtGui.QIcon(pixmap)
        self.videocallButton.setIcon(icon)
        self.videocallButton.setIconSize(QtCore.QSize(35, 35))

    # -----------------------------------------------------------------------------------------------------------------
    # Functions which called when user open context menu in friends list
    # -----------------------------------------------------------------------------------------------------------------

    def friend_right_click(self, pos):
        item = self.friends_list.itemAt(pos)
        num = self.friends_list.indexFromItem(item).row()
        friend = Profile.get_instance().get_friend(num)
        if friend is None:
            return
        settings = Settings.get_instance()
        allowed = friend.tox_id in settings["auto_accept_from_friends"]
        auto = (
            QtGui.QApplication.translate("MainWindow", "Disallow auto accept", None, QtGui.QApplication.UnicodeUTF8)
            if allowed
            else QtGui.QApplication.translate("MainWindow", "Allow auto accept", None, QtGui.QApplication.UnicodeUTF8)
        )
        if item is not None:
            self.listMenu = QtGui.QMenu()
            set_alias_item = self.listMenu.addAction(
                QtGui.QApplication.translate("MainWindow", "Set alias", None, QtGui.QApplication.UnicodeUTF8)
            )

            history_menu = self.listMenu.addMenu(
                QtGui.QApplication.translate("MainWindow", "Chat history", None, QtGui.QApplication.UnicodeUTF8)
            )
            clear_history_item = history_menu.addAction(
                QtGui.QApplication.translate("MainWindow", "Clear history", None, QtGui.QApplication.UnicodeUTF8)
            )
            export_to_text_item = history_menu.addAction(
                QtGui.QApplication.translate("MainWindow", "Export as text", None, QtGui.QApplication.UnicodeUTF8)
            )
            export_to_html_item = history_menu.addAction(
                QtGui.QApplication.translate("MainWindow", "Export as HTML", None, QtGui.QApplication.UnicodeUTF8)
            )

            copy_menu = self.listMenu.addMenu(
                QtGui.QApplication.translate("MainWindow", "Copy", None, QtGui.QApplication.UnicodeUTF8)
            )
            copy_name_item = copy_menu.addAction(
                QtGui.QApplication.translate("MainWindow", "Name", None, QtGui.QApplication.UnicodeUTF8)
            )
            copy_status_item = copy_menu.addAction(
                QtGui.QApplication.translate("MainWindow", "Status message", None, QtGui.QApplication.UnicodeUTF8)
            )
            copy_key_item = copy_menu.addAction(
                QtGui.QApplication.translate("MainWindow", "Public key", None, QtGui.QApplication.UnicodeUTF8)
            )

            auto_accept_item = self.listMenu.addAction(auto)
            remove_item = self.listMenu.addAction(
                QtGui.QApplication.translate("MainWindow", "Remove friend", None, QtGui.QApplication.UnicodeUTF8)
            )
            notes_item = self.listMenu.addAction(
                QtGui.QApplication.translate("MainWindow", "Notes", None, QtGui.QApplication.UnicodeUTF8)
            )

            submenu = plugin_support.PluginLoader.get_instance().get_menu(self.listMenu, num)
            if len(submenu):
                plug = self.listMenu.addMenu(
                    QtGui.QApplication.translate("MainWindow", "Plugins", None, QtGui.QApplication.UnicodeUTF8)
                )
                plug.addActions(submenu)
            self.connect(set_alias_item, QtCore.SIGNAL("triggered()"), lambda: self.set_alias(num))
            self.connect(remove_item, QtCore.SIGNAL("triggered()"), lambda: self.remove_friend(num))
            self.connect(copy_key_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_friend_key(num))
            self.connect(clear_history_item, QtCore.SIGNAL("triggered()"), lambda: self.clear_history(num))
            self.connect(auto_accept_item, QtCore.SIGNAL("triggered()"), lambda: self.auto_accept(num, not allowed))
            self.connect(notes_item, QtCore.SIGNAL("triggered()"), lambda: self.show_note(friend))
            self.connect(copy_name_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_name(friend))
            self.connect(copy_status_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_status(friend))
            self.connect(export_to_text_item, QtCore.SIGNAL("triggered()"), lambda: self.export_history(num))
            self.connect(export_to_html_item, QtCore.SIGNAL("triggered()"), lambda: self.export_history(num, False))
            parent_position = self.friends_list.mapToGlobal(QtCore.QPoint(0, 0))
            self.listMenu.move(parent_position + pos)
            self.listMenu.show()

    def show_note(self, friend):
        s = Settings.get_instance()
        note = s["notes"][friend.tox_id] if friend.tox_id in s["notes"] else ""
        user = QtGui.QApplication.translate("MainWindow", "Notes about user", None, QtGui.QApplication.UnicodeUTF8)
        user = "******".format(user, friend.name)

        def save_note(text):
            if friend.tox_id in s["notes"]:
                del s["notes"][friend.tox_id]
            if text:
                s["notes"][friend.tox_id] = text
            s.save()

        self.note = MultilineEdit(user, note, save_note)
        self.note.show()

    def export_history(self, num, as_text=True):
        s = self.profile.export_history(num, as_text)
        directory = QtGui.QFileDialog.getExistingDirectory(
            None,
            QtGui.QApplication.translate("MainWindow", "Choose folder", None, QtGui.QApplication.UnicodeUTF8),
            curr_directory(),
            QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontUseNativeDialog,
        )

        if directory:
            name = "exported_history_{}.{}".format(convert_time(time.time()), "txt" if as_text else "html")
            with open(directory + "/" + name, "wt") as fl:
                fl.write(s)

    def set_alias(self, num):
        self.profile.set_alias(num)

    def remove_friend(self, num):
        self.profile.delete_friend(num)

    def copy_friend_key(self, num):
        tox_id = self.profile.friend_public_key(num)
        clipboard = QtGui.QApplication.clipboard()
        clipboard.setText(tox_id)

    def copy_name(self, friend):
        clipboard = QtGui.QApplication.clipboard()
        clipboard.setText(friend.name)

    def copy_status(self, friend):
        clipboard = QtGui.QApplication.clipboard()
        clipboard.setText(friend.status_message)

    def clear_history(self, num):
        self.profile.clear_history(num)

    def auto_accept(self, num, value):
        settings = Settings.get_instance()
        tox_id = self.profile.friend_public_key(num)
        if value:
            settings["auto_accept_from_friends"].append(tox_id)
        else:
            settings["auto_accept_from_friends"].remove(tox_id)
        settings.save()

    # -----------------------------------------------------------------------------------------------------------------
    # Functions which called when user click somewhere else
    # -----------------------------------------------------------------------------------------------------------------

    def friend_click(self, index):
        num = index.row()
        self.profile.set_active(num)

    def mouseReleaseEvent(self, event):
        pos = self.connection_status.pos()
        x, y = pos.x() + self.user_info.pos().x(), pos.y() + self.user_info.pos().y()
        if (x < event.x() < x + 32) and (y < event.y() < y + 32):
            self.profile.change_status()
        else:
            super(MainWindow, self).mouseReleaseEvent(event)

    def filtering(self):
        ind = self.online_contacts.currentIndex()
        d = {0: 0, 1: 1, 2: 2, 3: 4, 4: 1 | 4, 5: 2 | 4}
        self.profile.filtration_and_sorting(d[ind], self.contact_name.text())
Ejemplo n.º 10
0
class ProfileSettings(CenteredWidget):
    """Form with profile settings such as name, status, TOX ID"""
    def __init__(self):
        super(ProfileSettings, self).__init__()
        self.initUI()
        self.center()

    def initUI(self):
        self.setObjectName("ProfileSettingsForm")
        self.setMinimumSize(QtCore.QSize(700, 600))
        self.setMaximumSize(QtCore.QSize(700, 600))
        self.nick = LineEdit(self)
        self.nick.setGeometry(QtCore.QRect(30, 60, 350, 27))
        profile = Profile.get_instance()
        self.nick.setText(profile.name)
        self.status = QtGui.QComboBox(self)
        self.status.setGeometry(QtCore.QRect(400, 60, 200, 27))
        self.status_message = LineEdit(self)
        self.status_message.setGeometry(QtCore.QRect(30, 130, 350, 27))
        self.status_message.setText(profile.status_message)
        self.label = QtGui.QLabel(self)
        self.label.setGeometry(QtCore.QRect(40, 30, 91, 25))
        font = QtGui.QFont()
        font.setPointSize(18)
        font.setWeight(75)
        font.setBold(True)
        self.label.setFont(font)
        self.label_2 = QtGui.QLabel(self)
        self.label_2.setGeometry(QtCore.QRect(40, 100, 100, 25))
        self.label_2.setFont(font)
        self.label_3 = QtGui.QLabel(self)
        self.label_3.setGeometry(QtCore.QRect(40, 180, 100, 25))
        self.label_3.setFont(font)
        self.tox_id = QtGui.QLabel(self)
        self.tox_id.setGeometry(QtCore.QRect(15, 210, 685, 21))
        font.setPointSize(10)
        self.tox_id.setFont(font)
        s = profile.tox_id
        self.tox_id.setText(s)
        self.copyId = QtGui.QPushButton(self)
        self.copyId.setGeometry(QtCore.QRect(40, 250, 180, 30))
        self.copyId.clicked.connect(self.copy)
        self.export = QtGui.QPushButton(self)
        self.export.setGeometry(QtCore.QRect(230, 250, 180, 30))
        self.export.clicked.connect(self.export_profile)
        self.new_nospam = QtGui.QPushButton(self)
        self.new_nospam.setGeometry(QtCore.QRect(420, 250, 180, 30))
        self.new_nospam.clicked.connect(self.new_no_spam)
        self.copy_pk = QtGui.QPushButton(self)
        self.copy_pk.setGeometry(QtCore.QRect(40, 300, 180, 30))
        self.copy_pk.clicked.connect(self.copy_public_key)
        self.new_avatar = QtGui.QPushButton(self)
        self.new_avatar.setGeometry(QtCore.QRect(230, 300, 180, 30))
        self.delete_avatar = QtGui.QPushButton(self)
        self.delete_avatar.setGeometry(QtCore.QRect(420, 300, 180, 30))
        self.delete_avatar.clicked.connect(self.reset_avatar)
        self.new_avatar.clicked.connect(self.set_avatar)
        self.profilepass = QtGui.QLabel(self)
        self.profilepass.setGeometry(QtCore.QRect(40, 340, 300, 30))
        font.setPointSize(18)
        self.profilepass.setFont(font)
        self.password = LineEdit(self)
        self.password.setGeometry(QtCore.QRect(40, 380, 300, 30))
        self.password.setEchoMode(QtGui.QLineEdit.EchoMode.Password)
        self.leave_blank = QtGui.QLabel(self)
        self.leave_blank.setGeometry(QtCore.QRect(350, 380, 300, 30))
        self.confirm_password = LineEdit(self)
        self.confirm_password.setGeometry(QtCore.QRect(40, 420, 300, 30))
        self.confirm_password.setEchoMode(QtGui.QLineEdit.EchoMode.Password)
        self.set_password = QtGui.QPushButton(self)
        self.set_password.setGeometry(QtCore.QRect(40, 470, 300, 30))
        self.set_password.clicked.connect(self.new_password)
        self.not_match = QtGui.QLabel(self)
        self.not_match.setGeometry(QtCore.QRect(350, 420, 300, 30))
        self.not_match.setVisible(False)
        self.not_match.setStyleSheet('QLabel { color: #BC1C1C; }')
        self.warning = QtGui.QLabel(self)
        self.warning.setGeometry(QtCore.QRect(40, 510, 500, 30))
        self.warning.setStyleSheet('QLabel { color: #BC1C1C; }')
        self.default = QtGui.QPushButton(self)
        self.default.setGeometry(QtCore.QRect(40, 550, 620, 30))
        path, name = Settings.get_auto_profile()
        self.auto = path + name == ProfileHelper.get_path() + Settings.get_instance().name
        self.default.clicked.connect(self.auto_profile)
        self.retranslateUi()
        if profile.status is not None:
            self.status.setCurrentIndex(profile.status)
        else:
            self.status.setVisible(False)
        QtCore.QMetaObject.connectSlotsByName(self)

    def retranslateUi(self):
        self.export.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Export profile", None, QtGui.QApplication.UnicodeUTF8))
        self.setWindowTitle(QtGui.QApplication.translate("ProfileSettingsForm", "Profile settings", None, QtGui.QApplication.UnicodeUTF8))
        self.label.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Name:", None, QtGui.QApplication.UnicodeUTF8))
        self.label_2.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Status:", None, QtGui.QApplication.UnicodeUTF8))
        self.label_3.setText(QtGui.QApplication.translate("ProfileSettingsForm", "TOX ID:", None, QtGui.QApplication.UnicodeUTF8))
        self.copyId.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Copy TOX ID", None, QtGui.QApplication.UnicodeUTF8))
        self.new_avatar.setText(QtGui.QApplication.translate("ProfileSettingsForm", "New avatar", None, QtGui.QApplication.UnicodeUTF8))
        self.delete_avatar.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Reset avatar", None, QtGui.QApplication.UnicodeUTF8))
        self.new_nospam.setText(QtGui.QApplication.translate("ProfileSettingsForm", "New NoSpam", None, QtGui.QApplication.UnicodeUTF8))
        self.profilepass.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Profile password", None, QtGui.QApplication.UnicodeUTF8))
        self.password.setPlaceholderText(QtGui.QApplication.translate("ProfileSettingsForm", "Password (at least 8 symbols)", None, QtGui.QApplication.UnicodeUTF8))
        self.confirm_password.setPlaceholderText(QtGui.QApplication.translate("ProfileSettingsForm", "Confirm password", None, QtGui.QApplication.UnicodeUTF8))
        self.set_password.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Set password", None, QtGui.QApplication.UnicodeUTF8))
        self.not_match.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Passwords do not match", None, QtGui.QApplication.UnicodeUTF8))
        self.leave_blank.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Leaving blank will reset current password", None, QtGui.QApplication.UnicodeUTF8))
        self.warning.setText(QtGui.QApplication.translate("ProfileSettingsForm", "There is no way to recover lost passwords", None, QtGui.QApplication.UnicodeUTF8))
        self.status.addItem(QtGui.QApplication.translate("ProfileSettingsForm", "Online", None, QtGui.QApplication.UnicodeUTF8))
        self.status.addItem(QtGui.QApplication.translate("ProfileSettingsForm", "Away", None, QtGui.QApplication.UnicodeUTF8))
        self.status.addItem(QtGui.QApplication.translate("ProfileSettingsForm", "Busy", None, QtGui.QApplication.UnicodeUTF8))
        self.copy_pk.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Copy public key", None, QtGui.QApplication.UnicodeUTF8))
        if self.auto:
            self.default.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Mark as not default profile", None, QtGui.QApplication.UnicodeUTF8))
        else:
            self.default.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Mark as default profile", None, QtGui.QApplication.UnicodeUTF8))

    def auto_profile(self):
        if self.auto:
            Settings.reset_auto_profile()
        else:
            Settings.set_auto_profile(ProfileHelper.get_path(), Settings.get_instance().name)
        self.auto = not self.auto
        if self.auto:
            self.default.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Mark as not default profile", None,
                                                              QtGui.QApplication.UnicodeUTF8))
        else:
            self.default.setText(
                QtGui.QApplication.translate("ProfileSettingsForm", "Mark as default profile", None,
                                             QtGui.QApplication.UnicodeUTF8))

    def new_password(self):
        if self.password.text() == self.confirm_password.text():
            if not len(self.password.text()) or len(self.password.text()) >= 8:
                e = toxencryptsave.ToxEncryptSave.get_instance()
                e.set_password(self.password.text())
                self.close()
            else:
                self.not_match.setText(
                    QtGui.QApplication.translate("ProfileSettingsForm", "Password must be at least 8 symbols", None,
                                                 QtGui.QApplication.UnicodeUTF8))
            self.not_match.setVisible(True)
        else:
            self.not_match.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Passwords do not match", None,
                                                                QtGui.QApplication.UnicodeUTF8))
            self.not_match.setVisible(True)

    def copy(self):
        clipboard = QtGui.QApplication.clipboard()
        profile = Profile.get_instance()
        clipboard.setText(profile.tox_id)
        pixmap = QtGui.QPixmap(curr_directory() + '/images/accept.png')
        icon = QtGui.QIcon(pixmap)
        self.copyId.setIcon(icon)
        self.copyId.setIconSize(QtCore.QSize(10, 10))

    def copy_public_key(self):
        clipboard = QtGui.QApplication.clipboard()
        profile = Profile.get_instance()
        clipboard.setText(profile.tox_id[:64])
        pixmap = QtGui.QPixmap(curr_directory() + '/images/accept.png')
        icon = QtGui.QIcon(pixmap)
        self.copy_pk.setIcon(icon)
        self.copy_pk.setIconSize(QtCore.QSize(10, 10))

    def new_no_spam(self):
        self.tox_id.setText(Profile.get_instance().new_nospam())

    def reset_avatar(self):
        Profile.get_instance().reset_avatar()

    def set_avatar(self):
        choose = QtGui.QApplication.translate("ProfileSettingsForm", "Choose avatar", None, QtGui.QApplication.UnicodeUTF8)
        name = QtGui.QFileDialog.getOpenFileName(self, choose, None, 'Images (*.png)',
                                                 options=QtGui.QFileDialog.DontUseNativeDialog)
        if name[0]:
            bitmap = QtGui.QPixmap(name[0])
            bitmap.scaled(QtCore.QSize(128, 128), aspectMode=QtCore.Qt.KeepAspectRatio,
                          mode=QtCore.Qt.SmoothTransformation)

            byte_array = QtCore.QByteArray()
            buffer = QtCore.QBuffer(byte_array)
            buffer.open(QtCore.QIODevice.WriteOnly)
            bitmap.save(buffer, 'PNG')
            Profile.get_instance().set_avatar(bytes(byte_array.data()))

    def export_profile(self):
        directory = QtGui.QFileDialog.getExistingDirectory(options=QtGui.QFileDialog.DontUseNativeDialog) + '/'
        if directory != '/':
            ProfileHelper.get_instance().export_profile(directory)
            settings = Settings.get_instance()
            settings.export(directory)
            profile = Profile.get_instance()
            profile.export_history(directory)

    def closeEvent(self, event):
        profile = Profile.get_instance()
        profile.set_name(self.nick.text())
        profile.set_status_message(self.status_message.text().encode('utf-8'))
        profile.set_status(self.status.currentIndex())
Ejemplo n.º 11
0
class NetworkSettings(CenteredWidget):
    """Network settings form: UDP, Ipv6 and proxy"""
    def __init__(self, reset):
        super(NetworkSettings, self).__init__()
        self.reset = reset
        self.initUI()
        self.center()

    def initUI(self):
        self.setObjectName("NetworkSettings")
        self.resize(300, 330)
        self.setMinimumSize(QtCore.QSize(300, 330))
        self.setMaximumSize(QtCore.QSize(300, 330))
        self.setBaseSize(QtCore.QSize(300, 330))
        self.ipv = QtGui.QCheckBox(self)
        self.ipv.setGeometry(QtCore.QRect(20, 10, 97, 22))
        self.ipv.setObjectName("ipv")
        self.udp = QtGui.QCheckBox(self)
        self.udp.setGeometry(QtCore.QRect(150, 10, 97, 22))
        self.udp.setObjectName("udp")
        self.proxy = QtGui.QCheckBox(self)
        self.proxy.setGeometry(QtCore.QRect(20, 40, 97, 22))
        self.http = QtGui.QCheckBox(self)
        self.http.setGeometry(QtCore.QRect(20, 70, 97, 22))
        self.proxy.setObjectName("proxy")
        self.proxyip = LineEdit(self)
        self.proxyip.setGeometry(QtCore.QRect(40, 130, 231, 27))
        self.proxyip.setObjectName("proxyip")
        self.proxyport = LineEdit(self)
        self.proxyport.setGeometry(QtCore.QRect(40, 190, 231, 27))
        self.proxyport.setObjectName("proxyport")
        self.label = QtGui.QLabel(self)
        self.label.setGeometry(QtCore.QRect(40, 100, 66, 17))
        self.label_2 = QtGui.QLabel(self)
        self.label_2.setGeometry(QtCore.QRect(40, 165, 66, 17))
        self.reconnect = QtGui.QPushButton(self)
        self.reconnect.setGeometry(QtCore.QRect(40, 230, 231, 30))
        self.reconnect.clicked.connect(self.restart_core)
        settings = Settings.get_instance()
        self.ipv.setChecked(settings['ipv6_enabled'])
        self.udp.setChecked(settings['udp_enabled'])
        self.proxy.setChecked(settings['proxy_type'])
        self.proxyip.setText(settings['proxy_host'])
        self.proxyport.setText(str(settings['proxy_port']))
        self.http.setChecked(settings['proxy_type'] == 1)
        self.warning = QtGui.QLabel(self)
        self.warning.setGeometry(QtCore.QRect(5, 270, 290, 60))
        self.warning.setStyleSheet('QLabel { color: #BC1C1C; }')
        self.retranslateUi()
        self.proxy.stateChanged.connect(lambda x: self.activate())
        self.activate()
        QtCore.QMetaObject.connectSlotsByName(self)

    def retranslateUi(self):
        self.setWindowTitle(QtGui.QApplication.translate("NetworkSettings", "Network settings", None, QtGui.QApplication.UnicodeUTF8))
        self.ipv.setText(QtGui.QApplication.translate("Form", "IPv6", None, QtGui.QApplication.UnicodeUTF8))
        self.udp.setText(QtGui.QApplication.translate("Form", "UDP", None, QtGui.QApplication.UnicodeUTF8))
        self.proxy.setText(QtGui.QApplication.translate("Form", "Proxy", None, QtGui.QApplication.UnicodeUTF8))
        self.label.setText(QtGui.QApplication.translate("Form", "IP:", None, QtGui.QApplication.UnicodeUTF8))
        self.label_2.setText(QtGui.QApplication.translate("Form", "Port:", None, QtGui.QApplication.UnicodeUTF8))
        self.reconnect.setText(QtGui.QApplication.translate("NetworkSettings", "Restart TOX core", None, QtGui.QApplication.UnicodeUTF8))
        self.http.setText(QtGui.QApplication.translate("Form", "HTTP", None, QtGui.QApplication.UnicodeUTF8))
        self.warning.setText(QtGui.QApplication.translate("Form", "WARNING:\nusing proxy with enabled UDP\ncan produce IP leak",
                                                          None, QtGui.QApplication.UnicodeUTF8))

    def activate(self):
        bl = self.proxy.isChecked()
        self.proxyip.setEnabled(bl)
        self.http.setEnabled(bl)
        self.proxyport.setEnabled(bl)

    def restart_core(self):
        try:
            settings = Settings.get_instance()
            settings['ipv6_enabled'] = self.ipv.isChecked()
            settings['udp_enabled'] = self.udp.isChecked()
            settings['proxy_type'] = 2 - int(self.http.isChecked()) if self.proxy.isChecked() else 0
            settings['proxy_host'] = str(self.proxyip.text())
            settings['proxy_port'] = int(self.proxyport.text())
            settings.save()
            # recreate tox instance
            Profile.get_instance().reset(self.reset)
            self.close()
        except Exception as ex:
            log('Exception in restart: ' + str(ex))
Ejemplo n.º 12
0
class AddContact(CenteredWidget):
    """Add contact form"""

    def __init__(self, tox_id=''):
        super(AddContact, self).__init__()
        self.initUI(tox_id)
        self._adding = False

    def initUI(self, tox_id):
        self.setObjectName('AddContact')
        self.resize(568, 306)
        self.sendRequestButton = QtGui.QPushButton(self)
        self.sendRequestButton.setGeometry(QtCore.QRect(50, 270, 471, 31))
        self.sendRequestButton.setMinimumSize(QtCore.QSize(0, 0))
        self.sendRequestButton.setBaseSize(QtCore.QSize(0, 0))
        self.sendRequestButton.setObjectName("sendRequestButton")
        self.sendRequestButton.clicked.connect(self.add_friend)
        self.tox_id = LineEdit(self)
        self.tox_id.setGeometry(QtCore.QRect(50, 40, 471, 27))
        self.tox_id.setObjectName("lineEdit")
        self.tox_id.setText(tox_id)
        self.label = QtGui.QLabel(self)
        self.label.setGeometry(QtCore.QRect(50, 10, 80, 20))
        self.error_label = DataLabel(self)
        self.error_label.setGeometry(QtCore.QRect(120, 10, 420, 20))
        font = QtGui.QFont()
        font.setPointSize(10)
        font.setWeight(30)
        self.error_label.setFont(font)
        self.error_label.setStyleSheet("QLabel { color: #BC1C1C; }")
        self.label.setObjectName("label")
        self.message_edit = QtGui.QTextEdit(self)
        self.message_edit.setGeometry(QtCore.QRect(50, 110, 471, 151))
        self.message_edit.setObjectName("textEdit")
        self.message = QtGui.QLabel(self)
        self.message.setGeometry(QtCore.QRect(50, 70, 101, 31))
        self.message.setFont(font)
        self.message.setObjectName("label_2")
        self.retranslateUi()
        self.message_edit.setText('Hello! Add me to your contact list please')
        font = QtGui.QFont()
        font.setPointSize(12)
        font.setBold(True)
        self.label.setFont(font)
        self.message.setFont(font)
        QtCore.QMetaObject.connectSlotsByName(self)

    def add_friend(self):
        if self._adding:
            return
        self._adding = True
        profile = Profile.get_instance()
        send = profile.send_friend_request(self.tox_id.text().strip(), self.message_edit.toPlainText())
        self._adding = False
        if send is True:
            # request was successful
            self.close()
        else:  # print error data
            self.error_label.setText(send)

    def retranslateUi(self):
        self.setWindowTitle(QtGui.QApplication.translate('AddContact', "Add contact", None, QtGui.QApplication.UnicodeUTF8))
        self.sendRequestButton.setText(QtGui.QApplication.translate("Form", "Send request", None, QtGui.QApplication.UnicodeUTF8))
        self.label.setText(QtGui.QApplication.translate('AddContact', "TOX ID:", None, QtGui.QApplication.UnicodeUTF8))
        self.message.setText(QtGui.QApplication.translate('AddContact', "Message:", None, QtGui.QApplication.UnicodeUTF8))
        self.tox_id.setPlaceholderText(QtGui.QApplication.translate('AddContact', "TOX ID or public key of contact", None, QtGui.QApplication.UnicodeUTF8))
Ejemplo n.º 13
0
class SearchScreen(QtGui.QWidget):

    def __init__(self, messages, width, *args):
        super().__init__(*args)
        self.setMaximumSize(width, 40)
        self.setMinimumSize(width, 40)
        self._messages = messages

        self.search_text = LineEdit(self)
        self.search_text.setGeometry(0, 0, width - 160, 40)

        self.search_button = ClickableLabel(self)
        self.search_button.setGeometry(width - 160, 0, 40, 40)
        pixmap = QtGui.QPixmap()
        pixmap.load(util.curr_directory() + '/images/search.png')
        self.search_button.setScaledContents(False)
        self.search_button.setAlignment(QtCore.Qt.AlignCenter)
        self.search_button.setPixmap(pixmap)
        self.connect(self.search_button, QtCore.SIGNAL('clicked()'), self.search)

        font = QtGui.QFont()
        font.setPointSize(32)
        font.setBold(True)

        self.prev_button = QtGui.QPushButton(self)
        self.prev_button.setGeometry(width - 120, 0, 40, 40)
        self.prev_button.clicked.connect(self.prev)
        self.prev_button.setText('\u25B2')

        self.next_button = QtGui.QPushButton(self)
        self.next_button.setGeometry(width - 80, 0, 40, 40)
        self.next_button.clicked.connect(self.next)
        self.next_button.setText('\u25BC')

        self.close_button = QtGui.QPushButton(self)
        self.close_button.setGeometry(width - 40, 0, 40, 40)
        self.close_button.clicked.connect(self.close)
        self.close_button.setText('×')
        self.close_button.setFont(font)

        font.setPointSize(18)
        self.next_button.setFont(font)
        self.prev_button.setFont(font)

        self.retranslateUi()

    def retranslateUi(self):
        self.search_text.setPlaceholderText(QtGui.QApplication.translate("MainWindow", "Search", None,
                                                                         QtGui.QApplication.UnicodeUTF8))

    def show(self):
        super().show()
        self.search_text.setFocus()

    def search(self):
        Profile.get_instance().update()
        text = self.search_text.text()
        friend = Profile.get_instance().get_curr_friend()
        if text and friend and util.is_re_valid(text):
            index = friend.search_string(text)
            self.load_messages(index)

    def prev(self):
        friend = Profile.get_instance().get_curr_friend()
        if friend is not None:
            index = friend.search_prev()
            self.load_messages(index)

    def next(self):
        friend = Profile.get_instance().get_curr_friend()
        text = self.search_text.text()
        if friend is not None:
            index = friend.search_next()
            if index is not None:
                count = self._messages.count()
                index += count
                item = self._messages.item(index)
                self._messages.scrollToItem(item)
                self._messages.itemWidget(item).select_text(text)
            else:
                self.not_found(text)

    def load_messages(self, index):
        text = self.search_text.text()
        if index is not None:
            profile = Profile.get_instance()
            count = self._messages.count()
            while count + index < 0:
                profile.load_history()
                count = self._messages.count()
            index += count
            item = self._messages.item(index)
            self._messages.scrollToItem(item)
            self._messages.itemWidget(item).select_text(text)
        else:
            self.not_found(text)

    def closeEvent(self, *args):
        Profile.get_instance().update()
        self._messages.setGeometry(0, 0, self._messages.width(), self._messages.height() + 40)
        super().closeEvent(*args)

    @staticmethod
    def not_found(text):
        mbox = QtGui.QMessageBox()
        mbox_text = QtGui.QApplication.translate("MainWindow",
                                                 'Text "{}" was not found',
                                                 None,
                                                 QtGui.QApplication.UnicodeUTF8)

        mbox.setText(mbox_text.format(text))
        mbox.setWindowTitle(QtGui.QApplication.translate("MainWindow",
                                                         'Not found',
                                                         None,
                                                         QtGui.QApplication.UnicodeUTF8))
        mbox.exec_()